From e21ae1188dea8bf78504054dde6074f507beb01c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 24 Oct 2018 22:28:59 +0200 Subject: [PATCH 01/45] fix: display test duration even if time is mocked out (#7264) --- CHANGELOG.md | 1 + e2e/__tests__/override-globals.test.js | 11 +++++++++ e2e/override-globals/package.json | 5 +++- e2e/override-globals/setup.js | 2 ++ packages/jest-circus/src/utils.js | 2 +- .../jest-util/src/install_common_globals.js | 8 +++++-- ...js => babel-plugin-jest-native-globals.js} | 23 ++++++++++++++++--- scripts/build.js | 4 ++-- 8 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 e2e/override-globals/setup.js rename scripts/{babel-plugin-jest-native-promise.js => babel-plugin-jest-native-globals.js} (52%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dcbe823063a..d53348f215f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ - `[jest-changed-files]` Return correctly the changed files when using `lastCommit=true` on Mercurial repositories ([#7228](https://github.com/facebook/jest/pull/7228)) - `[babel-jest]` Cache includes babel environment variables ([#7239](https://github.com/facebook/jest/pull/7239)) - `[jest-config]` Use strings instead of `RegExp` instances in normalized configuration ([#7251](https://github.com/facebook/jest/pull/7251)) +- `[jest-circus]` Make sure to display real duration even if time is mocked ([#7264](https://github.com/facebook/jest/pull/7264)) ### Chore & Maintenance diff --git a/e2e/__tests__/override-globals.test.js b/e2e/__tests__/override-globals.test.js index a8ad8ac7c252..489f43e76987 100644 --- a/e2e/__tests__/override-globals.test.js +++ b/e2e/__tests__/override-globals.test.js @@ -15,3 +15,14 @@ test('overriding native promise does not freeze Jest', () => { const run = runJest('override-globals'); expect(run.stderr).toMatch(/PASS __tests__(\/|\\)index.js/); }); + +test('has a duration even if time is faked', () => { + const regex = /works well \((\d+)ms\)/; + const {stderr} = runJest('override-globals', ['--verbose']); + + expect(stderr).toMatch(regex); + + const [, duration] = stderr.match(regex); + + expect(Number(duration)).toBeGreaterThan(0); +}); diff --git a/e2e/override-globals/package.json b/e2e/override-globals/package.json index 148788b25446..b4a435775e2b 100644 --- a/e2e/override-globals/package.json +++ b/e2e/override-globals/package.json @@ -1,5 +1,8 @@ { "jest": { - "testEnvironment": "node" + "testEnvironment": "node", + "setupFiles": [ + "/setup.js" + ] } } diff --git a/e2e/override-globals/setup.js b/e2e/override-globals/setup.js new file mode 100644 index 000000000000..0fb3e1ade0c8 --- /dev/null +++ b/e2e/override-globals/setup.js @@ -0,0 +1,2 @@ +Date.now = () => 0; +process.hrtime = () => [0, 5000]; diff --git a/packages/jest-circus/src/utils.js b/packages/jest-circus/src/utils.js index 96da54744ecf..328566bbcfb5 100644 --- a/packages/jest-circus/src/utils.js +++ b/packages/jest-circus/src/utils.js @@ -240,7 +240,7 @@ export const callAsyncCircusFn = ( export const getTestDuration = (test: TestEntry): ?number => { const {startedAt} = test; - return startedAt ? Date.now() - startedAt : null; + return typeof startedAt === 'number' ? Date.now() - startedAt : null; }; export const makeRunResult = ( diff --git a/packages/jest-util/src/install_common_globals.js b/packages/jest-util/src/install_common_globals.js index 5eada9d75747..d87e16a28861 100644 --- a/packages/jest-util/src/install_common_globals.js +++ b/packages/jest-util/src/install_common_globals.js @@ -18,8 +18,12 @@ const DTRACE = Object.keys(global).filter(key => key.startsWith('DTRACE')); export default function(globalObject: Global, globals: ConfigGlobals) { globalObject.process = createProcessObject(); - // Keep a reference to "Promise", since "jasmine_light.js" needs it. - globalObject[globalObject.Symbol.for('jest-native-promise')] = Promise; + const symbol = globalObject.Symbol; + // Keep a reference to some globals that Jest needs + globalObject[symbol.for('jest-native-promise')] = Promise; + globalObject[symbol.for('jest-native-now')] = globalObject.Date.now.bind( + globalObject.Date, + ); // Forward some APIs. DTRACE.forEach(dtrace => { diff --git a/scripts/babel-plugin-jest-native-promise.js b/scripts/babel-plugin-jest-native-globals.js similarity index 52% rename from scripts/babel-plugin-jest-native-promise.js rename to scripts/babel-plugin-jest-native-globals.js index b0fa9e57db85..a0e01e20b942 100644 --- a/scripts/babel-plugin-jest-native-promise.js +++ b/scripts/babel-plugin-jest-native-globals.js @@ -14,17 +14,34 @@ module.exports = ({template}) => { const promiseDeclaration = template(` var Promise = global[Symbol.for('jest-native-promise')] || global.Promise; `); + const nowDeclaration = template(` + var jestNow = global[Symbol.for('jest-native-now')] || global.Date.now; + `); return { - name: 'jest-native-promise', + name: 'jest-native-globals', visitor: { ReferencedIdentifier(path, state) { - if (path.node.name === 'Promise' && !state.injectedPromise) { - state.injectedPromise = true; + if (path.node.name === 'Promise' && !state.jestInjectedPromise) { + state.jestInjectedPromise = true; path .findParent(p => p.isProgram()) .unshiftContainer('body', promiseDeclaration()); } + if ( + path.node.name === 'Date' && + path.parent.property && + path.parent.property.name === 'now' + ) { + if (!state.jestInjectedNow) { + state.jestInjectedNow = true; + path + .findParent(p => p.isProgram()) + .unshiftContainer('body', nowDeclaration()); + } + + path.parentPath.replaceWithSourceString('jestNow'); + } }, }, }; diff --git a/scripts/build.js b/scripts/build.js index 07af2abdf4b6..5ec139a7b9cd 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -152,9 +152,9 @@ function buildFile(file, silent) { if (INLINE_REQUIRE_BLACKLIST.test(file)) { // The modules in the blacklist are injected into the user's sandbox - // We need to guard `Promise` there. + // We need to guard some globals there. options.plugins.push( - require.resolve('./babel-plugin-jest-native-promise') + require.resolve('./babel-plugin-jest-native-globals') ); } else { // Remove normal plugin. From b8619f865fda3b89b05e2e629fb9cce2ed919e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Ma=C5=82kowski?= Date: Thu, 25 Oct 2018 13:01:16 +0700 Subject: [PATCH 02/45] Standardize file names in packages/jest-haste-map (#7266) --- CHANGELOG.md | 1 + .../jest-haste-map/src/{haste_fs.js => HasteFS.js} | 0 .../src/{module_map.js => ModuleMap.js} | 0 .../src/__tests__/get_mock_name.test.js | 2 +- .../jest-haste-map/src/__tests__/index.test.js | 4 ++-- .../src/crawlers/__tests__/watchman.test.js | 2 +- packages/jest-haste-map/src/crawlers/watchman.js | 2 +- .../src/{get_mock_name.js => getMockName.js} | 0 packages/jest-haste-map/src/index.js | 14 +++++++------- .../{watchman_watcher.js => WatchmanWatcher.js} | 0 ...ct_requires.test.js => extractRequires.test.js} | 2 +- ...ension.test.js => getPlatformExtension.test.js} | 2 +- ...e_path_sep.test.js => normalizePathSep.test.js} | 4 ++-- .../{extract_requires.js => extractRequires.js} | 0 ...atform_extension.js => getPlatformExtension.js} | 0 .../{normalize_path_sep.js => normalizePathSep.js} | 0 packages/jest-haste-map/src/worker.js | 2 +- 17 files changed, 18 insertions(+), 17 deletions(-) rename packages/jest-haste-map/src/{haste_fs.js => HasteFS.js} (100%) rename packages/jest-haste-map/src/{module_map.js => ModuleMap.js} (100%) rename packages/jest-haste-map/src/{get_mock_name.js => getMockName.js} (100%) rename packages/jest-haste-map/src/lib/{watchman_watcher.js => WatchmanWatcher.js} (100%) rename packages/jest-haste-map/src/lib/__tests__/{extract_requires.test.js => extractRequires.test.js} (98%) rename packages/jest-haste-map/src/lib/__tests__/{get_platform_extension.test.js => getPlatformExtension.test.js} (92%) rename packages/jest-haste-map/src/lib/__tests__/{normalize_path_sep.test.js => normalizePathSep.test.js} (82%) rename packages/jest-haste-map/src/lib/{extract_requires.js => extractRequires.js} (100%) rename packages/jest-haste-map/src/lib/{get_platform_extension.js => getPlatformExtension.js} (100%) rename packages/jest-haste-map/src/lib/{normalize_path_sep.js => normalizePathSep.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index d53348f215f7..e306cecfbc08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ - `[tests]` Free tests from the dependency on value of FORCE_COLOR ([#6585](https://github.com/facebook/jest/pull/6585/files)) - `[jest-diff]` Standardize filenames ([#7238](https://github.com/facebook/jest/pull/7238)) - `[*]` Add babel plugin to make sure Jest is unaffected by fake Promise implementations ([#7225](https://github.com/facebook/jest/pull/7225)) +- `[jest-haste-map]` Standardize filenames ([#7266](https://github.com/facebook/jest/pull/7266)) ### Performance diff --git a/packages/jest-haste-map/src/haste_fs.js b/packages/jest-haste-map/src/HasteFS.js similarity index 100% rename from packages/jest-haste-map/src/haste_fs.js rename to packages/jest-haste-map/src/HasteFS.js diff --git a/packages/jest-haste-map/src/module_map.js b/packages/jest-haste-map/src/ModuleMap.js similarity index 100% rename from packages/jest-haste-map/src/module_map.js rename to packages/jest-haste-map/src/ModuleMap.js diff --git a/packages/jest-haste-map/src/__tests__/get_mock_name.test.js b/packages/jest-haste-map/src/__tests__/get_mock_name.test.js index 4009cbab2e2f..939a2364c6bc 100644 --- a/packages/jest-haste-map/src/__tests__/get_mock_name.test.js +++ b/packages/jest-haste-map/src/__tests__/get_mock_name.test.js @@ -8,7 +8,7 @@ 'use strict'; import path from 'path'; -import getMockName from '../get_mock_name'; +import getMockName from '../getMockName'; describe('getMockName', () => { it('extracts mock name from file path', () => { diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index bb14132a63fb..df716c9f0c09 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -75,7 +75,7 @@ jest.mock('sane', () => ({ WatchmanWatcher: mockWatcherConstructor, })); -jest.mock('../lib/watchman_watcher.js', () => mockWatcherConstructor); +jest.mock('../lib/WatchmanWatcher.js', () => mockWatcherConstructor); let mockChangedFiles; let mockFs; @@ -1230,7 +1230,7 @@ describe('HasteMap', () => { } catch (error) { const { DuplicateHasteCandidatesError, - } = require('../module_map').default; + } = require('../ModuleMap').default; expect(error).toBeInstanceOf(DuplicateHasteCandidatesError); expect(error.hasteName).toBe('Pear'); expect(error.platform).toBe('g'); diff --git a/packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js b/packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js index 7f80e7dadf7e..b67b849fe840 100644 --- a/packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js +++ b/packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js @@ -11,7 +11,7 @@ const path = require('path'); jest.mock('fb-watchman', () => { - const normalizePathSep = require('../../lib/normalize_path_sep').default; + const normalizePathSep = require('../../lib/normalizePathSep').default; const Client = jest.fn(); Client.prototype.command = jest.fn((args, callback) => setImmediate(() => { diff --git a/packages/jest-haste-map/src/crawlers/watchman.js b/packages/jest-haste-map/src/crawlers/watchman.js index d8fb38c5cf2f..e0d0dce9ee73 100644 --- a/packages/jest-haste-map/src/crawlers/watchman.js +++ b/packages/jest-haste-map/src/crawlers/watchman.js @@ -11,7 +11,7 @@ import type {InternalHasteMap} from 'types/HasteMap'; import type {CrawlerOptions} from '../types'; import * as fastPath from '../lib/fast_path'; -import normalizePathSep from '../lib/normalize_path_sep'; +import normalizePathSep from '../lib/normalizePathSep'; import path from 'path'; import watchman from 'fb-watchman'; import H from '../constants'; diff --git a/packages/jest-haste-map/src/get_mock_name.js b/packages/jest-haste-map/src/getMockName.js similarity index 100% rename from packages/jest-haste-map/src/get_mock_name.js rename to packages/jest-haste-map/src/getMockName.js diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index 12b56a3c4505..f7acf0cbfee4 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -13,22 +13,22 @@ import {getSha1, worker} from './worker'; import crypto from 'crypto'; import EventEmitter from 'events'; import fs from 'fs'; -import getMockName from './get_mock_name'; -import getPlatformExtension from './lib/get_platform_extension'; +import getMockName from './getMockName'; +import getPlatformExtension from './lib/getPlatformExtension'; import H from './constants'; -import HasteFS from './haste_fs'; -import HasteModuleMap from './module_map'; +import HasteFS from './HasteFS'; +import HasteModuleMap from './ModuleMap'; import invariant from 'invariant'; // eslint-disable-next-line import/default import nodeCrawl from './crawlers/node'; -import normalizePathSep from './lib/normalize_path_sep'; +import normalizePathSep from './lib/normalizePathSep'; import os from 'os'; import path from 'path'; import sane from 'sane'; import serializer from 'jest-serializer'; // eslint-disable-next-line import/default import watchmanCrawl from './crawlers/watchman'; -import WatchmanWatcher from './lib/watchman_watcher'; +import WatchmanWatcher from './lib/WatchmanWatcher'; import * as fastPath from './lib/fast_path'; import Worker from 'jest-worker'; @@ -43,7 +43,7 @@ import type { HasteRegExp, MockData, } from 'types/HasteMap'; -import type {SerializableModuleMap as HasteSerializableModuleMap} from './module_map'; +import type {SerializableModuleMap as HasteSerializableModuleMap} from './ModuleMap'; type HType = typeof H; diff --git a/packages/jest-haste-map/src/lib/watchman_watcher.js b/packages/jest-haste-map/src/lib/WatchmanWatcher.js similarity index 100% rename from packages/jest-haste-map/src/lib/watchman_watcher.js rename to packages/jest-haste-map/src/lib/WatchmanWatcher.js diff --git a/packages/jest-haste-map/src/lib/__tests__/extract_requires.test.js b/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js similarity index 98% rename from packages/jest-haste-map/src/lib/__tests__/extract_requires.test.js rename to packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js index b612edcf8cdf..a6172e0dcb8e 100644 --- a/packages/jest-haste-map/src/lib/__tests__/extract_requires.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js @@ -9,7 +9,7 @@ */ 'use strict'; -import extractRequires from '../extract_requires'; +import extractRequires from '../extractRequires'; it('extracts both requires and imports from code', () => { const code = ` diff --git a/packages/jest-haste-map/src/lib/__tests__/get_platform_extension.test.js b/packages/jest-haste-map/src/lib/__tests__/getPlatformExtension.test.js similarity index 92% rename from packages/jest-haste-map/src/lib/__tests__/get_platform_extension.test.js rename to packages/jest-haste-map/src/lib/__tests__/getPlatformExtension.test.js index df2c4fdc2db2..3c5da8702c24 100644 --- a/packages/jest-haste-map/src/lib/__tests__/get_platform_extension.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/getPlatformExtension.test.js @@ -9,7 +9,7 @@ 'use strict'; -import getPlatformExtension from '../get_platform_extension'; +import getPlatformExtension from '../getPlatformExtension'; describe('getPlatformExtension', () => { it('should get platform ext', () => { diff --git a/packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js b/packages/jest-haste-map/src/lib/__tests__/normalizePathSep.test.js similarity index 82% rename from packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js rename to packages/jest-haste-map/src/lib/__tests__/normalizePathSep.test.js index c6ed861b54a7..ab466fe6a62a 100644 --- a/packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/normalizePathSep.test.js @@ -13,14 +13,14 @@ describe('normalizePathSep', () => { it('does nothing on posix', () => { jest.resetModules(); jest.mock('path', () => jest.requireActual('path').posix); - const normalizePathSep = require('../normalize_path_sep').default; + const normalizePathSep = require('../normalizePathSep').default; expect(normalizePathSep('foo/bar/baz.js')).toEqual('foo/bar/baz.js'); }); it('replace slashes on windows', () => { jest.resetModules(); jest.mock('path', () => jest.requireActual('path').win32); - const normalizePathSep = require('../normalize_path_sep').default; + const normalizePathSep = require('../normalizePathSep').default; expect(normalizePathSep('foo/bar/baz.js')).toEqual('foo\\bar\\baz.js'); }); }); diff --git a/packages/jest-haste-map/src/lib/extract_requires.js b/packages/jest-haste-map/src/lib/extractRequires.js similarity index 100% rename from packages/jest-haste-map/src/lib/extract_requires.js rename to packages/jest-haste-map/src/lib/extractRequires.js diff --git a/packages/jest-haste-map/src/lib/get_platform_extension.js b/packages/jest-haste-map/src/lib/getPlatformExtension.js similarity index 100% rename from packages/jest-haste-map/src/lib/get_platform_extension.js rename to packages/jest-haste-map/src/lib/getPlatformExtension.js diff --git a/packages/jest-haste-map/src/lib/normalize_path_sep.js b/packages/jest-haste-map/src/lib/normalizePathSep.js similarity index 100% rename from packages/jest-haste-map/src/lib/normalize_path_sep.js rename to packages/jest-haste-map/src/lib/normalizePathSep.js diff --git a/packages/jest-haste-map/src/worker.js b/packages/jest-haste-map/src/worker.js index 53bc98be296d..acf575098e8f 100644 --- a/packages/jest-haste-map/src/worker.js +++ b/packages/jest-haste-map/src/worker.js @@ -14,7 +14,7 @@ import path from 'path'; import fs from 'graceful-fs'; import blacklist from './blacklist'; import H from './constants'; -import extractRequires from './lib/extract_requires'; +import extractRequires from './lib/extractRequires'; const PACKAGE_JSON = path.sep + 'package.json'; From c5e36835cff4b241327db9cf58c8f6f7227ed1f7 Mon Sep 17 00:00:00 2001 From: Daniel Ruf Date: Thu, 25 Oct 2018 09:00:54 +0200 Subject: [PATCH 03/45] fix: require Node.js 6+ for all packages (#7258) --- CHANGELOG.md | 1 + package.json | 3 +++ packages/babel-jest/package.json | 3 +++ packages/babel-plugin-jest-hoist/package.json | 3 +++ packages/babel-preset-jest/package.json | 3 +++ packages/diff-sequences/package.json | 3 +++ packages/eslint-config-fb-strict/package.json | 3 +++ packages/expect/package.json | 3 +++ packages/jest-changed-files/package.json | 3 +++ packages/jest-circus/package.json | 3 +++ packages/jest-config/package.json | 3 +++ packages/jest-diff/package.json | 3 +++ packages/jest-docblock/package.json | 3 +++ packages/jest-each/package.json | 3 +++ packages/jest-environment-jsdom/package.json | 3 +++ packages/jest-environment-node/package.json | 3 +++ packages/jest-get-type/package.json | 3 +++ packages/jest-haste-map/package.json | 3 +++ packages/jest-jasmine2/package.json | 3 +++ packages/jest-leak-detector/package.json | 3 +++ packages/jest-matcher-utils/package.json | 3 +++ packages/jest-message-util/package.json | 3 +++ packages/jest-mock/package.json | 3 +++ packages/jest-phabricator/package.json | 3 +++ packages/jest-regex-util/package.json | 3 +++ packages/jest-repl/package.json | 3 +++ packages/jest-resolve-dependencies/package.json | 3 +++ packages/jest-resolve/package.json | 3 +++ packages/jest-runner/package.json | 3 +++ packages/jest-runtime/package.json | 3 +++ packages/jest-serializer/package.json | 3 +++ packages/jest-snapshot/package.json | 3 +++ packages/jest-util/package.json | 3 +++ packages/jest-validate/package.json | 3 +++ packages/jest-watcher/package.json | 3 +++ packages/jest-worker/package.json | 3 +++ packages/pretty-format/package.json | 3 +++ 37 files changed, 109 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e306cecfbc08..264c361ed430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ - `[jest-diff]` Standardize filenames ([#7238](https://github.com/facebook/jest/pull/7238)) - `[*]` Add babel plugin to make sure Jest is unaffected by fake Promise implementations ([#7225](https://github.com/facebook/jest/pull/7225)) - `[jest-haste-map]` Standardize filenames ([#7266](https://github.com/facebook/jest/pull/7266)) +- `[*]` [**BREAKING**] Require Node.js 6+ for all packages ([#7258](https://github.com/facebook/jest/pull/7258)) ### Performance diff --git a/package.json b/package.json index d6ea708d7db8..412ff5e20274 100644 --- a/package.json +++ b/package.json @@ -118,5 +118,8 @@ "type": "opencollective", "url": "https://opencollective.com/jest", "logo": "https://opencollective.com/jest/logo.txt" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index dd0052e041e9..b9b8625aa97f 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -17,5 +17,8 @@ }, "peerDependencies": { "babel-core": "^6.0.0 || ^7.0.0-0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/babel-plugin-jest-hoist/package.json b/packages/babel-plugin-jest-hoist/package.json index c7923258b175..22ddd76455b4 100644 --- a/packages/babel-plugin-jest-hoist/package.json +++ b/packages/babel-plugin-jest-hoist/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js" } diff --git a/packages/babel-preset-jest/package.json b/packages/babel-preset-jest/package.json index 217247d29ddf..adfb0bfa9027 100644 --- a/packages/babel-preset-jest/package.json +++ b/packages/babel-preset-jest/package.json @@ -10,5 +10,8 @@ "dependencies": { "babel-plugin-jest-hoist": "^23.2.0", "babel-plugin-syntax-object-rest-spread": "^6.13.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/diff-sequences/package.json b/packages/diff-sequences/package.json index d8d6a7afd7d7..1428313d9399 100644 --- a/packages/diff-sequences/package.json +++ b/packages/diff-sequences/package.json @@ -14,5 +14,8 @@ "callback", "diff" ], + "engines": { + "node": ">= 6" + }, "main": "build/index.js" } diff --git a/packages/eslint-config-fb-strict/package.json b/packages/eslint-config-fb-strict/package.json index c963a54b9d4c..ab66821e3269 100644 --- a/packages/eslint-config-fb-strict/package.json +++ b/packages/eslint-config-fb-strict/package.json @@ -18,5 +18,8 @@ "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "~0.0.8" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/expect/package.json b/packages/expect/package.json index 8f488346b5b3..313df003904d 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -15,5 +15,8 @@ "jest-matcher-utils": "^23.6.0", "jest-message-util": "^23.4.0", "jest-regex-util": "^23.3.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-changed-files/package.json b/packages/jest-changed-files/package.json index cabb73c57560..b94dae7dcfa4 100644 --- a/packages/jest-changed-files/package.json +++ b/packages/jest-changed-files/package.json @@ -10,5 +10,8 @@ "dependencies": { "execa": "^1.0.0", "throat": "^4.0.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index e5dd7913f587..f1889e2d718b 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -25,5 +25,8 @@ "devDependencies": { "execa": "^1.0.0", "jest-runtime": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index 4bcf49b16f03..4bd4a8f5c40c 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -22,5 +22,8 @@ "jest-validate": "^23.6.0", "micromatch": "^2.3.11", "pretty-format": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 4410a02757a9..f8d179035aad 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -12,5 +12,8 @@ "diff": "^3.2.0", "jest-get-type": "^22.1.0", "pretty-format": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-docblock/package.json b/packages/jest-docblock/package.json index f93615b234db..fe5b997592e5 100644 --- a/packages/jest-docblock/package.json +++ b/packages/jest-docblock/package.json @@ -9,5 +9,8 @@ "main": "build/index.js", "dependencies": { "detect-newline": "^2.1.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index b985159c7057..342bc636b433 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -19,5 +19,8 @@ "chalk": "^2.0.1", "jest-util": "^23.4.0", "pretty-format": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-environment-jsdom/package.json b/packages/jest-environment-jsdom/package.json index f985f45ab81f..7d0b1df0de4d 100644 --- a/packages/jest-environment-jsdom/package.json +++ b/packages/jest-environment-jsdom/package.json @@ -11,5 +11,8 @@ "jest-mock": "^23.2.0", "jest-util": "^23.4.0", "jsdom": "^11.5.1" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-environment-node/package.json b/packages/jest-environment-node/package.json index 956538995feb..c56b96ff082f 100644 --- a/packages/jest-environment-node/package.json +++ b/packages/jest-environment-node/package.json @@ -10,5 +10,8 @@ "dependencies": { "jest-mock": "^23.2.0", "jest-util": "^23.4.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-get-type/package.json b/packages/jest-get-type/package.json index 1ee397bab10d..31bc2a8e0593 100644 --- a/packages/jest-get-type/package.json +++ b/packages/jest-get-type/package.json @@ -6,6 +6,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js" } diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index b0e5089cf015..4421d4156ce9 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -16,5 +16,8 @@ "jest-worker": "^23.2.0", "micromatch": "^2.3.11", "sane": "^3.0.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index 3294815a948e..bef29f9052bd 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -23,5 +23,8 @@ }, "devDependencies": { "jest-runtime": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-leak-detector/package.json b/packages/jest-leak-detector/package.json index d3c68e6ea4c5..d4d03fa78829 100644 --- a/packages/jest-leak-detector/package.json +++ b/packages/jest-leak-detector/package.json @@ -12,5 +12,8 @@ }, "devDependencies": { "weak": "^1.0.1" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index ffd725d22d1c..baf7017cbd44 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -6,6 +6,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js", "dependencies": { diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index d8e34d972d0f..9812ad2ed322 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js", "dependencies": { diff --git a/packages/jest-mock/package.json b/packages/jest-mock/package.json index e6826a9e65ea..7d7f2958a197 100644 --- a/packages/jest-mock/package.json +++ b/packages/jest-mock/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js", "browser": "build-es5/index.js" diff --git a/packages/jest-phabricator/package.json b/packages/jest-phabricator/package.json index 7706682a88e2..913598cd7a36 100644 --- a/packages/jest-phabricator/package.json +++ b/packages/jest-phabricator/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js" } diff --git a/packages/jest-regex-util/package.json b/packages/jest-regex-util/package.json index bd2a9ad7d06f..ab665d8b6805 100644 --- a/packages/jest-regex-util/package.json +++ b/packages/jest-regex-util/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js" } diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index 4f23fc46bfe6..95286104461f 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -16,5 +16,8 @@ }, "bin": { "jest-repl": "./bin/jest-repl.js" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index f7783fd0a313..20ed227945ae 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -10,5 +10,8 @@ "dependencies": { "jest-regex-util": "^23.3.0", "jest-snapshot": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 27690d89d9f7..4b380f43aa79 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -14,5 +14,8 @@ }, "devDependencies": { "jest-haste-map": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index ae9d25724778..e3cfd5d9609e 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -21,5 +21,8 @@ "jest-worker": "^23.2.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 5422e2da6ae5..1f0822befe46 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -37,5 +37,8 @@ }, "bin": { "jest-runtime": "./bin/jest-runtime.js" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-serializer/package.json b/packages/jest-serializer/package.json index 4b99781fe5f6..0bbb47d5cc72 100644 --- a/packages/jest-serializer/package.json +++ b/packages/jest-serializer/package.json @@ -5,6 +5,9 @@ "type": "git", "url": "https://github.com/facebook/jest.git" }, + "engines": { + "node": ">= 6" + }, "license": "MIT", "main": "build/index.js" } diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index 9e7eb2fa38da..56deb8bc3d85 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -21,5 +21,8 @@ }, "devDependencies": { "prettier": "^1.13.4" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-util/package.json b/packages/jest-util/package.json index c629f0caadbb..c2b0962f73a1 100644 --- a/packages/jest-util/package.json +++ b/packages/jest-util/package.json @@ -19,5 +19,8 @@ }, "devDependencies": { "jest-mock": "^23.2.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-validate/package.json b/packages/jest-validate/package.json index e9a5683cebec..33a9d90b4bb4 100644 --- a/packages/jest-validate/package.json +++ b/packages/jest-validate/package.json @@ -12,5 +12,8 @@ "jest-get-type": "^22.1.0", "leven": "^2.1.0", "pretty-format": "^23.6.0" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/jest-watcher/package.json b/packages/jest-watcher/package.json index 3a3aa657ae26..a2da8dd11379 100644 --- a/packages/jest-watcher/package.json +++ b/packages/jest-watcher/package.json @@ -15,6 +15,9 @@ "bugs": { "url": "https://github.com/facebook/jest/issues" }, + "engines": { + "node": ">= 6" + }, "homepage": "https://jestjs.io/", "license": "MIT" } diff --git a/packages/jest-worker/package.json b/packages/jest-worker/package.json index ee62bac69d07..5506a0d7160e 100644 --- a/packages/jest-worker/package.json +++ b/packages/jest-worker/package.json @@ -9,5 +9,8 @@ "main": "build/index.js", "dependencies": { "merge-stream": "^1.0.1" + }, + "engines": { + "node": ">= 6" } } diff --git a/packages/pretty-format/package.json b/packages/pretty-format/package.json index 852f826648a2..ec8a020bc6c1 100644 --- a/packages/pretty-format/package.json +++ b/packages/pretty-format/package.json @@ -19,5 +19,8 @@ "react": "*", "react-dom": "*", "react-test-renderer": "*" + }, + "engines": { + "node": ">= 6" } } From 4941a974e303db63e6ee5832f3737e69a138de18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 25 Oct 2018 14:23:54 +0100 Subject: [PATCH 04/45] Remove unused jest-docblock package from jest-haste-map (#7269) --- packages/jest-haste-map/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index 4421d4156ce9..0d00cc5b2fb1 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -11,7 +11,6 @@ "fb-watchman": "^2.0.0", "graceful-fs": "^4.1.11", "invariant": "^2.2.4", - "jest-docblock": "^23.2.0", "jest-serializer": "^23.0.1", "jest-worker": "^23.2.0", "micromatch": "^2.3.11", From 9db529ed804ed76411374b252389bd0b58d5d1d0 Mon Sep 17 00:00:00 2001 From: Christian Delahousse Date: Thu, 25 Oct 2018 14:58:53 -0700 Subject: [PATCH 05/45] Adding copyright headers to e2e/override-globals/setup.js (#7273) 'nuff said. --- e2e/override-globals/setup.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/e2e/override-globals/setup.js b/e2e/override-globals/setup.js index 0fb3e1ade0c8..de6dff3368d2 100644 --- a/e2e/override-globals/setup.js +++ b/e2e/override-globals/setup.js @@ -1,2 +1,11 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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. + * + * @flow + */ + Date.now = () => 0; process.hrtime = () => [0, 5000]; From a0d2404a52cf1d06ac6993530286b01c7a9a44b6 Mon Sep 17 00:00:00 2001 From: Edd Yerburgh Date: Fri, 26 Oct 2018 08:42:55 +0100 Subject: [PATCH 06/45] Add correct testURL default in docs (#7277) --- CHANGELOG.md | 1 + docs/Configuration.md | 2 +- website/versioned_docs/version-23.5/Configuration.md | 2 +- website/versioned_docs/version-23.6/Configuration.md | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 264c361ed430..6610643f005a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ - `[*]` Add babel plugin to make sure Jest is unaffected by fake Promise implementations ([#7225](https://github.com/facebook/jest/pull/7225)) - `[jest-haste-map]` Standardize filenames ([#7266](https://github.com/facebook/jest/pull/7266)) - `[*]` [**BREAKING**] Require Node.js 6+ for all packages ([#7258](https://github.com/facebook/jest/pull/7258)) +- `[docs]` Add correct default value for `testUrl` config option ([#7277](https://github.com/facebook/jest/pull/7277)) ### Performance diff --git a/docs/Configuration.md b/docs/Configuration.md index 55281c790207..73a841747cc1 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -905,7 +905,7 @@ An example of such function can be found in our default [jasmine2 test runner pa ### `testURL` [string] -Default: `about:blank` +Default: `http://localhost` This option sets the URL for the jsdom environment. It is reflected in properties such as `location.href`. diff --git a/website/versioned_docs/version-23.5/Configuration.md b/website/versioned_docs/version-23.5/Configuration.md index d7876e3f1569..ce8bb1ae41ae 100644 --- a/website/versioned_docs/version-23.5/Configuration.md +++ b/website/versioned_docs/version-23.5/Configuration.md @@ -871,7 +871,7 @@ An example of such function can be found in our default [jasmine2 test runner pa ### `testURL` [string] -Default: `about:blank` +Default: `http://localhost` This option sets the URL for the jsdom environment. It is reflected in properties such as `location.href`. diff --git a/website/versioned_docs/version-23.6/Configuration.md b/website/versioned_docs/version-23.6/Configuration.md index 430741801ac9..617f06826036 100644 --- a/website/versioned_docs/version-23.6/Configuration.md +++ b/website/versioned_docs/version-23.6/Configuration.md @@ -881,7 +881,7 @@ An example of such function can be found in our default [jasmine2 test runner pa ### `testURL` [string] -Default: `about:blank` +Default: `http://localhost` This option sets the URL for the jsdom environment. It is reflected in properties such as `location.href`. From d481defb350947eba0ebb0e597f7c67e13fd6159 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 26 Oct 2018 10:49:51 +0200 Subject: [PATCH 07/45] chore: remove flow annotation from setupfile --- e2e/override-globals/setup.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/e2e/override-globals/setup.js b/e2e/override-globals/setup.js index de6dff3368d2..ade70a19010f 100644 --- a/e2e/override-globals/setup.js +++ b/e2e/override-globals/setup.js @@ -3,8 +3,6 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * - * @flow */ Date.now = () => 0; From 251c2953d788031e36ad64c088d6947dec19ee84 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 26 Oct 2018 13:41:02 +0200 Subject: [PATCH 08/45] chore(docs): re-arrange Jets object docs into sections (#7278) --- docs/JestObjectAPI.md | 278 +++++++++++++++++++----------------------- 1 file changed, 127 insertions(+), 151 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 0442c12a34e6..89ded4fd7417 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -5,45 +5,7 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. -## Methods - -- [`jest.clearAllTimers()`](#jestclearalltimers) -- [`jest.disableAutomock()`](#jestdisableautomock) -- [`jest.enableAutomock()`](#jestenableautomock) -- [`jest.fn(implementation)`](#jestfnimplementation) -- [`jest.isMockFunction(fn)`](#jestismockfunctionfn) -- [`jest.genMockFromModule(moduleName)`](#jestgenmockfrommodulemodulename) -- [`jest.mock(moduleName, factory, options)`](#jestmockmodulename-factory-options) -- [`jest.unmock(moduleName)`](#jestunmockmodulename) -- [`jest.doMock(moduleName, factory, options)`](#jestdomockmodulename-factory-options) -- [`jest.dontMock(moduleName)`](#jestdontmockmodulename) -- [`jest.clearAllMocks()`](#jestclearallmocks) -- [`jest.resetAllMocks()`](#jestresetallmocks) -- [`jest.restoreAllMocks()`](#jestrestoreallmocks) -- [`jest.resetModules()`](#jestresetmodules) -- [`jest.retryTimes()`](#jestretrytimes) -- [`jest.runAllTicks()`](#jestrunallticks) -- [`jest.runAllTimers()`](#jestrunalltimers) -- [`jest.advanceTimersByTime(msToRun)`](#jestadvancetimersbytimemstorun) -- [`jest.runOnlyPendingTimers()`](#jestrunonlypendingtimers) -- [`jest.requireActual()`](#jestrequireactual) -- [`jest.requireMock()`](#jestrequiremock) -- [`jest.setMock(moduleName, moduleExports)`](#jestsetmockmodulename-moduleexports) -- [`jest.setTimeout(timeout)`](#jestsettimeouttimeout) -- [`jest.useFakeTimers()`](#jestusefaketimers) -- [`jest.useRealTimers()`](#jestuserealtimers) -- [`jest.spyOn(object, methodName)`](#jestspyonobject-methodname) -- [`jest.spyOn(object, methodName, accessType?)`](#jestspyonobject-methodname-accesstype) - ---- - -## Reference - -### `jest.clearAllTimers()` - -Removes any pending timers from the timer system. - -This means, if any timers have been scheduled (but have not yet executed), they will be cleared and will never have the opportunity to execute in the future. +## Mock Modules ### `jest.disableAutomock()` @@ -56,7 +18,9 @@ After this method is called, all `require()`s will return the real versions of e Jest configuration: ```json -"automock": true +{ + "automock": true +} ``` Example: @@ -126,24 +90,6 @@ test('original implementation', () => { _Note: this method was previously called `autoMockOn`. When using `babel-jest`, calls to `enableAutomock` will automatically be hoisted to the top of the code block. Use `autoMockOn` if you want to explicitly avoid this behavior._ -### `jest.fn(implementation)` - -Returns a new, unused [mock function](MockFunctionAPI.md). Optionally takes a mock implementation. - -```js -const mockFn = jest.fn(); -mockFn(); -expect(mockFn).toHaveBeenCalled(); - -// With a mock implementation: -const returnsTrue = jest.fn(() => true); -console.log(returnsTrue()); // true; -``` - -### `jest.isMockFunction(fn)` - -Determines if the given function is a mocked function. - ### `jest.genMockFromModule(moduleName)` Given the name of a module, use the automatic mocking system to generate a mocked version of the module for you. @@ -266,21 +212,25 @@ When using `babel-jest`, calls to `unmock` will automatically be hoisted to the Returns the `jest` object for chaining. -### `jest.clearAllMocks()` +### `jest.setMock(moduleName, moduleExports)` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Explicitly supplies the mock object that the module system should return for the specified module. + +On occasion there are times where the automatically generated mock the module system would normally provide you isn't adequate enough for your testing needs. Normally under those circumstances you should write a [manual mock](ManualMocks.md) that is more adequate for the module in question. However, on extremely rare occasions, even a manual mock isn't suitable for your purposes and you need to build the mock yourself inside your test. + +In these rare scenarios you can use this API to manually fill the slot in the module system's mock-module registry. Returns the `jest` object for chaining. -### `jest.resetAllMocks()` +_Note It is recommended to use [`jest.mock()`](#jestmockmodulename-factory-options) instead. The `jest.mock` API's second argument is a module factory instead of the expected exported module object._ -Resets the state of all mocks. Equivalent to calling [`.mockReset()`](MockFunctionAPI.md#mockfnmockreset) on every mocked function. +### `jest.requireActual(moduleName)` -Returns the `jest` object for chaining. +Returns the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not. -### `jest.restoreAllMocks()` +### `jest.requireMock(moduleName)` -Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when mock was created with `jest.spyOn`; other mocks will require you to manually restore them. +Returns a mock module instead of the actual module, bypassing all checks on whether the module should be required normally or not. ### `jest.resetModules()` @@ -315,100 +265,25 @@ test('works too', () => { Returns the `jest` object for chaining. -### `jest.retryTimes()` +## Mock functions -Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with [jest-circus](https://github.com/facebook/jest/tree/master/packages/jest-circus)! +### `jest.fn(implementation)` -Example in a test: +Returns a new, unused [mock function](MockFunctionAPI.md). Optionally takes a mock implementation. ```js -jest.retryTimes(3); -test('will fail', () => { - expect(true).toBe(false); -}); -``` - -Returns the `jest` object for chaining. - -### `jest.runAllTicks()` - -Exhausts the **micro**-task queue (usually interfaced in node via `process.nextTick`). - -When this API is called, all pending micro-tasks that have been queued via `process.nextTick` will be executed. Additionally, if those micro-tasks themselves schedule new micro-tasks, those will be continually exhausted until there are no more micro-tasks remaining in the queue. - -### `jest.runAllTimers()` - -Exhausts the **macro**-task queue (i.e., all tasks queued by `setTimeout()`, `setInterval()`, and `setImmediate()`). - -When this API is called, all pending "macro-tasks" that have been queued via `setTimeout()` or `setInterval()` will be executed. Additionally if those macro-tasks themselves schedule new macro-tasks, those will be continually exhausted until there are no more macro-tasks remaining in the queue. - -This is often useful for synchronously executing setTimeouts during a test in order to synchronously assert about some behavior that would only happen after the `setTimeout()` or `setInterval()` callbacks executed. See the [Timer mocks](TimerMocks.md) doc for more information. - -### `jest.runAllImmediates()` - -Exhausts all tasks queued by `setImmediate()`. - -### `jest.advanceTimersByTime(msToRun)` - -##### renamed in Jest **22.0.0+** - -Also under the alias: `.runTimersToTime()` - -Executes only the macro task queue (i.e. all tasks queued by `setTimeout()` or `setInterval()` and `setImmediate()`). - -When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via `setTimeout()` or `setInterval()`, and would be executed within this time frame will be executed. Additionally if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within `msToRun` milliseconds. - -### `jest.runOnlyPendingTimers()` - -Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by `setTimeout()` or `setInterval()` up to this point). If any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call. - -This is useful for scenarios such as one where the module being tested schedules a `setTimeout()` whose callback schedules another `setTimeout()` recursively (meaning the scheduling never stops). In these scenarios, it's useful to be able to run forward in time by a single step at a time. - -### `jest.requireActual(moduleName)` - -Returns the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not. - -### `jest.requireMock(moduleName)` - -Returns a mock module instead of the actual module, bypassing all checks on whether the module should be required normally or not. - -### `jest.setMock(moduleName, moduleExports)` - -Explicitly supplies the mock object that the module system should return for the specified module. - -On occasion there are times where the automatically generated mock the module system would normally provide you isn't adequate enough for your testing needs. Normally under those circumstances you should write a [manual mock](ManualMocks.md) that is more adequate for the module in question. However, on extremely rare occasions, even a manual mock isn't suitable for your purposes and you need to build the mock yourself inside your test. - -In these rare scenarios you can use this API to manually fill the slot in the module system's mock-module registry. - -Returns the `jest` object for chaining. - -_Note It is recommended to use [`jest.mock()`](#jestmockmodulename-factory-options) instead. The `jest.mock` API's second argument is a module factory instead of the expected exported module object._ - -### `jest.setTimeout(timeout)` - -Set the default timeout interval for tests and before/after hooks in milliseconds. - -_Note: The default timeout interval is 5 seconds if this method is not called._ - -_Note: The method must be called after the test framework is installed in the environment and before the test runs. A good place to do this is in the `setupTestFrameworkScriptFile`._ - -Example: +const mockFn = jest.fn(); +mockFn(); +expect(mockFn).toHaveBeenCalled(); -```js -jest.setTimeout(1000); // 1 second +// With a mock implementation: +const returnsTrue = jest.fn(() => true); +console.log(returnsTrue()); // true; ``` -### `jest.useFakeTimers()` - -Instructs Jest to use fake versions of the standard timer functions (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, `setImmediate` and `clearImmediate`). - -Returns the `jest` object for chaining. - -### `jest.useRealTimers()` - -Instructs Jest to use the real versions of the standard timer functions. +### `jest.isMockFunction(fn)` -Returns the `jest` object for chaining. +Determines if the given function is a mocked function. ### `jest.spyOn(object, methodName)` @@ -501,3 +376,104 @@ test('plays audio', () => { spy.mockRestore(); }); ``` + +### `jest.clearAllMocks()` + +Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.resetAllMocks()` + +Resets the state of all mocks. Equivalent to calling [`.mockReset()`](MockFunctionAPI.md#mockfnmockreset) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.restoreAllMocks()` + +Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when mock was created with `jest.spyOn`; other mocks will require you to manually restore them. + +## Mock timers + +### `jest.useFakeTimers()` + +Instructs Jest to use fake versions of the standard timer functions (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, `setImmediate` and `clearImmediate`). + +Returns the `jest` object for chaining. + +### `jest.useRealTimers()` + +Instructs Jest to use the real versions of the standard timer functions. + +Returns the `jest` object for chaining. + +### `jest.runAllTicks()` + +Exhausts the **micro**-task queue (usually interfaced in node via `process.nextTick`). + +When this API is called, all pending micro-tasks that have been queued via `process.nextTick` will be executed. Additionally, if those micro-tasks themselves schedule new micro-tasks, those will be continually exhausted until there are no more micro-tasks remaining in the queue. + +### `jest.runAllTimers()` + +Exhausts the **macro**-task queue (i.e., all tasks queued by `setTimeout()`, `setInterval()`, and `setImmediate()`). + +When this API is called, all pending "macro-tasks" that have been queued via `setTimeout()` or `setInterval()` will be executed. Additionally if those macro-tasks themselves schedule new macro-tasks, those will be continually exhausted until there are no more macro-tasks remaining in the queue. + +This is often useful for synchronously executing setTimeouts during a test in order to synchronously assert about some behavior that would only happen after the `setTimeout()` or `setInterval()` callbacks executed. See the [Timer mocks](TimerMocks.md) doc for more information. + +### `jest.runAllImmediates()` + +Exhausts all tasks queued by `setImmediate()`. + +### `jest.advanceTimersByTime(msToRun)` + +##### renamed in Jest **22.0.0+** + +Also under the alias: `.runTimersToTime()` + +Executes only the macro task queue (i.e. all tasks queued by `setTimeout()` or `setInterval()` and `setImmediate()`). + +When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via `setTimeout()` or `setInterval()`, and would be executed within this time frame will be executed. Additionally if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within `msToRun` milliseconds. + +### `jest.runOnlyPendingTimers()` + +Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by `setTimeout()` or `setInterval()` up to this point). If any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call. + +This is useful for scenarios such as one where the module being tested schedules a `setTimeout()` whose callback schedules another `setTimeout()` recursively (meaning the scheduling never stops). In these scenarios, it's useful to be able to run forward in time by a single step at a time. + +### `jest.clearAllTimers()` + +Removes any pending timers from the timer system. + +This means, if any timers have been scheduled (but have not yet executed), they will be cleared and will never have the opportunity to execute in the future. + +## Misc + +### `jest.setTimeout(timeout)` + +Set the default timeout interval for tests and before/after hooks in milliseconds. + +_Note: The default timeout interval is 5 seconds if this method is not called._ + +_Note: The method must be called after the test framework is installed in the environment and before the test runs. A good place to do this is in the `setupTestFrameworkScriptFile`._ + +Example: + +```js +jest.setTimeout(1000); // 1 second +``` + +### `jest.retryTimes()` + +Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with [jest-circus](https://github.com/facebook/jest/tree/master/packages/jest-circus)! + +Example in a test: + +```js +jest.retryTimes(3); +test('will fail', () => { + expect(true).toBe(false); +}); +``` + +Returns the `jest` object for chaining. From e41f0bb257c6652c3100b97a1087f9f812fbea0d Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 26 Oct 2018 16:55:07 +0200 Subject: [PATCH 09/45] chore: remove long-deprecated timer globals (#7285) --- CHANGELOG.md | 2 ++ docs/JestObjectAPI.md | 4 +++ .../src/__mocks__/index.js | 1 - packages/jest-runtime/src/index.js | 29 ++++++++++--------- .../src/__tests__/fake_timers.test.js | 22 ++++++++++++++ packages/jest-util/src/fake_timers.js | 16 ++++------ types/Environment.js | 1 + types/Jest.js | 1 + 8 files changed, 52 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6610643f005a..c316ca84cad7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - `[jest-config]` Accept an array as as well as a string for `testRegex`([#7209]https://github.com/facebook/jest/pull/7209)) - `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203)) - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) +- `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) ### Fixes @@ -85,6 +86,7 @@ - `[jest-haste-map]` Standardize filenames ([#7266](https://github.com/facebook/jest/pull/7266)) - `[*]` [**BREAKING**] Require Node.js 6+ for all packages ([#7258](https://github.com/facebook/jest/pull/7258)) - `[docs]` Add correct default value for `testUrl` config option ([#7277](https://github.com/facebook/jest/pull/7277)) +- `[jest-util]` [**BREAKING**] Remove long-deprecated globals for fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) ### Performance diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 89ded4fd7417..58c86823eb64 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -447,6 +447,10 @@ Removes any pending timers from the timer system. This means, if any timers have been scheduled (but have not yet executed), they will be cleared and will never have the opportunity to execute in the future. +### `jest.getTimerCount()` + +Returns the number of fake timers still left to run. + ## Misc ### `jest.setTimeout(timeout)` diff --git a/packages/jest-environment-jsdom/src/__mocks__/index.js b/packages/jest-environment-jsdom/src/__mocks__/index.js index 68f8411ac835..8ae042ba08ed 100644 --- a/packages/jest-environment-jsdom/src/__mocks__/index.js +++ b/packages/jest-environment-jsdom/src/__mocks__/index.js @@ -14,7 +14,6 @@ JSDOMEnvironment.mockImplementation(function(config) { this.global = { JSON, console: {}, - mockClearTimers: jest.fn(), }; const globalValues = Object.assign({}, config.globals); diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index 8adede5ec442..a24ed1712fd3 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -445,20 +445,22 @@ class Runtime { this._mockRegistry = Object.create(null); this._moduleRegistry = Object.create(null); - if (this._environment && this._environment.global) { - const envGlobal = this._environment.global; - Object.keys(envGlobal).forEach(key => { - const globalMock = envGlobal[key]; - if ( - (typeof globalMock === 'object' && globalMock !== null) || - typeof globalMock === 'function' - ) { - globalMock._isMockFunction === true && globalMock.mockClear(); - } - }); + if (this._environment) { + if (this._environment.global) { + const envGlobal = this._environment.global; + Object.keys(envGlobal).forEach(key => { + const globalMock = envGlobal[key]; + if ( + (typeof globalMock === 'object' && globalMock !== null) || + typeof globalMock === 'function' + ) { + globalMock._isMockFunction === true && globalMock.mockClear(); + } + }); + } - if (envGlobal.mockClearTimers) { - envGlobal.mockClearTimers(); + if (this._environment.fakeTimers) { + this._environment.fakeTimers.clearAllTimers(); } } } @@ -932,6 +934,7 @@ class Runtime { fn, genMockFromModule: (moduleName: string) => this._generateMock(from, moduleName), + getTimerCount: () => this._environment.fakeTimers.getTimerCount(), isMockFunction: this._moduleMocker.isMockFunction, mock, requireActual: localRequire.requireActual, diff --git a/packages/jest-util/src/__tests__/fake_timers.test.js b/packages/jest-util/src/__tests__/fake_timers.test.js index a9d8434532bf..c214f0312591 100644 --- a/packages/jest-util/src/__tests__/fake_timers.test.js +++ b/packages/jest-util/src/__tests__/fake_timers.test.js @@ -943,4 +943,26 @@ describe('FakeTimers', () => { expect(global.clearImmediate).not.toBe(nativeClearImmediate); }); }); + + describe('getTimerCount', () => { + it('returns the correct count', () => { + const timers = new FakeTimers({global, moduleMocker, timerConfig}); + + timers.useFakeTimers(); + + global.setTimeout(() => {}, 0); + global.setTimeout(() => {}, 0); + global.setTimeout(() => {}, 10); + + expect(timers.getTimerCount()).toEqual(3); + + timers.advanceTimersByTime(5); + + expect(timers.getTimerCount()).toEqual(1); + + timers.advanceTimersByTime(5); + + expect(timers.getTimerCount()).toEqual(0); + }); + }); }); diff --git a/packages/jest-util/src/fake_timers.js b/packages/jest-util/src/fake_timers.js index a31cb67b2c72..e1c64f6ce2c4 100644 --- a/packages/jest-util/src/fake_timers.js +++ b/packages/jest-util/src/fake_timers.js @@ -114,16 +114,6 @@ export default class FakeTimers { this.reset(); this._createMocks(); - - // These globally-accessible function are now deprecated! - // They will go away very soon, so do not use them! - // Instead, use the versions available on the `jest` object - global.mockRunTicksRepeatedly = this.runAllTicks.bind(this); - global.mockRunTimersOnce = this.runOnlyPendingTimers.bind(this); - global.mockAdvanceTimersByTime = this.advanceTimersByTime.bind(this); - global.mockRunTimersRepeatedly = this.runAllTimers.bind(this); - global.mockClearTimers = this.clearAllTimers.bind(this); - global.mockGetTimersCount = () => Object.keys(this._timers).length; } clearAllTimers() { @@ -352,6 +342,12 @@ export default class FakeTimers { global.process.nextTick = this._fakeTimerAPIs.nextTick; } + getTimerCount() { + this._checkFakeTimers(); + + return Object.keys(this._timers).length; + } + _checkFakeTimers() { if (this._global.setTimeout !== this._fakeTimerAPIs.setTimeout) { this._global.console.warn( diff --git a/types/Environment.js b/types/Environment.js index ed6ee314c490..07128ef7da27 100644 --- a/types/Environment.js +++ b/types/Environment.js @@ -28,6 +28,7 @@ declare class $JestEnvironment { advanceTimersByTime(msToRun: number): void, runOnlyPendingTimers(): void, runWithRealTimers(callback: any): void, + getTimerCount(): number, useFakeTimers(): void, useRealTimers(): void, }; diff --git a/types/Jest.js b/types/Jest.js index 88966e299f2c..889c45382a95 100644 --- a/types/Jest.js +++ b/types/Jest.js @@ -39,6 +39,7 @@ export type Jest = {| runOnlyPendingTimers(): void, advanceTimersByTime(msToRun: number): void, runTimersToTime(msToRun: number): void, + getTimerCount(): number, setMock(moduleName: string, moduleExports: any): Jest, setTimeout(timeout: number): Jest, spyOn( From c22d9f584627a1ae6c476d44f10c3c186b480722 Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Fri, 26 Oct 2018 15:01:11 -0700 Subject: [PATCH 10/45] Add shorthand for watch plugins and runners (#7213) --- CHANGELOG.md | 1 + docs/Configuration.md | 18 +++ .../__snapshots__/normalize.test.js.snap | 20 +++ .../src/__tests__/normalize.test.js | 121 ++++++++++++++++-- packages/jest-config/src/normalize.js | 22 +++- packages/jest-config/src/utils.js | 110 +++++++++++++--- packages/jest-runner/src/run_test.js | 1 + .../version-23.6/Configuration.md | 14 ++ 8 files changed, 273 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c316ca84cad7..986b2950b6dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- `[jest-config]` Add shorthand for watch plugins and runners ([#7213](https://github.com/facebook/jest/pull/7213)) - `[jest-config]` [**BREAKING**] Deprecate `setupTestFrameworkScriptFile` in favor of new `setupFilesAfterEnv` ([#7119](https://github.com/facebook/jest/pull/7119)) - `[jest-jasmine2/jest-circus/jest-cli]` Add test.todo ([#6996](https://github.com/facebook/jest/pull/6996)) - `[pretty-format]` Option to not escape strings in diff messages ([#5661](https://github.com/facebook/jest/pull/5661)) diff --git a/docs/Configuration.md b/docs/Configuration.md index 73a841747cc1..edd6a0f1cf54 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -609,6 +609,8 @@ This option allows you to use a custom runner instead of Jest's default test run - [`jest-runner-tsc`](https://github.com/azz/jest-runner-tsc) - [`jest-runner-prettier`](https://github.com/keplersj/jest-runner-prettier) +_Note: The `runner` property value can omit the `jest-runner-` prefix of the package name._ + To write a test-runner, export a class with which accepts `globalConfig` in the constructor, and has a `runTests` method with the signature: ```ts @@ -962,3 +964,19 @@ Default: `[]` An array of RegExp patterns that are matched against all source file paths before re-running tests in watch mode. If the file path matches any of the patterns, when it is updated, it will not trigger a re-run of tests. These patterns match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. Example: `["/node_modules/"]`. + +### `watchPlugins` [array] + +Default: `[]` + +This option allows you to use a custom watch plugins. Read more about watch plugins [here](watch-plugins). + +Examples of watch plugins include: + +- [`jest-watch-master`](https://github.com/rickhanlonii/jest-watch-master) +- [`jest-watch-select-projects`](https://github.com/rogeliog/jest-watch-select-projects) +- [`jest-watch-suspend`](https://github.com/unional/jest-watch-suspend) +- [`jest-watch-typeahead`](https://github.com/jest-community/jest-watch-typeahead) +- [`jest-watch-yarn-workspaces`](https://github.com/cameronhunter/jest-watch-directories/tree/master/packages/jest-watch-yarn-workspaces) + +_Note: The values in the `watchPlugins` property value can omit the `jest-watch-` prefix of the package name._ diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap index c8edc2f5911b..ea5a367f3d53 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap @@ -47,6 +47,16 @@ exports[`rootDir throws if the options is missing a rootDir property 1`] = ` " `; +exports[`runner throw error when a runner is not found 1`] = ` +"Validation Error: + + Jest Runner missing-runner cannot be found. Make sure the runner configuration option points to an existing node module. + + Configuration Documentation: + https://jestjs.io/docs/configuration.html +" +`; + exports[`setupTestFrameworkScriptFile logs a deprecation warning when \`setupTestFrameworkScriptFile\` is used 1`] = ` " Deprecation Warning: @@ -93,3 +103,13 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` exports[`testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; exports[`testPathPattern --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; + +exports[`watchPlugins throw error when a watch plugin is not found 1`] = ` +"Validation Error: + + Watch plugin missing-plugin cannot be found. Make sure the watchPlugins configuration option points to an existing node module. + + Configuration Documentation: + https://jestjs.io/docs/configuration.html +" +`; diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index 48c2fc306b01..e801b998b797 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -671,11 +671,8 @@ describe('testEnvironment', () => { beforeEach(() => { Resolver = require('jest-resolve'); Resolver.findNodeModule = jest.fn(name => { - if (name === 'jsdom') { - return 'node_modules/jsdom'; - } - if (name === 'jest-environment-jsdom') { - return 'node_modules/jest-environment-jsdom'; + if (['jsdom', 'jest-environment-jsdom'].includes(name)) { + return `node_modules/${name}`; } if (name.startsWith('/root')) { return name; @@ -1205,15 +1202,79 @@ describe('preset without setupFiles', () => { }); }); +describe('runner', () => { + let Resolver; + beforeEach(() => { + Resolver = require('jest-resolve'); + Resolver.findNodeModule = jest.fn(name => { + if (['eslint', 'jest-runner-eslint', 'my-runner-foo'].includes(name)) { + return `node_modules/${name}`; + } + if (name.startsWith('/root')) { + return name; + } + return findNodeModule(name); + }); + }); + + it('defaults to `jest-runner`', () => { + const {options} = normalize({rootDir: '/root'}, {}); + + expect(options.runner).toBe('jest-runner'); + }); + + it('resolves to runners that do not have the prefix', () => { + const {options} = normalize( + { + rootDir: '/root/', + runner: 'my-runner-foo', + }, + {}, + ); + + expect(options.runner).toBe('node_modules/my-runner-foo'); + }); + + it('resolves to runners and prefers jest-runner-`name`', () => { + const {options} = normalize( + { + rootDir: '/root/', + runner: 'eslint', + }, + {}, + ); + + expect(options.runner).toBe('node_modules/jest-runner-eslint'); + }); + + it('throw error when a runner is not found', () => { + expect(() => + normalize( + { + rootDir: '/root/', + runner: 'missing-runner', + }, + {}, + ), + ).toThrowErrorMatchingSnapshot(); + }); +}); + describe('watchPlugins', () => { let Resolver; beforeEach(() => { Resolver = require('jest-resolve'); Resolver.findNodeModule = jest.fn(name => { - if (name.startsWith(path.sep)) { + if ( + ['typeahead', 'jest-watch-typeahead', 'my-watch-plugin'].includes(name) + ) { + return `node_modules/${name}`; + } + + if (name.startsWith('/root')) { return name; } - return path.sep + 'node_modules' + path.sep + name; + return findNodeModule(name); }); }); @@ -1223,20 +1284,60 @@ describe('watchPlugins', () => { expect(options.watchPlugins).toEqual(undefined); }); - it('normalizes watchPlugins', () => { + it('resolves to watch plugins and prefers jest-watch-`name`', () => { const {options} = normalize( { rootDir: '/root/', - watchPlugins: ['my-watch-plugin', '/path/to/plugin'], + watchPlugins: ['typeahead'], }, {}, ); expect(options.watchPlugins).toEqual([ - {config: {}, path: '/node_modules/my-watch-plugin'}, + {config: {}, path: 'node_modules/jest-watch-typeahead'}, + ]); + }); + + it('resolves watch plugins that do not have the prefix', () => { + const {options} = normalize( + { + rootDir: '/root/', + watchPlugins: ['my-watch-plugin'], + }, + {}, + ); + + expect(options.watchPlugins).toEqual([ + {config: {}, path: 'node_modules/my-watch-plugin'}, + ]); + }); + + it('normalizes multiple watchPlugins', () => { + const {options} = normalize( + { + rootDir: '/root/', + watchPlugins: ['jest-watch-typeahead', '/path/to/plugin'], + }, + {}, + ); + + expect(options.watchPlugins).toEqual([ + {config: {}, path: 'node_modules/jest-watch-typeahead'}, {config: {}, path: '/root/path/to/plugin'}, ]); }); + + it('throw error when a watch plugin is not found', () => { + expect(() => + normalize( + { + rootDir: '/root/', + watchPlugins: ['missing-plugin'], + }, + {}, + ), + ).toThrowErrorMatchingSnapshot(); + }); }); describe('testPathPattern', () => { diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 018f223d87f9..0defd7699714 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -28,6 +28,8 @@ import { _replaceRootDirTags, escapeGlobCharacters, getTestEnvironment, + getRunner, + getWatchPlugin, resolve, } from './utils'; import {DEFAULT_JS_PATTERN, DEFAULT_REPORTER_LABEL} from './constants'; @@ -394,7 +396,10 @@ export default function normalize(options: InitialOptions, argv: Argv) { } if (options.testEnvironment) { - options.testEnvironment = getTestEnvironment(options); + options.testEnvironment = getTestEnvironment({ + rootDir: options.rootDir, + testEnvironment: options.testEnvironment, + }); } if (!options.roots && options.testPathDirs) { @@ -475,7 +480,6 @@ export default function normalize(options: InitialOptions, argv: Argv) { case 'globalSetup': case 'globalTeardown': case 'moduleLoader': - case 'runner': case 'snapshotResolver': case 'testResultsProcessor': case 'testRunner': @@ -488,6 +492,14 @@ export default function normalize(options: InitialOptions, argv: Argv) { rootDir: options.rootDir, }); break; + case 'runner': + value = + options[key] && + getRunner(newOptions.resolver, { + filePath: options[key], + rootDir: options.rootDir, + }); + break; case 'prettierPath': // We only want this to throw if "prettierPath" is explicitly passed // from config or CLI, and the requested path isn't found. Otherwise we @@ -658,18 +670,16 @@ export default function normalize(options: InitialOptions, argv: Argv) { if (typeof watchPlugin === 'string') { return { config: {}, - path: resolve(newOptions.resolver, { + path: getWatchPlugin(newOptions.resolver, { filePath: watchPlugin, - key, rootDir: options.rootDir, }), }; } else { return { config: watchPlugin[1] || {}, - path: resolve(newOptions.resolver, { + path: getWatchPlugin(newOptions.resolver, { filePath: watchPlugin[0], - key, rootDir: options.rootDir, }), }; diff --git a/packages/jest-config/src/utils.js b/packages/jest-config/src/utils.js index fb4aae572ae1..95f3b0a976ab 100644 --- a/packages/jest-config/src/utils.js +++ b/packages/jest-config/src/utils.js @@ -102,45 +102,119 @@ export const _replaceRootDirTags = (rootDir: string, config: any) => { return config; }; -/** - * Finds the test environment to use: - * - * 1. looks for jest-environment- relative to project. - * 1. looks for jest-environment- relative to Jest. - * 1. looks for relative to project. - * 1. looks for relative to Jest. - */ -export const getTestEnvironment = (config: Object) => { - const env = replaceRootDirInPath(config.rootDir, config.testEnvironment); - let module = Resolver.findNodeModule(`jest-environment-${env}`, { - basedir: config.rootDir, +export const resolveWithPrefix = ( + resolver: ?string, + { + filePath, + humanOptionName, + optionName, + prefix, + rootDir, + }: { + filePath: string, + humanOptionName: string, + optionName: string, + prefix: string, + rootDir: string, + }, +) => { + const fileName = replaceRootDirInPath(rootDir, filePath); + let module = Resolver.findNodeModule(`${prefix}${fileName}`, { + basedir: rootDir, + resolver, }); if (module) { return module; } try { - return require.resolve(`jest-environment-${env}`); + return require.resolve(`${prefix}${fileName}`); } catch (e) {} - module = Resolver.findNodeModule(env, {basedir: config.rootDir}); + module = Resolver.findNodeModule(fileName, { + basedir: rootDir, + resolver, + }); if (module) { return module; } try { - return require.resolve(env); + return require.resolve(fileName); } catch (e) {} throw createValidationError( - ` Test environment ${chalk.bold( - env, + ` ${humanOptionName} ${chalk.bold( + fileName, )} cannot be found. Make sure the ${chalk.bold( - 'testEnvironment', + optionName, )} configuration option points to an existing node module.`, ); }; +/** + * Finds the test environment to use: + * + * 1. looks for jest-environment- relative to project. + * 1. looks for jest-environment- relative to Jest. + * 1. looks for relative to project. + * 1. looks for relative to Jest. + */ +export const getTestEnvironment = ({ + rootDir, + testEnvironment: filePath, +}: { + rootDir: string, + testEnvironment: string, +}) => + resolveWithPrefix(null, { + filePath, + humanOptionName: 'Test environment', + optionName: 'testEnvironment', + prefix: 'jest-environment-', + rootDir, + }); + +/** + * Finds the watch plugins to use: + * + * 1. looks for jest-watch- relative to project. + * 1. looks for jest-watch- relative to Jest. + * 1. looks for relative to project. + * 1. looks for relative to Jest. + */ +export const getWatchPlugin = ( + resolver: ?string, + {filePath, rootDir}: {filePath: string, rootDir: string}, +) => + resolveWithPrefix(resolver, { + filePath, + humanOptionName: 'Watch plugin', + optionName: 'watchPlugins', + prefix: 'jest-watch-', + rootDir, + }); + +/** + * Finds the runner to use: + * + * 1. looks for jest-runner- relative to project. + * 1. looks for jest-runner- relative to Jest. + * 1. looks for relative to project. + * 1. looks for relative to Jest. + */ +export const getRunner = ( + resolver: ?string, + {filePath, rootDir}: {filePath: string, rootDir: string}, +) => + resolveWithPrefix(resolver, { + filePath, + humanOptionName: 'Jest Runner', + optionName: 'runner', + prefix: 'jest-runner-', + rootDir, + }); + export const isJSONString = (text: ?string) => text && typeof text === 'string' && diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index bba71b2c2dfe..4292349ec8e3 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -58,6 +58,7 @@ async function runTestInternal( if (customEnvironment) { testEnvironment = getTestEnvironment( Object.assign({}, config, { + // $FlowFixMe testEnvironment: customEnvironment, }), ); diff --git a/website/versioned_docs/version-23.6/Configuration.md b/website/versioned_docs/version-23.6/Configuration.md index 617f06826036..a687b04524e4 100644 --- a/website/versioned_docs/version-23.6/Configuration.md +++ b/website/versioned_docs/version-23.6/Configuration.md @@ -938,3 +938,17 @@ Default: `[]` An array of RegExp patterns that are matched against all source file paths before re-running tests in watch mode. If the file path matches any of the patterns, when it is updated, it will not trigger a re-run of tests. These patterns match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. Example: `["/node_modules/"]`. + +### `watchPlugins` [array] + +Default: `[]` + +This option allows you to use a custom watch plugins. Read more about watch plugins [here](watch-plugins). + +Examples of watch plugins include: + +- [`jest-watch-master`](https://github.com/rickhanlonii/jest-watch-master) +- [`jest-watch-select-projects`](https://github.com/rogeliog/jest-watch-select-projects) +- [`jest-watch-suspend`](https://github.com/unional/jest-watch-suspend) +- [`jest-watch-typeahead`](https://github.com/jest-community/jest-watch-typeahead) +- [`jest-watch-yarn-workspaces`](https://github.com/cameronhunter/jest-watch-directories/tree/master/packages/jest-watch-yarn-workspaces) From 5a624d414ba0c4063b25199b16c2953de01fa55a Mon Sep 17 00:00:00 2001 From: Anenth Date: Sun, 28 Oct 2018 18:26:29 +0530 Subject: [PATCH 11/45] Standardize file names in packages/jest-jasmine2 (#7290) ## Summary This is part of #4969 - standardizes file names in packages/jest-jasmine2 under Facebook naming conventions ## Test plan Did a manual verification, Tried running `yarn test` but got failure event on main --- ...ectation_failed.js => ExpectationFailed.js} | 0 .../src/{p_cancelable.js => PCancelable.js} | 0 ...p => expectationResultFactory.test.js.snap} | 0 ...est.js => expectationResultFactory.test.js} | 2 +- ...{hooks_error.test.js => hooksError.test.js} | 0 ..._test_error.test.js => itTestError.test.js} | 0 ...est_alias.test.js => itToTestAlias.test.js} | 0 .../{p_timeout.test.js => pTimeout.test.js} | 2 +- ...ueue_runner.test.js => queueRunner.test.js} | 2 +- .../{todo_error.test.js => todoError.test.js} | 0 ...ert_support.js => assertionErrorMessage.js} | 0 .../{error_on_private.js => errorOnPrivate.js} | 0 ..._factory.js => expectationResultFactory.js} | 0 packages/jest-jasmine2/src/index.js | 8 ++++---- .../src/{is_error.js => isError.js} | 0 .../{call_tracker.js => CallTracker.js} | 0 packages/jest-jasmine2/src/jasmine/Env.js | 18 +++++++++--------- .../{js_api_reporter.js => JsApiReporter.js} | 0 ...eport_dispatcher.js => ReportDispatcher.js} | 0 packages/jest-jasmine2/src/jasmine/Spec.js | 6 +++--- .../{spy_strategy.js => SpyStrategy.js} | 0 packages/jest-jasmine2/src/jasmine/Suite.js | 4 ++-- .../jasmine/{create_spy.js => createSpy.js} | 4 ++-- .../{jasmine_light.js => jasmineLight.js} | 8 ++++---- .../{spy_registry.js => spyRegistry.js} | 6 +++--- ...jasmine_async.js => jasmineAsyncInstall.js} | 12 ++++++------ .../src/{jest_expect.js => jestExpect.js} | 0 .../src/{p_timeout.js => pTimeout.js} | 0 .../src/{queue_runner.js => queueRunner.js} | 4 ++-- .../{tree_processor.js => treeProcessor.js} | 0 30 files changed, 38 insertions(+), 38 deletions(-) rename packages/jest-jasmine2/src/{expectation_failed.js => ExpectationFailed.js} (100%) rename packages/jest-jasmine2/src/{p_cancelable.js => PCancelable.js} (100%) rename packages/jest-jasmine2/src/__tests__/__snapshots__/{expectation_result_factory.test.js.snap => expectationResultFactory.test.js.snap} (100%) rename packages/jest-jasmine2/src/__tests__/{expectation_result_factory.test.js => expectationResultFactory.test.js} (96%) rename packages/jest-jasmine2/src/__tests__/{hooks_error.test.js => hooksError.test.js} (100%) rename packages/jest-jasmine2/src/__tests__/{it_test_error.test.js => itTestError.test.js} (100%) rename packages/jest-jasmine2/src/__tests__/{it_to_test_alias.test.js => itToTestAlias.test.js} (100%) rename packages/jest-jasmine2/src/__tests__/{p_timeout.test.js => pTimeout.test.js} (97%) rename packages/jest-jasmine2/src/__tests__/{queue_runner.test.js => queueRunner.test.js} (98%) rename packages/jest-jasmine2/src/__tests__/{todo_error.test.js => todoError.test.js} (100%) rename packages/jest-jasmine2/src/{assert_support.js => assertionErrorMessage.js} (100%) rename packages/jest-jasmine2/src/{error_on_private.js => errorOnPrivate.js} (100%) rename packages/jest-jasmine2/src/{expectation_result_factory.js => expectationResultFactory.js} (100%) rename packages/jest-jasmine2/src/{is_error.js => isError.js} (100%) rename packages/jest-jasmine2/src/jasmine/{call_tracker.js => CallTracker.js} (100%) rename packages/jest-jasmine2/src/jasmine/{js_api_reporter.js => JsApiReporter.js} (100%) rename packages/jest-jasmine2/src/jasmine/{report_dispatcher.js => ReportDispatcher.js} (100%) rename packages/jest-jasmine2/src/jasmine/{spy_strategy.js => SpyStrategy.js} (100%) rename packages/jest-jasmine2/src/jasmine/{create_spy.js => createSpy.js} (96%) rename packages/jest-jasmine2/src/jasmine/{jasmine_light.js => jasmineLight.js} (95%) rename packages/jest-jasmine2/src/jasmine/{spy_registry.js => spyRegistry.js} (97%) rename packages/jest-jasmine2/src/{jasmine_async.js => jasmineAsyncInstall.js} (93%) rename packages/jest-jasmine2/src/{jest_expect.js => jestExpect.js} (100%) rename packages/jest-jasmine2/src/{p_timeout.js => pTimeout.js} (100%) rename packages/jest-jasmine2/src/{queue_runner.js => queueRunner.js} (96%) rename packages/jest-jasmine2/src/{tree_processor.js => treeProcessor.js} (100%) diff --git a/packages/jest-jasmine2/src/expectation_failed.js b/packages/jest-jasmine2/src/ExpectationFailed.js similarity index 100% rename from packages/jest-jasmine2/src/expectation_failed.js rename to packages/jest-jasmine2/src/ExpectationFailed.js diff --git a/packages/jest-jasmine2/src/p_cancelable.js b/packages/jest-jasmine2/src/PCancelable.js similarity index 100% rename from packages/jest-jasmine2/src/p_cancelable.js rename to packages/jest-jasmine2/src/PCancelable.js diff --git a/packages/jest-jasmine2/src/__tests__/__snapshots__/expectation_result_factory.test.js.snap b/packages/jest-jasmine2/src/__tests__/__snapshots__/expectationResultFactory.test.js.snap similarity index 100% rename from packages/jest-jasmine2/src/__tests__/__snapshots__/expectation_result_factory.test.js.snap rename to packages/jest-jasmine2/src/__tests__/__snapshots__/expectationResultFactory.test.js.snap diff --git a/packages/jest-jasmine2/src/__tests__/expectation_result_factory.test.js b/packages/jest-jasmine2/src/__tests__/expectationResultFactory.test.js similarity index 96% rename from packages/jest-jasmine2/src/__tests__/expectation_result_factory.test.js rename to packages/jest-jasmine2/src/__tests__/expectationResultFactory.test.js index d036f36c0f06..06bb8c151935 100644 --- a/packages/jest-jasmine2/src/__tests__/expectation_result_factory.test.js +++ b/packages/jest-jasmine2/src/__tests__/expectationResultFactory.test.js @@ -8,7 +8,7 @@ 'use strict'; -import expectationResultFactory from '../expectation_result_factory'; +import expectationResultFactory from '../expectationResultFactory'; describe('expectationResultFactory', () => { it('returns the result if passed.', () => { diff --git a/packages/jest-jasmine2/src/__tests__/hooks_error.test.js b/packages/jest-jasmine2/src/__tests__/hooksError.test.js similarity index 100% rename from packages/jest-jasmine2/src/__tests__/hooks_error.test.js rename to packages/jest-jasmine2/src/__tests__/hooksError.test.js diff --git a/packages/jest-jasmine2/src/__tests__/it_test_error.test.js b/packages/jest-jasmine2/src/__tests__/itTestError.test.js similarity index 100% rename from packages/jest-jasmine2/src/__tests__/it_test_error.test.js rename to packages/jest-jasmine2/src/__tests__/itTestError.test.js diff --git a/packages/jest-jasmine2/src/__tests__/it_to_test_alias.test.js b/packages/jest-jasmine2/src/__tests__/itToTestAlias.test.js similarity index 100% rename from packages/jest-jasmine2/src/__tests__/it_to_test_alias.test.js rename to packages/jest-jasmine2/src/__tests__/itToTestAlias.test.js diff --git a/packages/jest-jasmine2/src/__tests__/p_timeout.test.js b/packages/jest-jasmine2/src/__tests__/pTimeout.test.js similarity index 97% rename from packages/jest-jasmine2/src/__tests__/p_timeout.test.js rename to packages/jest-jasmine2/src/__tests__/pTimeout.test.js index d0bccd1d237a..4daa94b78865 100644 --- a/packages/jest-jasmine2/src/__tests__/p_timeout.test.js +++ b/packages/jest-jasmine2/src/__tests__/pTimeout.test.js @@ -10,7 +10,7 @@ jest.useFakeTimers(); -import pTimeout from '../p_timeout'; +import pTimeout from '../pTimeout'; describe('pTimeout', () => { it('calls `clearTimeout` and resolves when `promise` resolves.', async () => { diff --git a/packages/jest-jasmine2/src/__tests__/queue_runner.test.js b/packages/jest-jasmine2/src/__tests__/queueRunner.test.js similarity index 98% rename from packages/jest-jasmine2/src/__tests__/queue_runner.test.js rename to packages/jest-jasmine2/src/__tests__/queueRunner.test.js index 516604a0156a..80c2b15ab202 100644 --- a/packages/jest-jasmine2/src/__tests__/queue_runner.test.js +++ b/packages/jest-jasmine2/src/__tests__/queueRunner.test.js @@ -8,7 +8,7 @@ 'use strict'; -import queueRunner from '../queue_runner'; +import queueRunner from '../queueRunner'; describe('queueRunner', () => { it('runs every function in the queue.', async () => { diff --git a/packages/jest-jasmine2/src/__tests__/todo_error.test.js b/packages/jest-jasmine2/src/__tests__/todoError.test.js similarity index 100% rename from packages/jest-jasmine2/src/__tests__/todo_error.test.js rename to packages/jest-jasmine2/src/__tests__/todoError.test.js diff --git a/packages/jest-jasmine2/src/assert_support.js b/packages/jest-jasmine2/src/assertionErrorMessage.js similarity index 100% rename from packages/jest-jasmine2/src/assert_support.js rename to packages/jest-jasmine2/src/assertionErrorMessage.js diff --git a/packages/jest-jasmine2/src/error_on_private.js b/packages/jest-jasmine2/src/errorOnPrivate.js similarity index 100% rename from packages/jest-jasmine2/src/error_on_private.js rename to packages/jest-jasmine2/src/errorOnPrivate.js diff --git a/packages/jest-jasmine2/src/expectation_result_factory.js b/packages/jest-jasmine2/src/expectationResultFactory.js similarity index 100% rename from packages/jest-jasmine2/src/expectation_result_factory.js rename to packages/jest-jasmine2/src/expectationResultFactory.js diff --git a/packages/jest-jasmine2/src/index.js b/packages/jest-jasmine2/src/index.js index b6fef61428b1..4ec456f130a5 100644 --- a/packages/jest-jasmine2/src/index.js +++ b/packages/jest-jasmine2/src/index.js @@ -16,12 +16,12 @@ import type Runtime from 'jest-runtime'; import path from 'path'; import installEach from './each'; -import {installErrorOnPrivate} from './error_on_private'; +import {installErrorOnPrivate} from './errorOnPrivate'; import {getCallsite} from 'jest-util'; import JasmineReporter from './reporter'; -import {install as jasmineAsyncInstall} from './jasmine_async'; +import jasmineAsyncInstall from './jasmineAsyncInstall'; -const JASMINE = require.resolve('./jasmine/jasmine_light.js'); +const JASMINE = require.resolve('./jasmine/jasmineLight.js'); async function jasmine2( globalConfig: GlobalConfig, @@ -117,7 +117,7 @@ async function jasmine2( env.addReporter(reporter); runtime - .requireInternalModule(path.resolve(__dirname, './jest_expect.js')) + .requireInternalModule(path.resolve(__dirname, './jestExpect.js')) .default({ expand: globalConfig.expand, }); diff --git a/packages/jest-jasmine2/src/is_error.js b/packages/jest-jasmine2/src/isError.js similarity index 100% rename from packages/jest-jasmine2/src/is_error.js rename to packages/jest-jasmine2/src/isError.js diff --git a/packages/jest-jasmine2/src/jasmine/call_tracker.js b/packages/jest-jasmine2/src/jasmine/CallTracker.js similarity index 100% rename from packages/jest-jasmine2/src/jasmine/call_tracker.js rename to packages/jest-jasmine2/src/jasmine/CallTracker.js diff --git a/packages/jest-jasmine2/src/jasmine/Env.js b/packages/jest-jasmine2/src/jasmine/Env.js index 21d27d753c23..c6556fec8a61 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.js +++ b/packages/jest-jasmine2/src/jasmine/Env.js @@ -31,10 +31,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* eslint-disable sort-keys */ import {AssertionError} from 'assert'; -import queueRunner from '../queue_runner'; -import treeProcessor from '../tree_processor'; -import checkIsError from '../is_error'; -import assertionErrorMessage from '../assert_support'; +import queueRunner from '../queueRunner'; +import treeProcessor from '../treeProcessor'; +import isError from '../isError'; +import assertionErrorMessage from '../assertionErrorMessage'; import {ErrorWithStack} from 'jest-util'; export default function(j$) { @@ -573,16 +573,16 @@ export default function(j$) { }; this.fail = function(error) { - let isError; + let checkIsError; let message; if (error instanceof AssertionError) { - isError = false; + checkIsError = false; message = assertionErrorMessage(error, {expand: j$.Spec.expand}); } else { - const check = checkIsError(error); + const check = isError(error); - isError = check.isError; + checkIsError = check.isError; message = check.message; } @@ -592,7 +592,7 @@ export default function(j$) { expected: '', actual: '', message, - error: isError ? error : new Error(message), + error: checkIsError ? error : new Error(message), }); }; } diff --git a/packages/jest-jasmine2/src/jasmine/js_api_reporter.js b/packages/jest-jasmine2/src/jasmine/JsApiReporter.js similarity index 100% rename from packages/jest-jasmine2/src/jasmine/js_api_reporter.js rename to packages/jest-jasmine2/src/jasmine/JsApiReporter.js diff --git a/packages/jest-jasmine2/src/jasmine/report_dispatcher.js b/packages/jest-jasmine2/src/jasmine/ReportDispatcher.js similarity index 100% rename from packages/jest-jasmine2/src/jasmine/report_dispatcher.js rename to packages/jest-jasmine2/src/jasmine/ReportDispatcher.js diff --git a/packages/jest-jasmine2/src/jasmine/Spec.js b/packages/jest-jasmine2/src/jasmine/Spec.js index c7ab00dfe70e..9f3bc12945ce 100644 --- a/packages/jest-jasmine2/src/jasmine/Spec.js +++ b/packages/jest-jasmine2/src/jasmine/Spec.js @@ -33,11 +33,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import {AssertionError} from 'assert'; -import ExpectationFailed from '../expectation_failed'; +import ExpectationFailed from '../ExpectationFailed'; -import expectationResultFactory from '../expectation_result_factory'; +import expectationResultFactory from '../expectationResultFactory'; -import assertionErrorMessage from '../assert_support'; +import assertionErrorMessage from '../assertionErrorMessage'; export default function Spec(attrs: Object) { this.resultCallback = attrs.resultCallback || function() {}; diff --git a/packages/jest-jasmine2/src/jasmine/spy_strategy.js b/packages/jest-jasmine2/src/jasmine/SpyStrategy.js similarity index 100% rename from packages/jest-jasmine2/src/jasmine/spy_strategy.js rename to packages/jest-jasmine2/src/jasmine/SpyStrategy.js diff --git a/packages/jest-jasmine2/src/jasmine/Suite.js b/packages/jest-jasmine2/src/jasmine/Suite.js index 307840c2dec6..90bd2a7cf21c 100644 --- a/packages/jest-jasmine2/src/jasmine/Suite.js +++ b/packages/jest-jasmine2/src/jasmine/Suite.js @@ -32,8 +32,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* eslint-disable sort-keys */ import {convertDescriptorToString} from 'jest-util'; -import ExpectationFailed from '../expectation_failed'; -import expectationResultFactory from '../expectation_result_factory'; +import ExpectationFailed from '../ExpectationFailed'; +import expectationResultFactory from '../expectationResultFactory'; export default function Suite(attrs: Object) { this.id = attrs.id; diff --git a/packages/jest-jasmine2/src/jasmine/create_spy.js b/packages/jest-jasmine2/src/jasmine/createSpy.js similarity index 96% rename from packages/jest-jasmine2/src/jasmine/create_spy.js rename to packages/jest-jasmine2/src/jasmine/createSpy.js index 7cd6325c3ead..ba05e617f86e 100644 --- a/packages/jest-jasmine2/src/jasmine/create_spy.js +++ b/packages/jest-jasmine2/src/jasmine/createSpy.js @@ -30,9 +30,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* eslint-disable sort-keys */ -import CallTracker from './call_tracker'; +import CallTracker from './CallTracker'; -import SpyStrategy from './spy_strategy'; +import SpyStrategy from './SpyStrategy'; function createSpy(name, originalFn) { const spyStrategy = new SpyStrategy({ diff --git a/packages/jest-jasmine2/src/jasmine/jasmine_light.js b/packages/jest-jasmine2/src/jasmine/jasmineLight.js similarity index 95% rename from packages/jest-jasmine2/src/jasmine/jasmine_light.js rename to packages/jest-jasmine2/src/jasmine/jasmineLight.js index f79918edcdeb..0d1b748bb3a3 100644 --- a/packages/jest-jasmine2/src/jasmine/jasmine_light.js +++ b/packages/jest-jasmine2/src/jasmine/jasmineLight.js @@ -33,12 +33,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import type {Jasmine} from 'types/Jasmine'; -import createSpy from './create_spy'; +import createSpy from './createSpy'; import Env from './Env'; -import JsApiReporter from './js_api_reporter'; -import ReportDispatcher from './report_dispatcher'; +import JsApiReporter from './JsApiReporter'; +import ReportDispatcher from './ReportDispatcher'; import Spec from './Spec'; -import SpyRegistry from './spy_registry'; +import SpyRegistry from './spyRegistry'; import Suite from './Suite'; import Timer from './Timer'; diff --git a/packages/jest-jasmine2/src/jasmine/spy_registry.js b/packages/jest-jasmine2/src/jasmine/spyRegistry.js similarity index 97% rename from packages/jest-jasmine2/src/jasmine/spy_registry.js rename to packages/jest-jasmine2/src/jasmine/spyRegistry.js index 4a619eaba36f..b5775a24f1db 100644 --- a/packages/jest-jasmine2/src/jasmine/spy_registry.js +++ b/packages/jest-jasmine2/src/jasmine/spyRegistry.js @@ -30,10 +30,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* @flow */ -import CallTracker from './call_tracker'; +import CallTracker from './CallTracker'; -import createSpy from './create_spy'; -import SpyStrategy from './spy_strategy'; +import createSpy from './createSpy'; +import SpyStrategy from './SpyStrategy'; const formatErrorMsg = (domain: string, usage?: string) => { const usageDefinition = usage ? '\nUsage: ' + usage : ''; diff --git a/packages/jest-jasmine2/src/jasmine_async.js b/packages/jest-jasmine2/src/jasmineAsyncInstall.js similarity index 93% rename from packages/jest-jasmine2/src/jasmine_async.js rename to packages/jest-jasmine2/src/jasmineAsyncInstall.js index a45e9ac21c15..90f5556d77ca 100644 --- a/packages/jest-jasmine2/src/jasmine_async.js +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.js @@ -16,7 +16,7 @@ import type {Global} from 'types/Global'; import isGeneratorFn from 'is-generator-fn'; import co from 'co'; -import checkIsError from './is_error'; +import isError from './isError'; function isPromise(obj) { return obj && typeof obj.then === 'function'; @@ -51,12 +51,12 @@ function promisifyLifeCycleFunction(originalFn, env) { if (isPromise(returnValue)) { returnValue.then(done.bind(null, null), error => { - const {isError, message} = checkIsError(error); + const {isError: checkIsError, message} = isError(error); if (message) { extraError.message = message; } - done.fail(isError ? error : extraError); + done.fail(checkIsError ? error : extraError); }); } else { done(); @@ -97,7 +97,7 @@ function promisifyIt(originalFn, env, jasmine) { if (isPromise(returnValue)) { returnValue.then(done.bind(null, null), error => { - const {isError, message} = checkIsError(error); + const {isError: checkIsError, message} = isError(error); if (message) { extraError.message = message; @@ -107,7 +107,7 @@ function promisifyIt(originalFn, env, jasmine) { env.pending(message); done(); } else { - done.fail(isError ? error : extraError); + done.fail(checkIsError ? error : extraError); } }); } else if (returnValue === undefined) { @@ -148,7 +148,7 @@ function makeConcurrent(originalFn: Function, env) { }; } -export function install(global: Global) { +export default function jasmineAsyncInstall(global: Global) { const jasmine = global.jasmine; const env = jasmine.getEnv(); diff --git a/packages/jest-jasmine2/src/jest_expect.js b/packages/jest-jasmine2/src/jestExpect.js similarity index 100% rename from packages/jest-jasmine2/src/jest_expect.js rename to packages/jest-jasmine2/src/jestExpect.js diff --git a/packages/jest-jasmine2/src/p_timeout.js b/packages/jest-jasmine2/src/pTimeout.js similarity index 100% rename from packages/jest-jasmine2/src/p_timeout.js rename to packages/jest-jasmine2/src/pTimeout.js diff --git a/packages/jest-jasmine2/src/queue_runner.js b/packages/jest-jasmine2/src/queueRunner.js similarity index 96% rename from packages/jest-jasmine2/src/queue_runner.js rename to packages/jest-jasmine2/src/queueRunner.js index 280a1ff73edd..de1aa47a7c95 100644 --- a/packages/jest-jasmine2/src/queue_runner.js +++ b/packages/jest-jasmine2/src/queueRunner.js @@ -7,8 +7,8 @@ * @flow */ -import PCancelable from './p_cancelable'; -import pTimeout from './p_timeout'; +import PCancelable from './PCancelable'; +import pTimeout from './pTimeout'; type Options = { clearTimeout: (timeoutID: number) => void, diff --git a/packages/jest-jasmine2/src/tree_processor.js b/packages/jest-jasmine2/src/treeProcessor.js similarity index 100% rename from packages/jest-jasmine2/src/tree_processor.js rename to packages/jest-jasmine2/src/treeProcessor.js From 5054cc1268977f69c435a20f09c5386c4cc95d1f Mon Sep 17 00:00:00 2001 From: Anenth Date: Tue, 30 Oct 2018 03:47:47 +0530 Subject: [PATCH 12/45] Standardize file names in packages/jest-validate (#7294) * Rename files to follow facebook's conventions * Rename files to follow facebook's conventions for test --- ...options.test.js.snap => validateCLIOptions.test.js.snap} | 0 .../__tests__/fixtures/{jest_config.js => jestConfig.js} | 0 packages/jest-validate/src/__tests__/validate.test.js | 6 +++--- ...idate_cli_options.test.js => validateCLIOptions.test.js} | 2 +- .../src/{default_config.js => defaultConfig.js} | 0 .../src/{example_config.js => exampleConfig.js} | 0 packages/jest-validate/src/index.js | 2 +- packages/jest-validate/src/validate.js | 2 +- .../src/{validate_cli_options.js => validateCLIOptions.js} | 2 +- 9 files changed, 7 insertions(+), 7 deletions(-) rename packages/jest-validate/src/__tests__/__snapshots__/{validate_cli_options.test.js.snap => validateCLIOptions.test.js.snap} (100%) rename packages/jest-validate/src/__tests__/fixtures/{jest_config.js => jestConfig.js} (100%) rename packages/jest-validate/src/__tests__/{validate_cli_options.test.js => validateCLIOptions.test.js} (94%) rename packages/jest-validate/src/{default_config.js => defaultConfig.js} (100%) rename packages/jest-validate/src/{example_config.js => exampleConfig.js} (100%) rename packages/jest-validate/src/{validate_cli_options.js => validateCLIOptions.js} (98%) diff --git a/packages/jest-validate/src/__tests__/__snapshots__/validate_cli_options.test.js.snap b/packages/jest-validate/src/__tests__/__snapshots__/validateCLIOptions.test.js.snap similarity index 100% rename from packages/jest-validate/src/__tests__/__snapshots__/validate_cli_options.test.js.snap rename to packages/jest-validate/src/__tests__/__snapshots__/validateCLIOptions.test.js.snap diff --git a/packages/jest-validate/src/__tests__/fixtures/jest_config.js b/packages/jest-validate/src/__tests__/fixtures/jestConfig.js similarity index 100% rename from packages/jest-validate/src/__tests__/fixtures/jest_config.js rename to packages/jest-validate/src/__tests__/fixtures/jestConfig.js diff --git a/packages/jest-validate/src/__tests__/validate.test.js b/packages/jest-validate/src/__tests__/validate.test.js index a03895a813c6..05c50e5ad886 100644 --- a/packages/jest-validate/src/__tests__/validate.test.js +++ b/packages/jest-validate/src/__tests__/validate.test.js @@ -10,14 +10,14 @@ import validate from '../validate'; import {multipleValidOptions} from '../condition'; -import jestValidateExampleConfig from '../example_config'; -import jestValidateDefaultConfig from '../default_config'; +import jestValidateExampleConfig from '../exampleConfig'; +import jestValidateDefaultConfig from '../defaultConfig'; const { defaultConfig, validConfig, deprecatedConfig, -} = require('./fixtures/jest_config'); +} = require('./fixtures/jestConfig'); test('recursively validates default Jest config', () => { expect( diff --git a/packages/jest-validate/src/__tests__/validate_cli_options.test.js b/packages/jest-validate/src/__tests__/validateCLIOptions.test.js similarity index 94% rename from packages/jest-validate/src/__tests__/validate_cli_options.test.js rename to packages/jest-validate/src/__tests__/validateCLIOptions.test.js index 44348836fc1e..fb4eba73321d 100644 --- a/packages/jest-validate/src/__tests__/validate_cli_options.test.js +++ b/packages/jest-validate/src/__tests__/validateCLIOptions.test.js @@ -8,7 +8,7 @@ 'use strict'; -import validateCLIOptions from '../validate_cli_options'; +import validateCLIOptions from '../validateCLIOptions'; test('validates yargs special options', () => { const options = ['$0', '_', 'help', 'h']; diff --git a/packages/jest-validate/src/default_config.js b/packages/jest-validate/src/defaultConfig.js similarity index 100% rename from packages/jest-validate/src/default_config.js rename to packages/jest-validate/src/defaultConfig.js diff --git a/packages/jest-validate/src/example_config.js b/packages/jest-validate/src/exampleConfig.js similarity index 100% rename from packages/jest-validate/src/example_config.js rename to packages/jest-validate/src/exampleConfig.js diff --git a/packages/jest-validate/src/index.js b/packages/jest-validate/src/index.js index 3a62ea7e5315..75806e93bb2a 100644 --- a/packages/jest-validate/src/index.js +++ b/packages/jest-validate/src/index.js @@ -14,7 +14,7 @@ import { ValidationError, } from './utils'; import validate from './validate'; -import validateCLIOptions from './validate_cli_options'; +import validateCLIOptions from './validateCLIOptions'; import {multipleValidOptions} from './condition'; module.exports = { diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index 96c54cdcf7a4..cf68a608cdd2 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -9,7 +9,7 @@ import type {ValidationOptions} from './types'; -import defaultConfig from './default_config'; +import defaultConfig from './defaultConfig'; let hasDeprecationWarnings = false; diff --git a/packages/jest-validate/src/validate_cli_options.js b/packages/jest-validate/src/validateCLIOptions.js similarity index 98% rename from packages/jest-validate/src/validate_cli_options.js rename to packages/jest-validate/src/validateCLIOptions.js index 28f3debff0bf..255093959030 100644 --- a/packages/jest-validate/src/validate_cli_options.js +++ b/packages/jest-validate/src/validateCLIOptions.js @@ -12,7 +12,7 @@ import type {Argv} from 'types/Argv'; import chalk from 'chalk'; import {createDidYouMeanMessage, format, ValidationError} from './utils'; import {deprecationWarning} from './deprecated'; -import defaultConfig from './default_config'; +import defaultConfig from './defaultConfig'; const BULLET: string = chalk.bold('\u25cf'); export const DOCUMENTATION_NOTE = ` ${chalk.bold('CLI Options Documentation:')} From b69780d17187e537b099fcefcab61eefeba5f1e6 Mon Sep 17 00:00:00 2001 From: Anenth Date: Tue, 30 Oct 2018 03:48:21 +0530 Subject: [PATCH 13/45] Standardize file names in packages/jest-util (#7293) * Rename files to follow facebook's conventions * Rename files to follow facebook's conventions for test --- ...buffered_console.js => BufferedConsole.js} | 2 +- .../src/{Console.js => CustomConsole.js} | 2 +- ...{error_with_stack.js => ErrorWithStack.js} | 0 .../src/{fake_timers.js => FakeTimers.js} | 2 +- .../src/{null_console.js => NullConsole.js} | 4 +-- ...s.test.js.snap => fakeTimers.test.js.snap} | 0 ...onsole.test.js => bufferedConsole.test.js} | 2 +- .../jest-util/src/__tests__/console.test.js | 2 +- ...ct.test.js => createProcessObject.test.js} | 2 +- ...ic_copy.test.js => deepCyclicCopy.test.js} | 2 +- ...h_stack.test.js => errorWithStack.test.js} | 2 +- ...fake_timers.test.js => fakeTimers.test.js} | 2 +- ...ults.test.js => formatTestResults.test.js} | 2 +- ...t_callsite.test.js => getCallsite.test.js} | 2 +- ...shot.test.js => getFailedSnapshot.test.js} | 2 +- ...s.test.js => installCommonGlobals.test.js} | 2 +- ...eractive.test.js => isInteractive.test.js} | 10 +++--- .../src/{clear_line.js => clearLine.js} | 0 ...string.js => convertDescriptorToString.js} | 0 ...ocess_object.js => createProcessObject.js} | 2 +- ...{deep_cyclic_copy.js => deepCyclicCopy.js} | 0 ...t_test_results.js => formatTestResults.js} | 0 .../src/{get_callsite.js => getCallsite.js} | 0 ..._console_output.js => getConsoleOutput.js} | 0 ...hot_tests.js => getFailedSnapshotTests.js} | 0 packages/jest-util/src/index.js | 32 +++++++++---------- ...mon_globals.js => installCommonGlobals.js} | 4 +-- .../{is_interative.js => isInteractive.js} | 0 .../src/{set_global.js => setGlobal.js} | 0 29 files changed, 39 insertions(+), 39 deletions(-) rename packages/jest-util/src/{buffered_console.js => BufferedConsole.js} (98%) rename packages/jest-util/src/{Console.js => CustomConsole.js} (98%) rename packages/jest-util/src/{error_with_stack.js => ErrorWithStack.js} (100%) rename packages/jest-util/src/{fake_timers.js => FakeTimers.js} (99%) rename packages/jest-util/src/{null_console.js => NullConsole.js} (77%) rename packages/jest-util/src/__tests__/__snapshots__/{fake_timers.test.js.snap => fakeTimers.test.js.snap} (100%) rename packages/jest-util/src/__tests__/{buffered_console.test.js => bufferedConsole.test.js} (98%) rename packages/jest-util/src/__tests__/{create_process_object.test.js => createProcessObject.test.js} (98%) rename packages/jest-util/src/__tests__/{deep_cyclic_copy.test.js => deepCyclicCopy.test.js} (99%) rename packages/jest-util/src/__tests__/{error_with_stack.test.js => errorWithStack.test.js} (93%) rename packages/jest-util/src/__tests__/{fake_timers.test.js => fakeTimers.test.js} (99%) rename packages/jest-util/src/__tests__/{format_test_results.test.js => formatTestResults.test.js} (93%) rename packages/jest-util/src/__tests__/{get_callsite.test.js => getCallsite.test.js} (97%) rename packages/jest-util/src/__tests__/{get_failed_snapshot.test.js => getFailedSnapshot.test.js} (95%) rename packages/jest-util/src/__tests__/{install_common_globals.test.js => installCommonGlobals.test.js} (93%) rename packages/jest-util/src/__tests__/{is_interactive.test.js => isInteractive.test.js} (84%) rename packages/jest-util/src/{clear_line.js => clearLine.js} (100%) rename packages/jest-util/src/{convert_descriptor_to_string.js => convertDescriptorToString.js} (100%) rename packages/jest-util/src/{create_process_object.js => createProcessObject.js} (98%) rename packages/jest-util/src/{deep_cyclic_copy.js => deepCyclicCopy.js} (100%) rename packages/jest-util/src/{format_test_results.js => formatTestResults.js} (100%) rename packages/jest-util/src/{get_callsite.js => getCallsite.js} (100%) rename packages/jest-util/src/{get_console_output.js => getConsoleOutput.js} (100%) rename packages/jest-util/src/{get_failed_snapshot_tests.js => getFailedSnapshotTests.js} (100%) rename packages/jest-util/src/{install_common_globals.js => installCommonGlobals.js} (91%) rename packages/jest-util/src/{is_interative.js => isInteractive.js} (100%) rename packages/jest-util/src/{set_global.js => setGlobal.js} (100%) diff --git a/packages/jest-util/src/buffered_console.js b/packages/jest-util/src/BufferedConsole.js similarity index 98% rename from packages/jest-util/src/buffered_console.js rename to packages/jest-util/src/BufferedConsole.js index 434d8d194927..7b3b2a4a7129 100644 --- a/packages/jest-util/src/buffered_console.js +++ b/packages/jest-util/src/BufferedConsole.js @@ -21,7 +21,7 @@ import assert from 'assert'; import {Console} from 'console'; import {format} from 'util'; import chalk from 'chalk'; -import getCallsite from './get_callsite'; +import getCallsite from './getCallsite'; export default class BufferedConsole extends Console { _buffer: ConsoleBuffer; diff --git a/packages/jest-util/src/Console.js b/packages/jest-util/src/CustomConsole.js similarity index 98% rename from packages/jest-util/src/Console.js rename to packages/jest-util/src/CustomConsole.js index 064d9842fc2c..92335c788e67 100644 --- a/packages/jest-util/src/Console.js +++ b/packages/jest-util/src/CustomConsole.js @@ -14,7 +14,7 @@ import assert from 'assert'; import {format} from 'util'; import {Console} from 'console'; import chalk from 'chalk'; -import clearLine from './clear_line'; +import clearLine from './clearLine'; type Formatter = (type: LogType, message: LogMessage) => string; diff --git a/packages/jest-util/src/error_with_stack.js b/packages/jest-util/src/ErrorWithStack.js similarity index 100% rename from packages/jest-util/src/error_with_stack.js rename to packages/jest-util/src/ErrorWithStack.js diff --git a/packages/jest-util/src/fake_timers.js b/packages/jest-util/src/FakeTimers.js similarity index 99% rename from packages/jest-util/src/fake_timers.js rename to packages/jest-util/src/FakeTimers.js index e1c64f6ce2c4..953820c9995e 100644 --- a/packages/jest-util/src/fake_timers.js +++ b/packages/jest-util/src/FakeTimers.js @@ -12,7 +12,7 @@ import type {Global} from 'types/Global'; import type {ModuleMocker} from 'types/Mock'; import {formatStackTrace} from 'jest-message-util'; -import setGlobal from './set_global'; +import setGlobal from './setGlobal'; /** * We don't know the type of arguments for a callback ahead of time which is why diff --git a/packages/jest-util/src/null_console.js b/packages/jest-util/src/NullConsole.js similarity index 77% rename from packages/jest-util/src/null_console.js rename to packages/jest-util/src/NullConsole.js index d89d6f70f685..bfc753f926cf 100644 --- a/packages/jest-util/src/null_console.js +++ b/packages/jest-util/src/NullConsole.js @@ -7,9 +7,9 @@ * @flow */ -import Console from './Console'; +import CustomConsole from './CustomConsole'; -export default class NullConsole extends Console { +export default class NullConsole extends CustomConsole { assert() {} debug() {} dir() {} diff --git a/packages/jest-util/src/__tests__/__snapshots__/fake_timers.test.js.snap b/packages/jest-util/src/__tests__/__snapshots__/fakeTimers.test.js.snap similarity index 100% rename from packages/jest-util/src/__tests__/__snapshots__/fake_timers.test.js.snap rename to packages/jest-util/src/__tests__/__snapshots__/fakeTimers.test.js.snap diff --git a/packages/jest-util/src/__tests__/buffered_console.test.js b/packages/jest-util/src/__tests__/bufferedConsole.test.js similarity index 98% rename from packages/jest-util/src/__tests__/buffered_console.test.js rename to packages/jest-util/src/__tests__/bufferedConsole.test.js index ede81e84c810..368c03e0b89e 100644 --- a/packages/jest-util/src/__tests__/buffered_console.test.js +++ b/packages/jest-util/src/__tests__/bufferedConsole.test.js @@ -8,7 +8,7 @@ */ import chalk from 'chalk'; -import BufferedConsole from '../buffered_console'; +import BufferedConsole from '../BufferedConsole'; describe('CustomConsole', () => { let _console; diff --git a/packages/jest-util/src/__tests__/console.test.js b/packages/jest-util/src/__tests__/console.test.js index 4502f8ac32f6..375160a4698b 100644 --- a/packages/jest-util/src/__tests__/console.test.js +++ b/packages/jest-util/src/__tests__/console.test.js @@ -8,7 +8,7 @@ */ import chalk from 'chalk'; -import CustomConsole from '../Console'; +import CustomConsole from '../CustomConsole'; describe('CustomConsole', () => { let _console; diff --git a/packages/jest-util/src/__tests__/create_process_object.test.js b/packages/jest-util/src/__tests__/createProcessObject.test.js similarity index 98% rename from packages/jest-util/src/__tests__/create_process_object.test.js rename to packages/jest-util/src/__tests__/createProcessObject.test.js index dafb1ef4578e..55f582c4b200 100644 --- a/packages/jest-util/src/__tests__/create_process_object.test.js +++ b/packages/jest-util/src/__tests__/createProcessObject.test.js @@ -6,7 +6,7 @@ */ import EventEmitter from 'events'; -import createProcessObject from '../create_process_object'; +import createProcessObject from '../createProcessObject'; it('creates a process object that looks like the original one', () => { const fakeProcess = createProcessObject(); diff --git a/packages/jest-util/src/__tests__/deep_cyclic_copy.test.js b/packages/jest-util/src/__tests__/deepCyclicCopy.test.js similarity index 99% rename from packages/jest-util/src/__tests__/deep_cyclic_copy.test.js rename to packages/jest-util/src/__tests__/deepCyclicCopy.test.js index 3f26bff2ebad..556c516a1743 100644 --- a/packages/jest-util/src/__tests__/deep_cyclic_copy.test.js +++ b/packages/jest-util/src/__tests__/deepCyclicCopy.test.js @@ -6,7 +6,7 @@ * */ -import deepCyclicCopy from '../deep_cyclic_copy'; +import deepCyclicCopy from '../deepCyclicCopy'; it('returns the same value for primitive or function values', () => { const fn = () => {}; diff --git a/packages/jest-util/src/__tests__/error_with_stack.test.js b/packages/jest-util/src/__tests__/errorWithStack.test.js similarity index 93% rename from packages/jest-util/src/__tests__/error_with_stack.test.js rename to packages/jest-util/src/__tests__/errorWithStack.test.js index 98c35c57c6b9..6de67fe8489f 100644 --- a/packages/jest-util/src/__tests__/error_with_stack.test.js +++ b/packages/jest-util/src/__tests__/errorWithStack.test.js @@ -7,7 +7,7 @@ * @flow */ -import ErrorWithStack from '../error_with_stack'; +import ErrorWithStack from '../ErrorWithStack'; describe('ErrorWithStack', () => { const message = '💩 something went wrong'; diff --git a/packages/jest-util/src/__tests__/fake_timers.test.js b/packages/jest-util/src/__tests__/fakeTimers.test.js similarity index 99% rename from packages/jest-util/src/__tests__/fake_timers.test.js rename to packages/jest-util/src/__tests__/fakeTimers.test.js index c214f0312591..8a05fde1dee0 100644 --- a/packages/jest-util/src/__tests__/fake_timers.test.js +++ b/packages/jest-util/src/__tests__/fakeTimers.test.js @@ -14,7 +14,7 @@ describe('FakeTimers', () => { let FakeTimers, moduleMocker, timerConfig; beforeEach(() => { - FakeTimers = require('../fake_timers').default; + FakeTimers = require('../FakeTimers').default; const mock = require('jest-mock'); const global = vm.runInNewContext('this'); moduleMocker = new mock.ModuleMocker(global); diff --git a/packages/jest-util/src/__tests__/format_test_results.test.js b/packages/jest-util/src/__tests__/formatTestResults.test.js similarity index 93% rename from packages/jest-util/src/__tests__/format_test_results.test.js rename to packages/jest-util/src/__tests__/formatTestResults.test.js index f2187c9fbb8c..6d03ccee06fe 100644 --- a/packages/jest-util/src/__tests__/format_test_results.test.js +++ b/packages/jest-util/src/__tests__/formatTestResults.test.js @@ -8,7 +8,7 @@ 'use strict'; -import formatTestResults from '../format_test_results'; +import formatTestResults from '../formatTestResults'; describe('formatTestResults', () => { const assertion = { diff --git a/packages/jest-util/src/__tests__/get_callsite.test.js b/packages/jest-util/src/__tests__/getCallsite.test.js similarity index 97% rename from packages/jest-util/src/__tests__/get_callsite.test.js rename to packages/jest-util/src/__tests__/getCallsite.test.js index 98598f049f87..f615ddcd083b 100644 --- a/packages/jest-util/src/__tests__/get_callsite.test.js +++ b/packages/jest-util/src/__tests__/getCallsite.test.js @@ -2,7 +2,7 @@ import fs from 'fs'; import SourceMap from 'source-map'; -import getCallsite from '../get_callsite'; +import getCallsite from '../getCallsite'; // Node 10.5.x compatibility jest.mock('fs', () => diff --git a/packages/jest-util/src/__tests__/get_failed_snapshot.test.js b/packages/jest-util/src/__tests__/getFailedSnapshot.test.js similarity index 95% rename from packages/jest-util/src/__tests__/get_failed_snapshot.test.js rename to packages/jest-util/src/__tests__/getFailedSnapshot.test.js index ca9992978bb3..e2d26e30a304 100644 --- a/packages/jest-util/src/__tests__/get_failed_snapshot.test.js +++ b/packages/jest-util/src/__tests__/getFailedSnapshot.test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import getFailedSnapshotTests from '../get_failed_snapshot_tests'; +import getFailedSnapshotTests from '../getFailedSnapshotTests'; test('return a list of path', () => { const targetFilename = 'somewhere.js'; diff --git a/packages/jest-util/src/__tests__/install_common_globals.test.js b/packages/jest-util/src/__tests__/installCommonGlobals.test.js similarity index 93% rename from packages/jest-util/src/__tests__/install_common_globals.test.js rename to packages/jest-util/src/__tests__/installCommonGlobals.test.js index b606ee81cc85..0aa0d42e454b 100644 --- a/packages/jest-util/src/__tests__/install_common_globals.test.js +++ b/packages/jest-util/src/__tests__/installCommonGlobals.test.js @@ -18,7 +18,7 @@ beforeEach(() => { fake = jest.fn(); global.DTRACE_NET_SERVER_CONNECTION = fake; - installCommonGlobals = require('../install_common_globals').default; + installCommonGlobals = require('../installCommonGlobals').default; }); it('returns the passed object', () => { diff --git a/packages/jest-util/src/__tests__/is_interactive.test.js b/packages/jest-util/src/__tests__/isInteractive.test.js similarity index 84% rename from packages/jest-util/src/__tests__/is_interactive.test.js rename to packages/jest-util/src/__tests__/isInteractive.test.js index d4b7efae05b2..5df194f2411a 100644 --- a/packages/jest-util/src/__tests__/is_interactive.test.js +++ b/packages/jest-util/src/__tests__/isInteractive.test.js @@ -19,7 +19,7 @@ it('Returns true when running on interactive environment', () => { process.stdout.isTTY = true; process.env.TERM = 'xterm-256color'; - const isInteractive = require('../is_interative').default; + const isInteractive = require('../isInteractive').default; expect(isInteractive).toBe(true); }); @@ -31,7 +31,7 @@ it('Returns false when running on a non-interactive environment', () => { jest.doMock('is-ci', () => true); process.stdout.isTTY = false; process.env.TERM = 'xterm-256color'; - isInteractive = require('../is_interative').default; + isInteractive = require('../isInteractive').default; expect(isInteractive).toBe(expectedResult); // Test with is-ci being false and isTTY false @@ -39,7 +39,7 @@ it('Returns false when running on a non-interactive environment', () => { jest.doMock('is-ci', () => false); process.stdout.isTTY = false; process.env.TERM = 'xterm-256color'; - isInteractive = require('../is_interative').default; + isInteractive = require('../isInteractive').default; expect(isInteractive).toBe(expectedResult); // Test with is-ci being true and isTTY true @@ -47,7 +47,7 @@ it('Returns false when running on a non-interactive environment', () => { jest.doMock('is-ci', () => true); process.stdout.isTTY = true; process.env.TERM = 'xterm-256color'; - isInteractive = require('../is_interative').default; + isInteractive = require('../isInteractive').default; expect(isInteractive).toBe(expectedResult); // Test with dumb terminal @@ -55,6 +55,6 @@ it('Returns false when running on a non-interactive environment', () => { jest.doMock('is-ci', () => false); process.stdout.isTTY = false; process.env.TERM = 'dumb'; - isInteractive = require('../is_interative').default; + isInteractive = require('../isInteractive').default; expect(isInteractive).toBe(expectedResult); }); diff --git a/packages/jest-util/src/clear_line.js b/packages/jest-util/src/clearLine.js similarity index 100% rename from packages/jest-util/src/clear_line.js rename to packages/jest-util/src/clearLine.js diff --git a/packages/jest-util/src/convert_descriptor_to_string.js b/packages/jest-util/src/convertDescriptorToString.js similarity index 100% rename from packages/jest-util/src/convert_descriptor_to_string.js rename to packages/jest-util/src/convertDescriptorToString.js diff --git a/packages/jest-util/src/create_process_object.js b/packages/jest-util/src/createProcessObject.js similarity index 98% rename from packages/jest-util/src/create_process_object.js rename to packages/jest-util/src/createProcessObject.js index 426b0dfcfd61..02619dcf4439 100644 --- a/packages/jest-util/src/create_process_object.js +++ b/packages/jest-util/src/createProcessObject.js @@ -7,7 +7,7 @@ * @flow */ -import deepCyclicCopy from './deep_cyclic_copy'; +import deepCyclicCopy from './deepCyclicCopy'; const BLACKLIST = new Set(['env', 'mainModule', '_events']); diff --git a/packages/jest-util/src/deep_cyclic_copy.js b/packages/jest-util/src/deepCyclicCopy.js similarity index 100% rename from packages/jest-util/src/deep_cyclic_copy.js rename to packages/jest-util/src/deepCyclicCopy.js diff --git a/packages/jest-util/src/format_test_results.js b/packages/jest-util/src/formatTestResults.js similarity index 100% rename from packages/jest-util/src/format_test_results.js rename to packages/jest-util/src/formatTestResults.js diff --git a/packages/jest-util/src/get_callsite.js b/packages/jest-util/src/getCallsite.js similarity index 100% rename from packages/jest-util/src/get_callsite.js rename to packages/jest-util/src/getCallsite.js diff --git a/packages/jest-util/src/get_console_output.js b/packages/jest-util/src/getConsoleOutput.js similarity index 100% rename from packages/jest-util/src/get_console_output.js rename to packages/jest-util/src/getConsoleOutput.js diff --git a/packages/jest-util/src/get_failed_snapshot_tests.js b/packages/jest-util/src/getFailedSnapshotTests.js similarity index 100% rename from packages/jest-util/src/get_failed_snapshot_tests.js rename to packages/jest-util/src/getFailedSnapshotTests.js diff --git a/packages/jest-util/src/index.js b/packages/jest-util/src/index.js index 0d206057f5a5..5cd88557a8ff 100644 --- a/packages/jest-util/src/index.js +++ b/packages/jest-util/src/index.js @@ -9,21 +9,21 @@ import mkdirp from 'mkdirp'; -import BufferedConsole from './buffered_console'; -import clearLine from './clear_line'; -import Console from './Console'; -import ErrorWithStack from './error_with_stack'; -import FakeTimers from './fake_timers'; -import formatTestResults from './format_test_results'; -import getFailedSnapshotTests from './get_failed_snapshot_tests'; -import getConsoleOutput from './get_console_output'; -import installCommonGlobals from './install_common_globals'; -import NullConsole from './null_console'; -import isInteractive from './is_interative'; -import getCallsite from './get_callsite'; -import setGlobal from './set_global'; -import deepCyclicCopy from './deep_cyclic_copy'; -import convertDescriptorToString from './convert_descriptor_to_string'; +import BufferedConsole from './BufferedConsole'; +import clearLine from './clearLine'; +import CustomConsole from './CustomConsole'; +import ErrorWithStack from './ErrorWithStack'; +import FakeTimers from './FakeTimers'; +import formatTestResults from './formatTestResults'; +import getFailedSnapshotTests from './getFailedSnapshotTests'; +import getConsoleOutput from './getConsoleOutput'; +import installCommonGlobals from './installCommonGlobals'; +import NullConsole from './NullConsole'; +import isInteractive from './isInteractive'; +import getCallsite from './getCallsite'; +import setGlobal from './setGlobal'; +import deepCyclicCopy from './deepCyclicCopy'; +import convertDescriptorToString from './convertDescriptorToString'; const createDirectory = (path: string) => { try { @@ -37,7 +37,7 @@ const createDirectory = (path: string) => { module.exports = { BufferedConsole, - Console, + Console: CustomConsole, ErrorWithStack, FakeTimers, NullConsole, diff --git a/packages/jest-util/src/install_common_globals.js b/packages/jest-util/src/installCommonGlobals.js similarity index 91% rename from packages/jest-util/src/install_common_globals.js rename to packages/jest-util/src/installCommonGlobals.js index d87e16a28861..571972449af7 100644 --- a/packages/jest-util/src/install_common_globals.js +++ b/packages/jest-util/src/installCommonGlobals.js @@ -10,8 +10,8 @@ import type {ConfigGlobals} from 'types/Config'; import type {Global} from 'types/Global'; -import createProcessObject from './create_process_object'; -import deepCyclicCopy from './deep_cyclic_copy'; +import createProcessObject from './createProcessObject'; +import deepCyclicCopy from './deepCyclicCopy'; const DTRACE = Object.keys(global).filter(key => key.startsWith('DTRACE')); diff --git a/packages/jest-util/src/is_interative.js b/packages/jest-util/src/isInteractive.js similarity index 100% rename from packages/jest-util/src/is_interative.js rename to packages/jest-util/src/isInteractive.js diff --git a/packages/jest-util/src/set_global.js b/packages/jest-util/src/setGlobal.js similarity index 100% rename from packages/jest-util/src/set_global.js rename to packages/jest-util/src/setGlobal.js From 682afa9875029c7faa0c27b59e8905d7780fc500 Mon Sep 17 00:00:00 2001 From: Anenth Date: Tue, 30 Oct 2018 03:48:47 +0530 Subject: [PATCH 14/45] Standardize file names in packages/jest-resolve (#7292) * Rename files to follow facebook's conventions * Rename files to follow facebook's conventions for test * Remove .js * Fix file path --- e2e/custom-resolver/resolver.js | 2 +- .../{is_builtin_module.test.js => isBuiltinModule.test.js} | 2 +- packages/jest-resolve/src/__tests__/resolve.test.js | 2 +- .../src/{default_resolver.js => defaultResolver.js} | 4 ++-- packages/jest-resolve/src/index.js | 6 +++--- .../src/{is_builtin_module.js => isBuiltinModule.js} | 0 .../src/{node_modules_paths.js => nodeModulesPaths.js} | 0 packages/jest-runtime/src/__tests__/defaultResolver.js | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) rename packages/jest-resolve/src/__tests__/{is_builtin_module.test.js => isBuiltinModule.test.js} (92%) rename packages/jest-resolve/src/{default_resolver.js => defaultResolver.js} (97%) rename packages/jest-resolve/src/{is_builtin_module.js => isBuiltinModule.js} (100%) rename packages/jest-resolve/src/{node_modules_paths.js => nodeModulesPaths.js} (100%) diff --git a/e2e/custom-resolver/resolver.js b/e2e/custom-resolver/resolver.js index 7385bfdd28c4..e9a718b139b5 100644 --- a/e2e/custom-resolver/resolver.js +++ b/e2e/custom-resolver/resolver.js @@ -2,7 +2,7 @@ const { default: defaultResolver, -} = require('jest-resolve/build/default_resolver'); +} = require('jest-resolve/build/defaultResolver'); const exportedModules = new Map([ ['foo', 'foo'], diff --git a/packages/jest-resolve/src/__tests__/is_builtin_module.test.js b/packages/jest-resolve/src/__tests__/isBuiltinModule.test.js similarity index 92% rename from packages/jest-resolve/src/__tests__/is_builtin_module.test.js rename to packages/jest-resolve/src/__tests__/isBuiltinModule.test.js index 7be6a38dcae6..a18f8b4a0b0d 100644 --- a/packages/jest-resolve/src/__tests__/is_builtin_module.test.js +++ b/packages/jest-resolve/src/__tests__/isBuiltinModule.test.js @@ -1,7 +1,7 @@ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // @flow -import isBuiltinModule from '../is_builtin_module'; +import isBuiltinModule from '../isBuiltinModule'; describe('isBuiltinModule', () => { it('should return true for the `path` module', () => { diff --git a/packages/jest-resolve/src/__tests__/resolve.test.js b/packages/jest-resolve/src/__tests__/resolve.test.js index 7d17eebac935..f4c75c4e6927 100644 --- a/packages/jest-resolve/src/__tests__/resolve.test.js +++ b/packages/jest-resolve/src/__tests__/resolve.test.js @@ -15,7 +15,7 @@ const path = require('path'); const ModuleMap = require('jest-haste-map').ModuleMap; const Resolver = require('../'); const userResolver = require('../__mocks__/userResolver'); -const nodeModulesPaths = require('../node_modules_paths').default; +const nodeModulesPaths = require('../nodeModulesPaths').default; beforeEach(() => { userResolver.mockClear(); diff --git a/packages/jest-resolve/src/default_resolver.js b/packages/jest-resolve/src/defaultResolver.js similarity index 97% rename from packages/jest-resolve/src/default_resolver.js rename to packages/jest-resolve/src/defaultResolver.js index ae85c4e888d8..02f311c22ece 100644 --- a/packages/jest-resolve/src/default_resolver.js +++ b/packages/jest-resolve/src/defaultResolver.js @@ -13,8 +13,8 @@ import type {ErrorWithCode} from 'types/Errors'; import browserResolve from 'browser-resolve'; import fs from 'fs'; import path from 'path'; -import isBuiltinModule from './is_builtin_module'; -import nodeModulesPaths from './node_modules_paths'; +import isBuiltinModule from './isBuiltinModule'; +import nodeModulesPaths from './nodeModulesPaths'; type ResolverOptions = {| basedir: Path, diff --git a/packages/jest-resolve/src/index.js b/packages/jest-resolve/src/index.js index 4d3c042d7117..7ad9ea1e960d 100644 --- a/packages/jest-resolve/src/index.js +++ b/packages/jest-resolve/src/index.js @@ -14,9 +14,9 @@ import type {ErrorWithCode} from 'types/Errors'; import fs from 'fs'; import path from 'path'; -import nodeModulesPaths from './node_modules_paths'; -import isBuiltinModule from './is_builtin_module'; -import defaultResolver from './default_resolver.js'; +import nodeModulesPaths from './nodeModulesPaths'; +import isBuiltinModule from './isBuiltinModule'; +import defaultResolver from './defaultResolver'; import chalk from 'chalk'; type ResolverConfig = {| diff --git a/packages/jest-resolve/src/is_builtin_module.js b/packages/jest-resolve/src/isBuiltinModule.js similarity index 100% rename from packages/jest-resolve/src/is_builtin_module.js rename to packages/jest-resolve/src/isBuiltinModule.js diff --git a/packages/jest-resolve/src/node_modules_paths.js b/packages/jest-resolve/src/nodeModulesPaths.js similarity index 100% rename from packages/jest-resolve/src/node_modules_paths.js rename to packages/jest-resolve/src/nodeModulesPaths.js diff --git a/packages/jest-runtime/src/__tests__/defaultResolver.js b/packages/jest-runtime/src/__tests__/defaultResolver.js index 089aa58e6055..adb6f54aa902 100644 --- a/packages/jest-runtime/src/__tests__/defaultResolver.js +++ b/packages/jest-runtime/src/__tests__/defaultResolver.js @@ -6,5 +6,5 @@ * of patent rights can be found in the PATENTS file in the same directory. * */ -import resolver from 'jest-resolve/build/default_resolver.js'; +import resolver from 'jest-resolve/build/defaultResolver.js'; module.exports = resolver; From 714cb516944c74a9ed9d6eda867911b398003468 Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Tue, 30 Oct 2018 06:23:12 +0800 Subject: [PATCH 15/45] Update toStrictEqual failure message (#7224) ## Summary This pull request updates the failure message returned by toStrictEqual so that it is more inline with what #7105 envisions. ## Test plan The matcher is tested with a snapshot test. Here are a few screenshots of the before and after along with the test file. Before: (I had to minimize the image to fit both tests in one screen) ![image](https://user-images.githubusercontent.com/18214059/47253151-16505300-d482-11e8-9596-a5a37c238d4b.png) After: ![image](https://user-images.githubusercontent.com/18214059/47253131-e012d380-d481-11e8-9211-be3417ec0cd7.png) --- CHANGELOG.md | 1 + .../__snapshots__/matchers.test.js.snap | 24 +++++++++++++++++++ .../expect/src/__tests__/matchers.test.js | 14 +++++++++++ packages/expect/src/matchers.js | 21 ++++++---------- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 986b2950b6dd..51eea6cb9c45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ - `[babel-jest]` Cache includes babel environment variables ([#7239](https://github.com/facebook/jest/pull/7239)) - `[jest-config]` Use strings instead of `RegExp` instances in normalized configuration ([#7251](https://github.com/facebook/jest/pull/7251)) - `[jest-circus]` Make sure to display real duration even if time is mocked ([#7264](https://github.com/facebook/jest/pull/7264)) +- `[expect]` Improves the failing message for `toStrictEqual` matcher. ([#7224](https://github.com/facebook/jest/pull/7224)) ### Chore & Maintenance diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index 400e8b6e424d..5a3e468bb84b 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -3479,6 +3479,30 @@ Received: \\"bar\\"" `; +exports[`.toStrictEqual() matches the expected snapshot when it fails 1`] = ` +"expect(received).toStrictEqual(expected) + +Difference: + +- Expected ++ Received + + Object { +- \\"test\\": TestClassA { +- \\"a\\": 1, +- \\"b\\": 2, +- }, ++ \\"test\\": 2, + }" +`; + +exports[`.toStrictEqual() matches the expected snapshot when it fails 2`] = ` +"expect(received).not.toStrictEqual(expected) + +Expected: {\\"test\\": {\\"a\\": 1, \\"b\\": 2}} +Received: {\\"test\\": {\\"a\\": 1, \\"b\\": 2}}" +`; + exports[`toMatchObject() {pass: false} expect([0]).toMatchObject([-0]) 1`] = ` "expect(received).toMatchObject(expected) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index e695eec418ed..344e451b55e4 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -244,6 +244,20 @@ describe('.toStrictEqual()', () => { }).toStrictEqual({test: new TestClassA(1, 2)}); }); + it('matches the expected snapshot when it fails', () => { + expect(() => + jestExpect({ + test: 2, + }).toStrictEqual({test: new TestClassA(1, 2)}), + ).toThrowErrorMatchingSnapshot(); + + expect(() => + jestExpect({ + test: new TestClassA(1, 2), + }).not.toStrictEqual({test: new TestClassA(1, 2)}), + ).toThrowErrorMatchingSnapshot(); + }); + it('does not pass for different types', () => { expect({ test: new TestClassA(1, 2), diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 215114de52d5..043032bc0803 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -628,27 +628,20 @@ const matchers: MatchersObject = { true, ); + const hint = matcherHint('.toStrictEqual', undefined, undefined, { + isNot: this.isNot, + }); const message = pass ? () => - matcherHint('.not.toStrictEqual') + + hint + '\n\n' + - `Expected value to not equal:\n` + - ` ${printExpected(expected)}\n` + - `Received:\n` + - ` ${printReceived(received)}` + `Expected: ${printExpected(expected)}\n` + + `Received: ${printReceived(received)}` : () => { const diffString = diff(expected, received, { expand: this.expand, }); - return ( - matcherHint('.toStrictEqual') + - '\n\n' + - `Expected value to equal:\n` + - ` ${printExpected(expected)}\n` + - `Received:\n` + - ` ${printReceived(received)}` + - (diffString ? `\n\nDifference:\n\n${diffString}` : '') - ); + return hint + (diffString ? `\n\nDifference:\n\n${diffString}` : ''); }; // Passing the the actual and expected objects so that a custom reporter From 5cdfc22af486e8ef8fcf9ce1c5464c998d33d5c7 Mon Sep 17 00:00:00 2001 From: Jess Sze Date: Tue, 30 Oct 2018 15:39:49 +0800 Subject: [PATCH 16/45] Remove duplicate doc entry (#7297) --- CHANGELOG.md | 1 + docs/MockFunctions.md | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51eea6cb9c45..37eae7df2063 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,7 @@ - `[*]` [**BREAKING**] Require Node.js 6+ for all packages ([#7258](https://github.com/facebook/jest/pull/7258)) - `[docs]` Add correct default value for `testUrl` config option ([#7277](https://github.com/facebook/jest/pull/7277)) - `[jest-util]` [**BREAKING**] Remove long-deprecated globals for fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) +- `[docs]` Remove duplicate code in `MockFunctions` ([#7297](https://github.com/facebook/jest/pull/7297)) ### Performance diff --git a/docs/MockFunctions.md b/docs/MockFunctions.md index eb96d94ca990..dfc33a7af6f3 100644 --- a/docs/MockFunctions.md +++ b/docs/MockFunctions.md @@ -160,9 +160,6 @@ Still, there are cases where it's useful to go beyond the ability to specify ret ```javascript const myMockFn = jest.fn(cb => cb(null, true)); -myMockFn((err, val) => console.log(val)); -// > true - myMockFn((err, val) => console.log(val)); // > true ``` From 51e68e7df4d673a49a50a794ebd2c45c8294a46a Mon Sep 17 00:00:00 2001 From: Matt Phillips Date: Tue, 30 Oct 2018 08:58:06 +0000 Subject: [PATCH 17/45] [jest-each]: Add empty string/array validation check (#7249) * Add empty array check to jest-each * Add changelog entry * Add empty string check to jest-each * Fix types in error messages * Add tagged template literal with no data validation check --- CHANGELOG.md | 1 + .../__snapshots__/array.test.js.snap | 56 +++++++++++-- .../__snapshots__/template.test.js.snap | 80 +++++++++++++++++++ .../jest-each/src/__tests__/array.test.js | 13 +++ .../jest-each/src/__tests__/template.test.js | 32 ++++++++ packages/jest-each/src/bind.js | 36 ++++++++- 6 files changed, 209 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37eae7df2063..7793451b3ace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### Fixes +- `[jest-each]` Add empty array validation check ([#7249](https://github.com/facebook/jest/pull/7249)) - `[jest-cli]` Interrupt tests if interactive watch plugin key is pressed ([#7222](https://github.com/facebook/jest/pull/7222)) - `[jest-cli]` Fix coverage summary reporting ([#7058](https://github.com/facebook/jest/pull/7058)) - `[jest-each]` Add each array validation check ([#7033](https://github.com/facebook/jest/pull/7033)) diff --git a/packages/jest-each/src/__tests__/__snapshots__/array.test.js.snap b/packages/jest-each/src/__tests__/__snapshots__/array.test.js.snap index 75cc81d64769..d779a5e5df50 100644 --- a/packages/jest-each/src/__tests__/__snapshots__/array.test.js.snap +++ b/packages/jest-each/src/__tests__/__snapshots__/array.test.js.snap @@ -1,56 +1,96 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`jest-each .describe throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .describe throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .describe.only throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .describe.only throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .fdescribe throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .fdescribe throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .fit throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .fit throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .it throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .it throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .it.only throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .it.only throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .test throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .test throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " `; +exports[`jest-each .test.only throws an error when called with an empty array 1`] = ` +"Error: \`.each\` called with an empty Array of table data. +" +`; + exports[`jest-each .test.only throws an error when not called with an array 1`] = ` -"\`.each\` must be called with an Array or Tagged Template String. +"\`.each\` must be called with an Array or Tagged Template Literal. Instead was called with: undefined " diff --git a/packages/jest-each/src/__tests__/__snapshots__/template.test.js.snap b/packages/jest-each/src/__tests__/__snapshots__/template.test.js.snap index f99bb2662c27..f5097aa6218d 100644 --- a/packages/jest-each/src/__tests__/__snapshots__/template.test.js.snap +++ b/packages/jest-each/src/__tests__/__snapshots__/template.test.js.snap @@ -1,5 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`jest-each .describe throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .describe throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -29,6 +34,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .describe throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .describe.only throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .describe.only throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -58,6 +73,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .describe.only throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .fdescribe throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .fdescribe throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -87,6 +112,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .fdescribe throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .fit throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .fit throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -116,6 +151,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .fit throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .it throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .it throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -145,6 +190,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .it throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .it.only throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .it.only throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -174,6 +229,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .it.only throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .test throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .test throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -203,6 +268,16 @@ Received: Missing 2 arguments" `; +exports[`jest-each .test throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; + +exports[`jest-each .test.only throws an error when called with an empty string 1`] = ` +"Error: \`.each\` called with an empty Tagged Template Literal of table data. +" +`; + exports[`jest-each .test.only throws error when there are fewer arguments than headings over multiple rows 1`] = ` "Not enough arguments supplied for given headings: a | b | expected @@ -231,3 +306,8 @@ Received: Missing 2 arguments" `; + +exports[`jest-each .test.only throws error when there are no arguments for given headings 1`] = ` +"Error: \`.each\` called with a Tagged Template Literal with no data, remember to interpolate with \${expression} syntax. +" +`; diff --git a/packages/jest-each/src/__tests__/array.test.js b/packages/jest-each/src/__tests__/array.test.js index 594b25ef0161..95268afa597d 100644 --- a/packages/jest-each/src/__tests__/array.test.js +++ b/packages/jest-each/src/__tests__/array.test.js @@ -60,6 +60,19 @@ describe('jest-each', () => { ).toThrowErrorMatchingSnapshot(); }); + test('throws an error when called with an empty array', () => { + const globalTestMocks = getGlobalTestMocks(); + const eachObject = each.withGlobal(globalTestMocks)([]); + const testFunction = get(eachObject, keyPath); + + testFunction('expected string', noop); + const globalMock = get(globalTestMocks, keyPath); + + expect(() => + globalMock.mock.calls[0][1](), + ).toThrowErrorMatchingSnapshot(); + }); + test('calls global with given title', () => { const globalTestMocks = getGlobalTestMocks(); const eachObject = each.withGlobal(globalTestMocks)([[]]); diff --git a/packages/jest-each/src/__tests__/template.test.js b/packages/jest-each/src/__tests__/template.test.js index 30f368ef54ce..ed5f9664d2eb 100644 --- a/packages/jest-each/src/__tests__/template.test.js +++ b/packages/jest-each/src/__tests__/template.test.js @@ -46,6 +46,23 @@ describe('jest-each', () => { ['describe', 'only'], ].forEach(keyPath => { describe(`.${keyPath.join('.')}`, () => { + test('throws error when there are no arguments for given headings', () => { + const globalTestMocks = getGlobalTestMocks(); + const eachObject = each.withGlobal(globalTestMocks)` + a | b | expected + `; + const testFunction = get(eachObject, keyPath); + const testCallBack = jest.fn(); + testFunction('this will blow up :(', testCallBack); + + const globalMock = get(globalTestMocks, keyPath); + + expect(() => + globalMock.mock.calls[0][1](), + ).toThrowErrorMatchingSnapshot(); + expect(testCallBack).not.toHaveBeenCalled(); + }); + test('throws error when there are fewer arguments than headings when given one row', () => { const globalTestMocks = getGlobalTestMocks(); const eachObject = each.withGlobal(globalTestMocks)` @@ -83,6 +100,21 @@ describe('jest-each', () => { expect(testCallBack).not.toHaveBeenCalled(); }); + test('throws an error when called with an empty string', () => { + const globalTestMocks = getGlobalTestMocks(); + const eachObject = each.withGlobal(globalTestMocks)` `; + const testFunction = get(eachObject, keyPath); + const testCallBack = jest.fn(); + testFunction('this will blow up :(', testCallBack); + + const globalMock = get(globalTestMocks, keyPath); + + expect(() => + globalMock.mock.calls[0][1](), + ).toThrowErrorMatchingSnapshot(); + expect(testCallBack).not.toHaveBeenCalled(); + }); + test('calls global with given title', () => { const globalTestMocks = getGlobalTestMocks(); const eachObject = each.withGlobal(globalTestMocks)` diff --git a/packages/jest-each/src/bind.js b/packages/jest-each/src/bind.js index 9d78fc25dc81..d2a7d1ebd550 100644 --- a/packages/jest-each/src/bind.js +++ b/packages/jest-each/src/bind.js @@ -31,7 +31,7 @@ export default (cb: Function, supportsDone: boolean = true) => (...args: any) => if (!Array.isArray(tableArg)) { const error = new ErrorWithStack( - '`.each` must be called with an Array or Tagged Template String.\n\n' + + '`.each` must be called with an Array or Tagged Template Literal.\n\n' + `Instead was called with: ${pretty(tableArg, { maxDepth: 1, min: true, @@ -42,6 +42,36 @@ export default (cb: Function, supportsDone: boolean = true) => (...args: any) => throw error; }); } + + if (isTaggedTemplateLiteral(tableArg)) { + if (isEmptyString(tableArg[0])) { + const error = new ErrorWithStack( + 'Error: `.each` called with an empty Tagged Template Literal of table data.\n', + eachBind, + ); + return cb(title, () => { + throw error; + }); + } + + const error = new ErrorWithStack( + 'Error: `.each` called with a Tagged Template Literal with no data, remember to interpolate with ${expression} syntax.\n', + eachBind, + ); + return cb(title, () => { + throw error; + }); + } + + if (isEmptyTable(tableArg)) { + const error = new ErrorWithStack( + 'Error: `.each` called with an empty Array of table data.\n', + eachBind, + ); + return cb(title, () => { + throw error; + }); + } const table: Table = tableArg.every(Array.isArray) ? tableArg : tableArg.map(entry => [entry]); @@ -91,6 +121,10 @@ export default (cb: Function, supportsDone: boolean = true) => (...args: any) => ); }; +const isTaggedTemplateLiteral = array => array.raw !== undefined; +const isEmptyTable = table => table.length === 0; +const isEmptyString = str => typeof str === 'string' && str.trim() === ''; + const getPrettyIndexes = placeholders => placeholders.reduce( (indexes, placeholder, index) => From fb61bfffb803bad0c2ff9ab1798a6c4c31cb14fa Mon Sep 17 00:00:00 2001 From: Andrew Pyle Date: Tue, 30 Oct 2018 09:05:19 -0500 Subject: [PATCH 18/45] [WIP] [jest-validate] Add config comments feature (#7295) --- CHANGELOG.md | 1 + docs/Configuration.md | 18 +++++++++++++++++ .../src/__tests__/validate.test.js | 20 +++++++++++++++++++ packages/jest-validate/src/defaultConfig.js | 3 ++- packages/jest-validate/src/validate.js | 7 +++++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7793451b3ace..fef44a6a3939 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- `[jest-validate]` Add support for comments in `package.json` using a `"//"` key [#7295](https://github.com/facebook/jest/pull/7295)) - `[jest-config]` Add shorthand for watch plugins and runners ([#7213](https://github.com/facebook/jest/pull/7213)) - `[jest-config]` [**BREAKING**] Deprecate `setupTestFrameworkScriptFile` in favor of new `setupFilesAfterEnv` ([#7119](https://github.com/facebook/jest/pull/7119)) - `[jest-jasmine2/jest-circus/jest-cli]` Add test.todo ([#6996](https://github.com/facebook/jest/pull/6996)) diff --git a/docs/Configuration.md b/docs/Configuration.md index edd6a0f1cf54..35bddeccbdf6 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -980,3 +980,21 @@ Examples of watch plugins include: - [`jest-watch-yarn-workspaces`](https://github.com/cameronhunter/jest-watch-directories/tree/master/packages/jest-watch-yarn-workspaces) _Note: The values in the `watchPlugins` property value can omit the `jest-watch-` prefix of the package name._ + +### `//` [string] + +No default + +This option allow comments in `package.json`. Include the comment text as the value of this key anywhere in `package.json`. + +Example: + +```json +{ + "name": "my-project", + "jest": { + "//": "Comment goes here", + "verbose": true + } +} +``` diff --git a/packages/jest-validate/src/__tests__/validate.test.js b/packages/jest-validate/src/__tests__/validate.test.js index 05c50e5ad886..9f93b9a713e2 100644 --- a/packages/jest-validate/src/__tests__/validate.test.js +++ b/packages/jest-validate/src/__tests__/validate.test.js @@ -266,3 +266,23 @@ test('Repeated types within multiple valid examples are coalesced in error repor ), ).toThrowErrorMatchingSnapshot(); }); + +test('Comments in config JSON using "//" key are not warned', () => { + jest.spyOn(console, 'warn').mockImplementation(() => {}); + const config = {'//': 'a comment'}; + + validate(config, { + exampleConfig: validConfig, + }); + expect(console.warn).not.toBeCalled(); + + console.warn.mockReset(); + + validate(config, { + exampleConfig: validConfig, + recursiveBlacklist: [('myCustomKey': "don't validate this")], + }); + expect(console.warn).not.toBeCalled(); + + console.warn.mockRestore(); +}); diff --git a/packages/jest-validate/src/defaultConfig.js b/packages/jest-validate/src/defaultConfig.js index 2d3d097e6c67..cef77d526f4d 100644 --- a/packages/jest-validate/src/defaultConfig.js +++ b/packages/jest-validate/src/defaultConfig.js @@ -23,7 +23,8 @@ export default ({ error: errorMessage, exampleConfig: {}, recursive: true, - recursiveBlacklist: [], + // Allow NPM-sanctioned comments in package.json. Use a "//" key. + recursiveBlacklist: ['//'], title: { deprecation: DEPRECATION, error: ERROR, diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index cf68a608cdd2..832cba8814ee 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -81,10 +81,17 @@ const _validate = ( const validate = (config: Object, options: ValidationOptions) => { hasDeprecationWarnings = false; + // Preserve default blacklist entries even with user-supplied blacklist + const combinedBlacklist: Array = [].concat( + defaultConfig.recursiveBlacklist || [], + options.recursiveBlacklist || [], + ); + const defaultedOptions: ValidationOptions = Object.assign( {}, defaultConfig, options, + {recursiveBlacklist: combinedBlacklist}, {title: Object.assign({}, defaultConfig.title, options.title)}, ); From 968ddc416ae52f15e15ed1e64b0196f44c3dabde Mon Sep 17 00:00:00 2001 From: Andrew Pyle Date: Wed, 31 Oct 2018 04:28:34 -0500 Subject: [PATCH 19/45] Standardize filenames in packages/expect (#7306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary References Standardize file naming #4969. Updates naming in package expect. Uses conventions listed in #4969 (comment): - Files that primarily export types, objects or classes should use CapitalizedFileNames.js and should mirror what’s inside 1:1. - Files that export a single function should have the function name with camelCase in it. - Folder names should use dashes, unless they are special folders. ### Decisions - Test & snapshot files retained their name, but converted it to camelCase. - Files which exported an object were named according to the internal object, which was camelCase. However, I believe that the standard referenced above states that objects should have CapitalizedNames. Should the internal objects be renamed too? - `matchers.js` - `jestMatchersObject.js` - `spyMatchers.js` - `toThrowmatchers.js` ### Questions How should `asymmetricMatchers.js` be named? It exports a class `AsymmetricMatcher`, but it also exports a bunch of functions, and was named in camelCase before. ## Test plan Output of yarn run test on master and standardize filenames in packages/jest circus branches was the same. [jest-test-expect-master.txt](https://github.com/facebook/jest/files/2532360/jest-test-expect-master.txt) [jest-test-expect-standardize-filenames.txt](https://github.com/facebook/jest/files/2532363/jest-test-expect-standardize-filenames.txt) --- CHANGELOG.md | 1 + ...atchers.test.js.snap => spyMatchers.test.js.snap} | 0 ...ers.test.js.snap => toThrowMatchers.test.js.snap} | 0 ...ertion_counts.test.js => assertionCounts.test.js} | 0 ...c_matchers.test.js => asymmetricMatchers.test.js} | 2 +- packages/expect/src/__tests__/extend.test.js | 2 +- .../{fake_chalk.test.js => fakeChalk.test.js} | 2 +- .../__tests__/{is_error.test.js => isError.test.js} | 0 .../{spy_matchers.test.js => spyMatchers.test.js} | 0 ...ol_in_objects.test.js => symbolInObjects.test.js} | 0 ...hrow_matchers.test.js => toThrowMatchers.test.js} | 0 ...{asymmetric_matchers.js => asymmetricMatchers.js} | 8 +------- ..._errors.js => extractExpectedAssertionsErrors.js} | 2 +- packages/expect/src/{fake_chalk.js => fakeChalk.js} | 0 packages/expect/src/index.js | 12 ++++++------ .../expect/src/{jasmine_utils.js => jasmineUtils.js} | 0 ...jest_matchers_object.js => jestMatchersObject.js} | 2 +- packages/expect/src/matchers.js | 2 +- .../expect/src/{spy_matchers.js => spyMatchers.js} | 2 +- .../src/{to_throw_matchers.js => toThrowMatchers.js} | 2 +- packages/expect/src/utils.js | 2 +- scripts/browserBuild.js | 2 +- 22 files changed, 18 insertions(+), 23 deletions(-) rename packages/expect/src/__tests__/__snapshots__/{spy_matchers.test.js.snap => spyMatchers.test.js.snap} (100%) rename packages/expect/src/__tests__/__snapshots__/{to_throw_matchers.test.js.snap => toThrowMatchers.test.js.snap} (100%) rename packages/expect/src/__tests__/{assertion_counts.test.js => assertionCounts.test.js} (100%) rename packages/expect/src/__tests__/{asymmetric_matchers.test.js => asymmetricMatchers.test.js} (99%) rename packages/expect/src/__tests__/{fake_chalk.test.js => fakeChalk.test.js} (88%) rename packages/expect/src/__tests__/{is_error.test.js => isError.test.js} (100%) rename packages/expect/src/__tests__/{spy_matchers.test.js => spyMatchers.test.js} (100%) rename packages/expect/src/__tests__/{symbol_in_objects.test.js => symbolInObjects.test.js} (100%) rename packages/expect/src/__tests__/{to_throw_matchers.test.js => toThrowMatchers.test.js} (100%) rename packages/expect/src/{asymmetric_matchers.js => asymmetricMatchers.js} (98%) rename packages/expect/src/{extract_expected_assertions_errors.js => extractExpectedAssertionsErrors.js} (97%) rename packages/expect/src/{fake_chalk.js => fakeChalk.js} (100%) rename packages/expect/src/{jasmine_utils.js => jasmineUtils.js} (100%) rename packages/expect/src/{jest_matchers_object.js => jestMatchersObject.js} (97%) rename packages/expect/src/{spy_matchers.js => spyMatchers.js} (99%) rename packages/expect/src/{to_throw_matchers.js => toThrowMatchers.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index fef44a6a3939..7b67389a430c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ ### Fixes +- `[expect]` Standardize file naming in `expect` ([#7306](https://github.com/facebook/jest/pull/7306)) - `[jest-each]` Add empty array validation check ([#7249](https://github.com/facebook/jest/pull/7249)) - `[jest-cli]` Interrupt tests if interactive watch plugin key is pressed ([#7222](https://github.com/facebook/jest/pull/7222)) - `[jest-cli]` Fix coverage summary reporting ([#7058](https://github.com/facebook/jest/pull/7058)) diff --git a/packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap similarity index 100% rename from packages/expect/src/__tests__/__snapshots__/spy_matchers.test.js.snap rename to packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap diff --git a/packages/expect/src/__tests__/__snapshots__/to_throw_matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap similarity index 100% rename from packages/expect/src/__tests__/__snapshots__/to_throw_matchers.test.js.snap rename to packages/expect/src/__tests__/__snapshots__/toThrowMatchers.test.js.snap diff --git a/packages/expect/src/__tests__/assertion_counts.test.js b/packages/expect/src/__tests__/assertionCounts.test.js similarity index 100% rename from packages/expect/src/__tests__/assertion_counts.test.js rename to packages/expect/src/__tests__/assertionCounts.test.js diff --git a/packages/expect/src/__tests__/asymmetric_matchers.test.js b/packages/expect/src/__tests__/asymmetricMatchers.test.js similarity index 99% rename from packages/expect/src/__tests__/asymmetric_matchers.test.js rename to packages/expect/src/__tests__/asymmetricMatchers.test.js index 9b7a030d4d54..08b0907d09ee 100644 --- a/packages/expect/src/__tests__/asymmetric_matchers.test.js +++ b/packages/expect/src/__tests__/asymmetricMatchers.test.js @@ -20,7 +20,7 @@ const { stringNotContaining, stringMatching, stringNotMatching, -} = require('../asymmetric_matchers'); +} = require('../asymmetricMatchers'); test('Any.asymmetricMatch()', () => { const Thing = function() {}; diff --git a/packages/expect/src/__tests__/extend.test.js b/packages/expect/src/__tests__/extend.test.js index 8fe6b6f3c78e..e2f3ecf0bdd6 100644 --- a/packages/expect/src/__tests__/extend.test.js +++ b/packages/expect/src/__tests__/extend.test.js @@ -8,7 +8,7 @@ const matcherUtils = require('jest-matcher-utils'); const {iterableEquality, subsetEquality} = require('../utils'); -const {equals} = require('../jasmine_utils'); +const {equals} = require('../jasmineUtils'); const jestExpect = require('../'); jestExpect.extend({ diff --git a/packages/expect/src/__tests__/fake_chalk.test.js b/packages/expect/src/__tests__/fakeChalk.test.js similarity index 88% rename from packages/expect/src/__tests__/fake_chalk.test.js rename to packages/expect/src/__tests__/fakeChalk.test.js index c461b75c1b2d..532dae6144c7 100644 --- a/packages/expect/src/__tests__/fake_chalk.test.js +++ b/packages/expect/src/__tests__/fakeChalk.test.js @@ -6,7 +6,7 @@ */ 'use strict'; -const fakeChalk = jest.requireActual('../fake_chalk'); +const fakeChalk = jest.requireActual('../fakeChalk'); describe('Fake Chalk', () => { it('returns input when invoked', () => { diff --git a/packages/expect/src/__tests__/is_error.test.js b/packages/expect/src/__tests__/isError.test.js similarity index 100% rename from packages/expect/src/__tests__/is_error.test.js rename to packages/expect/src/__tests__/isError.test.js diff --git a/packages/expect/src/__tests__/spy_matchers.test.js b/packages/expect/src/__tests__/spyMatchers.test.js similarity index 100% rename from packages/expect/src/__tests__/spy_matchers.test.js rename to packages/expect/src/__tests__/spyMatchers.test.js diff --git a/packages/expect/src/__tests__/symbol_in_objects.test.js b/packages/expect/src/__tests__/symbolInObjects.test.js similarity index 100% rename from packages/expect/src/__tests__/symbol_in_objects.test.js rename to packages/expect/src/__tests__/symbolInObjects.test.js diff --git a/packages/expect/src/__tests__/to_throw_matchers.test.js b/packages/expect/src/__tests__/toThrowMatchers.test.js similarity index 100% rename from packages/expect/src/__tests__/to_throw_matchers.test.js rename to packages/expect/src/__tests__/toThrowMatchers.test.js diff --git a/packages/expect/src/asymmetric_matchers.js b/packages/expect/src/asymmetricMatchers.js similarity index 98% rename from packages/expect/src/asymmetric_matchers.js rename to packages/expect/src/asymmetricMatchers.js index b182fb1f1c44..01cc89af8550 100644 --- a/packages/expect/src/asymmetric_matchers.js +++ b/packages/expect/src/asymmetricMatchers.js @@ -7,13 +7,7 @@ * @flow */ -import { - equals, - fnNameFor, - hasProperty, - isA, - isUndefined, -} from './jasmine_utils'; +import {equals, fnNameFor, hasProperty, isA, isUndefined} from './jasmineUtils'; import {emptyObject} from './utils'; diff --git a/packages/expect/src/extract_expected_assertions_errors.js b/packages/expect/src/extractExpectedAssertionsErrors.js similarity index 97% rename from packages/expect/src/extract_expected_assertions_errors.js rename to packages/expect/src/extractExpectedAssertionsErrors.js index af7d243142ae..29f766e6d7f9 100644 --- a/packages/expect/src/extract_expected_assertions_errors.js +++ b/packages/expect/src/extractExpectedAssertionsErrors.js @@ -14,7 +14,7 @@ import { pluralize, } from 'jest-matcher-utils'; -import {getState, setState} from './jest_matchers_object'; +import {getState, setState} from './jestMatchersObject'; const resetAssertionsLocalState = () => { setState({ diff --git a/packages/expect/src/fake_chalk.js b/packages/expect/src/fakeChalk.js similarity index 100% rename from packages/expect/src/fake_chalk.js rename to packages/expect/src/fakeChalk.js diff --git a/packages/expect/src/index.js b/packages/expect/src/index.js index 573d1bf9b42c..4c0aef0d3e92 100644 --- a/packages/expect/src/index.js +++ b/packages/expect/src/index.js @@ -23,11 +23,11 @@ import type { import * as matcherUtils from 'jest-matcher-utils'; import {iterableEquality, subsetEquality} from './utils'; import matchers from './matchers'; -import spyMatchers from './spy_matchers'; +import spyMatchers from './spyMatchers'; import toThrowMatchers, { createMatcher as createThrowMatcher, -} from './to_throw_matchers'; -import {equals} from './jasmine_utils'; +} from './toThrowMatchers'; +import {equals} from './jasmineUtils'; import { any, anything, @@ -39,15 +39,15 @@ import { stringNotContaining, stringMatching, stringNotMatching, -} from './asymmetric_matchers'; +} from './asymmetricMatchers'; import { INTERNAL_MATCHER_FLAG, getState, setState, getMatchers, setMatchers, -} from './jest_matchers_object'; -import extractExpectedAssertionsErrors from './extract_expected_assertions_errors'; +} from './jestMatchersObject'; +import extractExpectedAssertionsErrors from './extractExpectedAssertionsErrors'; class JestAssertionError extends Error { matcherResult: any; diff --git a/packages/expect/src/jasmine_utils.js b/packages/expect/src/jasmineUtils.js similarity index 100% rename from packages/expect/src/jasmine_utils.js rename to packages/expect/src/jasmineUtils.js diff --git a/packages/expect/src/jest_matchers_object.js b/packages/expect/src/jestMatchersObject.js similarity index 97% rename from packages/expect/src/jest_matchers_object.js rename to packages/expect/src/jestMatchersObject.js index 253681620fce..b3b7d8f87d7d 100644 --- a/packages/expect/src/jest_matchers_object.js +++ b/packages/expect/src/jestMatchersObject.js @@ -7,7 +7,7 @@ * @flow */ -import {AsymmetricMatcher} from './asymmetric_matchers'; +import {AsymmetricMatcher} from './asymmetricMatchers'; import type { Expect, MatchersObject, diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 043032bc0803..4e9575213513 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -32,7 +32,7 @@ import { typeEquality, isOneline, } from './utils'; -import {equals} from './jasmine_utils'; +import {equals} from './jasmineUtils'; type ContainIterable = | Array diff --git a/packages/expect/src/spy_matchers.js b/packages/expect/src/spyMatchers.js similarity index 99% rename from packages/expect/src/spy_matchers.js rename to packages/expect/src/spyMatchers.js index 2a176fb9e1f1..5571bd837c79 100644 --- a/packages/expect/src/spy_matchers.js +++ b/packages/expect/src/spyMatchers.js @@ -23,7 +23,7 @@ import { printWithType, RECEIVED_COLOR, } from 'jest-matcher-utils'; -import {equals} from './jasmine_utils'; +import {equals} from './jasmineUtils'; import {iterableEquality, partition, isOneline} from './utils'; import diff from 'jest-diff'; diff --git a/packages/expect/src/to_throw_matchers.js b/packages/expect/src/toThrowMatchers.js similarity index 99% rename from packages/expect/src/to_throw_matchers.js rename to packages/expect/src/toThrowMatchers.js index b5e953a10792..48f69b46d630 100644 --- a/packages/expect/src/to_throw_matchers.js +++ b/packages/expect/src/toThrowMatchers.js @@ -19,7 +19,7 @@ import { printExpected, printWithType, } from 'jest-matcher-utils'; -import {equals} from './jasmine_utils'; +import {equals} from './jasmineUtils'; import {isError} from './utils'; export const createMatcher = (matcherName: string, fromPromise?: boolean) => ( diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index 9a7a0220fac5..2c7de7ab2237 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -12,7 +12,7 @@ import { isA, isImmutableUnorderedKeyed, isImmutableUnorderedSet, -} from './jasmine_utils'; +} from './jasmineUtils'; type GetPath = { hasEndProp?: boolean, diff --git a/scripts/browserBuild.js b/scripts/browserBuild.js index c7f0414c7aa5..ae1c5b3cc636 100644 --- a/scripts/browserBuild.js +++ b/scripts/browserBuild.js @@ -45,7 +45,7 @@ function browserBuild(pkgName, entryPath, destination) { { resolveId(id) { return id === 'chalk' - ? path.resolve(__dirname, '../packages/expect/build/fake_chalk.js') + ? path.resolve(__dirname, '../packages/expect/build/fakeChalk.js') : undefined; }, }, From 2f32100c0e8ae04dc24da25f0713c004bb6b2c51 Mon Sep 17 00:00:00 2001 From: Andrew Pyle Date: Wed, 31 Oct 2018 04:29:05 -0500 Subject: [PATCH 20/45] Standardize filenames in packages/jest circus (#7301) * Rename event_handler -> eventHandler. Function & Mocks * Rename error_handlers -> globalErrorHandlers. File & imports * Rename format_node_assert_errors -> formatNodeAssertErrors - File, Function & Imports renamed - `export default (...` changed to `const formatNodeAssertErrors = (...` with `export default formatNodeAssertErrors` at end of file * Rename test_utils & runTest -> testUtils - Rename file, function, imports, mocks, & tests * Rename after_all.test.js -> afterAll.test.js - Rename file only * Rename after_all.test.js.snap -> afterAll.test.js.snap - Forgot snapshot when renaming afterAll.test.js - Rename snapshot to match test filename * Rename base_test.test.js -> baseTest.test.js - Rename file & snap * Rename circus_it_test_error.test.js -> circusItTestError.test.js * Rename circus_todo_test_error.test.js -> CircusItTodoTestError.test.js - Added "it" to name to match CircusItTestError.test.js - Rename file * Rename hooks_error.test.js -> hooksError.test.js - Rename file * Rename legacy_code_todo_rewrite -> legacy-code-todo-rewrite - Directory names should use dashes * Add CHANGELOG.md entry * Fix broken link to legacy-code-todo-rewrite/ in jest-circus/runner.js * Revert export in testUtils.js to runTest per @thymikee's request * Rename files in legacy-code-todo-rewrite/ - jest_adapter.js -> jestAdapter.js - jest_adapter_init.js -> jestAdapterInit.js - jest_expect.js -> jestExpect.js - Fixed imports within directory and in runner.js --- CHANGELOG.md | 1 + packages/jest-circus/runner.js | 2 +- .../{test_event_handler.js => testEventHandler.js} | 0 .../src/__mocks__/{test_utils.js => testUtils.js} | 2 +- .../{after_all.test.js.snap => afterAll.test.js.snap} | 0 .../{base_test.test.js.snap => baseTest.test.js.snap} | 0 .../src/__tests__/{after_all.test.js => afterAll.test.js} | 2 +- .../src/__tests__/{base_test.test.js => baseTest.test.js} | 2 +- ...rcus_it_test_error.test.js => circusItTestError.test.js} | 0 ...odo_test_error.test.js => circusItTodoTestError.test.js} | 0 packages/jest-circus/src/__tests__/hooks.test.js | 2 +- .../__tests__/{hooks_error.test.js => hooksError.test.js} | 0 .../jest-circus/src/{event_handler.js => eventHandler.js} | 6 +++--- ...rmat_node_assert_errors.js => formatNodeAssertErrors.js} | 4 +++- .../src/{error_handlers.js => globalErrorHandlers.js} | 0 .../jestAdapter.js} | 4 ++-- .../jestAdapterInit.js} | 0 .../jestExpect.js} | 0 packages/jest-circus/src/state.js | 4 ++-- 19 files changed, 16 insertions(+), 13 deletions(-) rename packages/jest-circus/src/__mocks__/{test_event_handler.js => testEventHandler.js} (100%) rename packages/jest-circus/src/__mocks__/{test_utils.js => testUtils.js} (97%) rename packages/jest-circus/src/__tests__/__snapshots__/{after_all.test.js.snap => afterAll.test.js.snap} (100%) rename packages/jest-circus/src/__tests__/__snapshots__/{base_test.test.js.snap => baseTest.test.js.snap} (100%) rename packages/jest-circus/src/__tests__/{after_all.test.js => afterAll.test.js} (97%) rename packages/jest-circus/src/__tests__/{base_test.test.js => baseTest.test.js} (94%) rename packages/jest-circus/src/__tests__/{circus_it_test_error.test.js => circusItTestError.test.js} (100%) rename packages/jest-circus/src/__tests__/{circus_todo_test_error.test.js => circusItTodoTestError.test.js} (100%) rename packages/jest-circus/src/__tests__/{hooks_error.test.js => hooksError.test.js} (100%) rename packages/jest-circus/src/{event_handler.js => eventHandler.js} (97%) rename packages/jest-circus/src/{format_node_assert_errors.js => formatNodeAssertErrors.js} (97%) rename packages/jest-circus/src/{error_handlers.js => globalErrorHandlers.js} (100%) rename packages/jest-circus/src/{legacy_code_todo_rewrite/jest_adapter.js => legacy-code-todo-rewrite/jestAdapter.js} (95%) rename packages/jest-circus/src/{legacy_code_todo_rewrite/jest_adapter_init.js => legacy-code-todo-rewrite/jestAdapterInit.js} (100%) rename packages/jest-circus/src/{legacy_code_todo_rewrite/jest_expect.js => legacy-code-todo-rewrite/jestExpect.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b67389a430c..42f65a4894b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ ### Chore & Maintenance +- `[jest-circus]` Standardize file naming in `jest-circus` ([#7301](https://github.com/facebook/jest/pull/7301)) - `[docs]` Add synchronous test.each setup ([#7150](https://github.com/facebook/jest/pull/7150)) - `[docs]` Add `this.extend` to the Custom Matchers API reference ([#7130](https://github.com/facebook/jest/pull/7130)) - `[docs]` Fix default value for `coverageReporters` value in configuration docs ([#7126](https://github.com/facebook/jest/pull/7126)) diff --git a/packages/jest-circus/runner.js b/packages/jest-circus/runner.js index 214956a9f42a..8ed8163ee414 100644 --- a/packages/jest-circus/runner.js +++ b/packages/jest-circus/runner.js @@ -9,5 +9,5 @@ */ // Allow people to use `jest-circus/runner` as a runner. -const runner = require('./build/legacy_code_todo_rewrite/jest_adapter'); +const runner = require('./build/legacy-code-todo-rewrite/jestAdapter'); module.exports = runner; diff --git a/packages/jest-circus/src/__mocks__/test_event_handler.js b/packages/jest-circus/src/__mocks__/testEventHandler.js similarity index 100% rename from packages/jest-circus/src/__mocks__/test_event_handler.js rename to packages/jest-circus/src/__mocks__/testEventHandler.js diff --git a/packages/jest-circus/src/__mocks__/test_utils.js b/packages/jest-circus/src/__mocks__/testUtils.js similarity index 97% rename from packages/jest-circus/src/__mocks__/test_utils.js rename to packages/jest-circus/src/__mocks__/testUtils.js index 39594b009a2b..4e3ca543dccb 100644 --- a/packages/jest-circus/src/__mocks__/test_utils.js +++ b/packages/jest-circus/src/__mocks__/testUtils.js @@ -20,7 +20,7 @@ import {skipSuiteOnWindows} from '../../../../scripts/ConditionalTest'; const CIRCUS_PATH = require.resolve('../../build/index'); const CIRCUS_RUN_PATH = require.resolve('../../build/run'); const CIRCUS_STATE_PATH = require.resolve('../../build/state'); -const TEST_EVENT_HANDLER_PATH = require.resolve('./test_event_handler'); +const TEST_EVENT_HANDLER_PATH = require.resolve('./testEventHandler'); const BABEL_REGISTER_PATH = require.resolve('babel-register'); skipSuiteOnWindows(); diff --git a/packages/jest-circus/src/__tests__/__snapshots__/after_all.test.js.snap b/packages/jest-circus/src/__tests__/__snapshots__/afterAll.test.js.snap similarity index 100% rename from packages/jest-circus/src/__tests__/__snapshots__/after_all.test.js.snap rename to packages/jest-circus/src/__tests__/__snapshots__/afterAll.test.js.snap diff --git a/packages/jest-circus/src/__tests__/__snapshots__/base_test.test.js.snap b/packages/jest-circus/src/__tests__/__snapshots__/baseTest.test.js.snap similarity index 100% rename from packages/jest-circus/src/__tests__/__snapshots__/base_test.test.js.snap rename to packages/jest-circus/src/__tests__/__snapshots__/baseTest.test.js.snap diff --git a/packages/jest-circus/src/__tests__/after_all.test.js b/packages/jest-circus/src/__tests__/afterAll.test.js similarity index 97% rename from packages/jest-circus/src/__tests__/after_all.test.js rename to packages/jest-circus/src/__tests__/afterAll.test.js index 22e424d96f20..7cccc1f66d49 100644 --- a/packages/jest-circus/src/__tests__/after_all.test.js +++ b/packages/jest-circus/src/__tests__/afterAll.test.js @@ -10,7 +10,7 @@ 'use strict'; -import {runTest} from '../__mocks__/test_utils'; +import {runTest} from '../__mocks__/testUtils'; test('tests are not marked done until their parent afterAll runs', () => { const {stdout} = runTest(` diff --git a/packages/jest-circus/src/__tests__/base_test.test.js b/packages/jest-circus/src/__tests__/baseTest.test.js similarity index 94% rename from packages/jest-circus/src/__tests__/base_test.test.js rename to packages/jest-circus/src/__tests__/baseTest.test.js index ec83663ba8db..1cc1c2abab94 100644 --- a/packages/jest-circus/src/__tests__/base_test.test.js +++ b/packages/jest-circus/src/__tests__/baseTest.test.js @@ -10,7 +10,7 @@ 'use strict'; -import {runTest} from '../__mocks__/test_utils'; +import {runTest} from '../__mocks__/testUtils'; test('simple test', () => { const {stdout} = runTest(` diff --git a/packages/jest-circus/src/__tests__/circus_it_test_error.test.js b/packages/jest-circus/src/__tests__/circusItTestError.test.js similarity index 100% rename from packages/jest-circus/src/__tests__/circus_it_test_error.test.js rename to packages/jest-circus/src/__tests__/circusItTestError.test.js diff --git a/packages/jest-circus/src/__tests__/circus_todo_test_error.test.js b/packages/jest-circus/src/__tests__/circusItTodoTestError.test.js similarity index 100% rename from packages/jest-circus/src/__tests__/circus_todo_test_error.test.js rename to packages/jest-circus/src/__tests__/circusItTodoTestError.test.js diff --git a/packages/jest-circus/src/__tests__/hooks.test.js b/packages/jest-circus/src/__tests__/hooks.test.js index 2486cc3d6e62..6d9b58bce341 100644 --- a/packages/jest-circus/src/__tests__/hooks.test.js +++ b/packages/jest-circus/src/__tests__/hooks.test.js @@ -10,7 +10,7 @@ 'use strict'; -import {runTest} from '../__mocks__/test_utils'; +import {runTest} from '../__mocks__/testUtils'; test('beforeEach is executed before each test in current/child describe blocks', () => { const {stdout} = runTest(` diff --git a/packages/jest-circus/src/__tests__/hooks_error.test.js b/packages/jest-circus/src/__tests__/hooksError.test.js similarity index 100% rename from packages/jest-circus/src/__tests__/hooks_error.test.js rename to packages/jest-circus/src/__tests__/hooksError.test.js diff --git a/packages/jest-circus/src/event_handler.js b/packages/jest-circus/src/eventHandler.js similarity index 97% rename from packages/jest-circus/src/event_handler.js rename to packages/jest-circus/src/eventHandler.js index fb5af141b802..893e61f61410 100644 --- a/packages/jest-circus/src/event_handler.js +++ b/packages/jest-circus/src/eventHandler.js @@ -20,12 +20,12 @@ import { import { injectGlobalErrorHandlers, restoreGlobalErrorHandlers, -} from './error_handlers'; +} from './globalErrorHandlers'; // To pass this value from Runtime object to state we need to use global[sym] const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL'); -const handler: EventHandler = (event, state): void => { +const eventHandler: EventHandler = (event, state): void => { switch (event.name) { case 'include_test_location_in_result': { state.includeTestLocationInResult = true; @@ -183,4 +183,4 @@ const handler: EventHandler = (event, state): void => { } }; -export default handler; +export default eventHandler; diff --git a/packages/jest-circus/src/format_node_assert_errors.js b/packages/jest-circus/src/formatNodeAssertErrors.js similarity index 97% rename from packages/jest-circus/src/format_node_assert_errors.js rename to packages/jest-circus/src/formatNodeAssertErrors.js index 9151fa9fe3fa..d6080ce0b168 100644 --- a/packages/jest-circus/src/format_node_assert_errors.js +++ b/packages/jest-circus/src/formatNodeAssertErrors.js @@ -43,7 +43,7 @@ const humanReadableOperators = { strictEqual: 'to strictly be equal', }; -export default (event: Event, state: State) => { +const formatNodeAssertErrors = (event: Event, state: State) => { switch (event.name) { case 'test_done': { event.test.errors = event.test.errors.map(errors => { @@ -167,3 +167,5 @@ function assertionErrorMessage(error: AssertionError, options: DiffOptions) { trimmedStack ); } + +export default formatNodeAssertErrors; diff --git a/packages/jest-circus/src/error_handlers.js b/packages/jest-circus/src/globalErrorHandlers.js similarity index 100% rename from packages/jest-circus/src/error_handlers.js rename to packages/jest-circus/src/globalErrorHandlers.js diff --git a/packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter.js b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.js similarity index 95% rename from packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter.js rename to packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.js index bf2d87b9f4bd..af85e4d095b4 100644 --- a/packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter.js +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.js @@ -12,7 +12,7 @@ import type {GlobalConfig, ProjectConfig} from 'types/Config'; import type {TestResult} from 'types/TestResult'; import type Runtime from 'jest-runtime'; -const FRAMEWORK_INITIALIZER = require.resolve('./jest_adapter_init'); +const FRAMEWORK_INITIALIZER = require.resolve('./jestAdapterInit'); import path from 'path'; const jestAdapter = async ( @@ -28,7 +28,7 @@ const jestAdapter = async ( } = runtime.requireInternalModule(FRAMEWORK_INITIALIZER); runtime - .requireInternalModule(path.resolve(__dirname, './jest_expect.js')) + .requireInternalModule(path.resolve(__dirname, './jestExpect.js')) .default({ expand: globalConfig.expand, }); diff --git a/packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter_init.js b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.js similarity index 100% rename from packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter_init.js rename to packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.js diff --git a/packages/jest-circus/src/legacy_code_todo_rewrite/jest_expect.js b/packages/jest-circus/src/legacy-code-todo-rewrite/jestExpect.js similarity index 100% rename from packages/jest-circus/src/legacy_code_todo_rewrite/jest_expect.js rename to packages/jest-circus/src/legacy-code-todo-rewrite/jestExpect.js diff --git a/packages/jest-circus/src/state.js b/packages/jest-circus/src/state.js index 3187775bcc2f..36d4fa69cf04 100644 --- a/packages/jest-circus/src/state.js +++ b/packages/jest-circus/src/state.js @@ -10,8 +10,8 @@ import type {Event, State, EventHandler} from 'types/Circus'; import {makeDescribe} from './utils'; -import eventHandler from './event_handler'; -import formatNodeAssertErrors from './format_node_assert_errors'; +import eventHandler from './eventHandler'; +import formatNodeAssertErrors from './formatNodeAssertErrors'; const eventHandlers: Array = [ eventHandler, From b5310c1a41debd5f37108b3b8fd117a84d2c95bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 31 Oct 2018 11:41:06 +0100 Subject: [PATCH 21/45] feat: upgrade Flow to 0.85.0 (#7303) --- .flowconfig | 2 +- package.json | 2 +- packages/expect/src/jasmineUtils.js | 5 ++++- .../jest-cli/src/lib/__tests__/init.test.js | 4 ++++ .../jest-cli/src/reporters/verbose_reporter.js | 4 +++- packages/jest-config/src/normalize.js | 17 ++++++++++++----- .../src/__tests__/inline_snapshots.test.js | 16 ++++++++++++++++ .../src/lib/format_test_name_by_pattern.js | 1 - .../pretty-format/src/__tests__/react.test.js | 7 +------ types/Matchers.js | 2 +- types/TestResult.js | 8 +++++++- yarn.lock | 8 ++++---- 12 files changed, 54 insertions(+), 22 deletions(-) diff --git a/.flowconfig b/.flowconfig index 27a7723184e7..e4a6b93f5217 100644 --- a/.flowconfig +++ b/.flowconfig @@ -18,4 +18,4 @@ untyped-import untyped-type-import [version] -^0.80.0 +^0.85.0 diff --git a/package.json b/package.json index 412ff5e20274..1a1dff05b021 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "~0.0.19", "execa": "^1.0.0", - "flow-bin": "^0.80.0", + "flow-bin": "^0.85.0", "glob": "^7.1.1", "graceful-fs": "^4.1.11", "istanbul-api": "^1.3.1", diff --git a/packages/expect/src/jasmineUtils.js b/packages/expect/src/jasmineUtils.js index 144374f0cdff..a1b88aac8f5a 100644 --- a/packages/expect/src/jasmineUtils.js +++ b/packages/expect/src/jasmineUtils.js @@ -39,7 +39,7 @@ export function equals( } function isAsymmetric(obj) { - return obj && isA('Function', obj.asymmetricMatch); + return !!obj && isA('Function', obj.asymmetricMatch); } function asymmetricMatch(a, b) { @@ -51,6 +51,7 @@ function asymmetricMatch(a, b) { } if (asymmetricA) { + // $FlowFixMe – Flow sees `a` as a number return a.asymmetricMatch(b); } @@ -96,6 +97,7 @@ function eq(a, b, aStack, bStack, customTesters, hasKey): boolean { case '[object String]': // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is // equivalent to `new String("5")`. + // $FlowFixMe – Flow sees `a` as a number return a == String(b); case '[object Number]': // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for @@ -113,6 +115,7 @@ function eq(a, b, aStack, bStack, customTesters, hasKey): boolean { a.source == b.source && a.global == b.global && a.multiline == b.multiline && + // $FlowFixMe – Flow sees `a` as a number a.ignoreCase == b.ignoreCase ); } diff --git a/packages/jest-cli/src/lib/__tests__/init.test.js b/packages/jest-cli/src/lib/__tests__/init.test.js index a38c59492e18..81981ce6e0c2 100644 --- a/packages/jest-cli/src/lib/__tests__/init.test.js +++ b/packages/jest-cli/src/lib/__tests__/init.test.js @@ -31,7 +31,9 @@ describe('init', () => { beforeEach(() => { // $FlowFixMe mock console.log to reduce noise from the tests console.log = jest.fn(); + // $FlowFixMe mock fs.writeFileSync = jest.fn(); + // $FlowFixMe mock path.sep = '/'; }); @@ -39,7 +41,9 @@ describe('init', () => { jest.clearAllMocks(); // $FlowFixMe console.log = consoleLog; + // $FlowFixMe mock fs.writeFileSync = writeFileSync; + // $FlowFixMe mock path.sep = sep; }); diff --git a/packages/jest-cli/src/reporters/verbose_reporter.js b/packages/jest-cli/src/reporters/verbose_reporter.js index 9883c1844049..ff82c3f573ea 100644 --- a/packages/jest-cli/src/reporters/verbose_reporter.js +++ b/packages/jest-cli/src/reporters/verbose_reporter.js @@ -28,7 +28,9 @@ export default class VerboseReporter extends DefaultReporter { this._globalConfig = globalConfig; } - static filterTestResults(testResults: Array) { + static filterTestResults( + testResults: Array, + ): Array { return testResults.filter(({status}) => status !== 'pending'); } diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 0defd7699714..fc04dd34deec 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -8,7 +8,13 @@ */ import type {Argv} from 'types/Argv'; -import type {InitialOptions, ReporterConfig} from 'types/Config'; +import type { + InitialOptions, + DefaultOptions, + ReporterConfig, + GlobalConfig, + ProjectConfig, +} from 'types/Config'; import crypto from 'crypto'; import glob from 'glob'; @@ -419,9 +425,9 @@ export default function normalize(options: InitialOptions, argv: Argv) { } const babelJest = setupBabelJest(options); - const newOptions = Object.assign({}, DEFAULT_CONFIG); - // Cast back to exact type - options = (options: InitialOptions); + const newOptions: $Shape< + DefaultOptions & ProjectConfig & GlobalConfig, + > = (Object.assign({}, DEFAULT_CONFIG): any); if (options.resolver) { newOptions.resolver = resolve(null, { @@ -431,7 +437,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { }); } - Object.keys(options).reduce((newOptions, key) => { + Object.keys(options).reduce((newOptions, key: $Keys) => { // The resolver has been resolved separately; skip it if (key === 'resolver') { return newOptions; @@ -687,6 +693,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { }); break; } + // $FlowFixMe - automock is missing in GlobalConfig, so what newOptions[key] = value; return newOptions; }, newOptions); diff --git a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.js b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.js index d8a19052e9d9..cbd98b3bd297 100644 --- a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.js +++ b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.js @@ -23,27 +23,37 @@ const existsSync = fs.existsSync; const statSync = fs.statSync; const readdirSync = fs.readdirSync; beforeEach(() => { + // $FlowFixMe mock fs.writeFileSync = jest.fn(); + // $FlowFixMe mock fs.readFileSync = jest.fn(); + // $FlowFixMe mock fs.existsSync = jest.fn(() => true); // $FlowFixMe mock fs.statSync = jest.fn(filePath => ({ isDirectory: () => !filePath.endsWith('.js'), })); + // $FlowFixMe mock fs.readdirSync = jest.fn(() => []); prettier.resolveConfig.sync.mockReset(); }); afterEach(() => { + // $FlowFixMe mock fs.writeFileSync = writeFileSync; + // $FlowFixMe mock fs.readFileSync = readFileSync; + // $FlowFixMe mock fs.existsSync = existsSync; + // $FlowFixMe mock fs.statSync = statSync; + // $FlowFixMe mock fs.readdirSync = readdirSync; }); test('saveInlineSnapshots() replaces empty function call with a template literal', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => `expect(1).toMatchInlineSnapshot();\n`, ): any); @@ -69,6 +79,7 @@ test.each([['babylon'], ['flow'], ['typescript']])( 'saveInlineSnapshots() replaces existing template literal - %s parser', parser => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => 'expect(1).toMatchInlineSnapshot(`2`);\n', ): any); @@ -97,6 +108,7 @@ test.each([['babylon'], ['flow'], ['typescript']])( test('saveInlineSnapshots() replaces existing template literal with property matchers', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => 'expect(1).toMatchInlineSnapshot({}, `2`);\n', ): any); @@ -120,6 +132,7 @@ test('saveInlineSnapshots() replaces existing template literal with property mat test('saveInlineSnapshots() throws if frame does not match', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => 'expect(1).toMatchInlineSnapshot();\n', ): any); @@ -141,6 +154,7 @@ test('saveInlineSnapshots() throws if frame does not match', () => { test('saveInlineSnapshots() throws if multiple calls to to the same location', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => 'expect(1).toMatchInlineSnapshot();\n', ): any); @@ -160,6 +174,7 @@ test('saveInlineSnapshots() throws if multiple calls to to the same location', ( test('saveInlineSnapshots() uses escaped backticks', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => 'expect("`").toMatchInlineSnapshot();\n', ): any); @@ -175,6 +190,7 @@ test('saveInlineSnapshots() uses escaped backticks', () => { test('saveInlineSnapshots() works with non-literals in expect call', () => { const filename = path.join(__dirname, 'my.test.js'); + // $FlowFixMe mock fs.readFileSync = (jest.fn( () => `expect({a: 'a'}).toMatchInlineSnapshot();\n`, ): any); diff --git a/packages/jest-watcher/src/lib/format_test_name_by_pattern.js b/packages/jest-watcher/src/lib/format_test_name_by_pattern.js index ea07bfc726ee..ac4b3b090bec 100644 --- a/packages/jest-watcher/src/lib/format_test_name_by_pattern.js +++ b/packages/jest-watcher/src/lib/format_test_name_by_pattern.js @@ -31,7 +31,6 @@ export default (testName: string, pattern: string, width: number) => { return chalk.dim(inlineTestName); } - // $FlowFixMe const startPatternIndex = Math.max(match.index, 0); const endPatternIndex = startPatternIndex + match[0].length; diff --git a/packages/pretty-format/src/__tests__/react.test.js b/packages/pretty-format/src/__tests__/react.test.js index 77ed951983e4..ebd2a4fd4cd1 100644 --- a/packages/pretty-format/src/__tests__/react.test.js +++ b/packages/pretty-format/src/__tests__/react.test.js @@ -272,12 +272,7 @@ test('supports a single element with custom React elements with props (using dis test('supports a single element with custom React elements with props (using anonymous function)', () => { assertPrintedJSX( React.createElement('Mouse', { - prop: React.createElement( - () => { - React.createElement('div'); - }, - {foo: 'bar'}, - ), + prop: React.createElement(() => React.createElement('div'), {foo: 'bar'}), }), '\n }\n/>', ); diff --git a/types/Matchers.js b/types/Matchers.js index 70be4f1a50ab..79e89d433fb8 100644 --- a/types/Matchers.js +++ b/types/Matchers.js @@ -50,7 +50,7 @@ export type Expect = { assertions(number): void, extend(any): void, extractExpectedAssertionsErrors: () => Array<{ - actual: string, + actual: string | number, error: Error, expected: string, }>, diff --git a/types/TestResult.js b/types/TestResult.js index 7ef862e2308e..2cf15a5dbfa9 100644 --- a/types/TestResult.js +++ b/types/TestResult.js @@ -83,7 +83,13 @@ export type AssertionLocation = {| path: string, |}; -export type Status = 'passed' | 'failed' | 'skipped' | 'pending' | 'todo'; +export type Status = + | 'passed' + | 'failed' + | 'skipped' + | 'pending' + | 'todo' + | 'disabled'; export type Bytes = number; export type Milliseconds = number; diff --git a/yarn.lock b/yarn.lock index 9fab80793a82..b20d4a6f2266 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6099,10 +6099,10 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I= -flow-bin@^0.80.0: - version "0.80.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.80.0.tgz#04cc1ee626a6f50786f78170c92ebe1745235403" - integrity sha512-0wRnqvXErQRPrx6GBLB5swgndfWkotd9MgfePgT7Z+VsE046c8Apzl7KKTCypB/pzn0pZF2g5Jurxxb2umET8g== +flow-bin@^0.85.0: + version "0.85.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.85.0.tgz#a3ca80748a35a071d5bbb2fcd61d64d977fc53a6" + integrity sha512-ougBA2q6Rn9sZrjZQ9r5pTFxCotlGouySpD2yRIuq5AYwwfIT8HHhVMeSwrN5qJayjHINLJyrnsSkkPCZyfMrQ== flow-remove-types@^1.1.0: version "1.2.3" From bb9efac6c0e5fa3e487d80a639658c29044e081c Mon Sep 17 00:00:00 2001 From: Jeff Lau Date: Wed, 31 Oct 2018 19:41:34 -0400 Subject: [PATCH 22/45] Fix bugs with mock/spy result tracking of recursive functions. (#6381) --- CHANGELOG.md | 6 +- docs/MockFunctionAPI.md | 16 +- .../__snapshots__/spyMatchers.test.js.snap | 142 ++++++++++++++++++ .../expect/src/__tests__/spyMatchers.test.js | 142 +++++++++++++++++- packages/expect/src/spyMatchers.js | 49 +++--- .../jest-mock/src/__tests__/jest_mock.test.js | 138 +++++++++++++++-- packages/jest-mock/src/index.js | 36 ++++- .../mock_serializer.test.js.snap | 12 +- .../src/__tests__/mock_serializer.test.js | 6 +- 9 files changed, 488 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42f65a4894b7..8a0b85b5fb40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ - `[jest-config]` Use strings instead of `RegExp` instances in normalized configuration ([#7251](https://github.com/facebook/jest/pull/7251)) - `[jest-circus]` Make sure to display real duration even if time is mocked ([#7264](https://github.com/facebook/jest/pull/7264)) - `[expect]` Improves the failing message for `toStrictEqual` matcher. ([#7224](https://github.com/facebook/jest/pull/7224)) +- `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381) ### Chore & Maintenance @@ -185,9 +186,6 @@ ### Fixes - `[jest-haste-map]` Optimize watchman crawler by using `glob` on initial query ([#6689](https://github.com/facebook/jest/pull/6689)) - -### Fixes - - `[pretty-format]` Fix formatting of invalid Date objects ([#6635](https://github.com/facebook/jest/pull/6635)) ## 23.4.0 @@ -348,7 +346,7 @@ - `[jest-diff]` Support returning diff from oneline strings ([#6221](https://github.com/facebook/jest/pull/6221)) - `[expect]` Improve return matchers ([#6172](https://github.com/facebook/jest/pull/6172)) - `[jest-cli]` Overhaul watch plugin hooks names ([#6249](https://github.com/facebook/jest/pull/6249)) -- `[jest-mock]` Include tracked call results in serialized mock ([#6244](https://github.com/facebook/jest/pull/6244)) +- `[jest-mock]` [**BREAKING**] Include tracked call results in serialized mock ([#6244](https://github.com/facebook/jest/pull/6244)) ### Fixes diff --git a/docs/MockFunctionAPI.md b/docs/MockFunctionAPI.md index dfdfb7672ac8..199d7a797175 100644 --- a/docs/MockFunctionAPI.md +++ b/docs/MockFunctionAPI.md @@ -29,24 +29,30 @@ For example: A mock function `f` that has been called twice, with the arguments ### `mockFn.mock.results` -An array containing the results of all calls that have been made to this mock function. Each entry in this array is an object containing a boolean `isThrow` property, and a `value` property. `isThrow` is true if the call terminated due to a `throw`, or false if the the call returned normally. The `value` property contains the value that was thrown or returned. +An array containing the results of all calls that have been made to this mock function. Each entry in this array is an object containing a `type` property, and a `value` property. `type` will be one of the following: -For example: A mock function `f` that has been called three times, returning `result1`, throwing an error, and then returning `result2`, would have a `mock.results` array that looks like this: +- `'return'` - Indicates that the call completed by returning normally. +- `'throw'` - Indicates that the call completed by throwing a value. +- `'incomplete'` - Indicates that the call has not yet completed. This occurs if you test the result from within the mock function itself, or from within a function that was called by the mock. + +The `value` property contains the value that was thrown or returned. `value` is undefined when `type === 'incomplete'`. + +For example: A mock function `f` that has been called three times, returning `'result1'`, throwing an error, and then returning `'result2'`, would have a `mock.results` array that looks like this: ```js [ { - isThrow: false, + type: 'return', value: 'result1', }, { - isThrow: true, + type: 'throw', value: { /* Error instance */ }, }, { - isThrow: false, + type: 'return', value: 'result2', }, ]; diff --git a/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap index 95a15e70ccf4..220a4e47e8de 100644 --- a/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap @@ -149,6 +149,14 @@ Expected mock function \\"named-mock\\" to have last returned: But it was not called" `; +exports[`lastReturnedWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).lastReturnedWith(expected) + +Expected mock function to have last returned: + 0 +But the last call has not returned yet" +`; + exports[`lastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].lastReturnedWith() @@ -237,6 +245,15 @@ But the last call returned: \\"foo\\"" `; +exports[`lastReturnedWith works with three calls 1`] = ` +"expect(jest.fn()).not.lastReturnedWith(expected) + +Expected mock function to not have last returned: + \\"foo3\\" +But it last returned exactly: + \\"foo3\\"" +`; + exports[`lastReturnedWith works with undefined 1`] = ` "expect(jest.fn()).not.lastReturnedWith(expected) @@ -406,6 +423,40 @@ Expected mock function \\"named-mock\\" first call to have returned with: But it was not called" `; +exports[`nthReturnedWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).nthReturnedWith(expected) + +Expected mock function first call to have returned with: + 6 +But the first call has not returned yet" +`; + +exports[`nthReturnedWith incomplete recursive calls are handled properly 2`] = ` +"expect(jest.fn()).nthReturnedWith(expected) + +Expected mock function second call to have returned with: + 3 +But the second call has not returned yet" +`; + +exports[`nthReturnedWith incomplete recursive calls are handled properly 3`] = ` +"expect(jest.fn()).not.nthReturnedWith(expected) + +Expected mock function third call to not have returned with: + 1 +But the third call returned exactly: + 1" +`; + +exports[`nthReturnedWith incomplete recursive calls are handled properly 4`] = ` +"expect(jest.fn()).not.nthReturnedWith(expected) + +Expected mock function 4th call to not have returned with: + 0 +But the 4th call returned exactly: + 0" +`; + exports[`nthReturnedWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`nthReturnedWith should reject nth value greater than number of calls 1`] = ` @@ -1437,6 +1488,14 @@ Expected mock function \\"named-mock\\" to have last returned: But it was not called" `; +exports[`toHaveLastReturnedWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toHaveLastReturnedWith(expected) + +Expected mock function to have last returned: + 0 +But the last call has not returned yet" +`; + exports[`toHaveLastReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveLastReturnedWith() @@ -1525,6 +1584,15 @@ But the last call returned: \\"foo\\"" `; +exports[`toHaveLastReturnedWith works with three calls 1`] = ` +"expect(jest.fn()).not.toHaveLastReturnedWith(expected) + +Expected mock function to not have last returned: + \\"foo3\\" +But it last returned exactly: + \\"foo3\\"" +`; + exports[`toHaveLastReturnedWith works with undefined 1`] = ` "expect(jest.fn()).not.toHaveLastReturnedWith(expected) @@ -1558,6 +1626,40 @@ Expected mock function \\"named-mock\\" first call to have returned with: But it was not called" `; +exports[`toHaveNthReturnedWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toHaveNthReturnedWith(expected) + +Expected mock function first call to have returned with: + 6 +But the first call has not returned yet" +`; + +exports[`toHaveNthReturnedWith incomplete recursive calls are handled properly 2`] = ` +"expect(jest.fn()).toHaveNthReturnedWith(expected) + +Expected mock function second call to have returned with: + 3 +But the second call has not returned yet" +`; + +exports[`toHaveNthReturnedWith incomplete recursive calls are handled properly 3`] = ` +"expect(jest.fn()).not.toHaveNthReturnedWith(expected) + +Expected mock function third call to not have returned with: + 1 +But the third call returned exactly: + 1" +`; + +exports[`toHaveNthReturnedWith incomplete recursive calls are handled properly 4`] = ` +"expect(jest.fn()).not.toHaveNthReturnedWith(expected) + +Expected mock function 4th call to not have returned with: + 0 +But the 4th call returned exactly: + 0" +`; + exports[`toHaveNthReturnedWith should reject non integer nth value 1`] = `"nth value 0.1 must be a positive integer greater than 0"`; exports[`toHaveNthReturnedWith should reject nth value greater than number of calls 1`] = ` @@ -1735,6 +1837,12 @@ Expected mock function \\"named-mock\\" not to have returned, but it returned: 42" `; +exports[`toHaveReturned incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toHaveReturned() + +Expected mock function to have returned." +`; + exports[`toHaveReturned passes when at least one call does not throw 1`] = ` "expect(jest.fn()).not.toHaveReturned() @@ -1850,6 +1958,12 @@ exports[`toHaveReturnedTimes includes the custom mock name in the error message Expected mock function \\"named-mock\\" to have returned one time, but it returned two times." `; +exports[`toHaveReturnedTimes incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).not.toHaveReturnedTimes(2) + +Expected mock function not to have returned two times, but it returned exactly two times." +`; + exports[`toHaveReturnedTimes only accepts a number argument 1`] = ` "expect(received)[.not].toHaveReturnedTimes(expected) @@ -1936,6 +2050,14 @@ Expected mock function \\"named-mock\\" to have returned: But it did not return." `; +exports[`toHaveReturnedWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toHaveReturnedWith(expected) + +Expected mock function to have returned: + undefined +But it did not return." +`; + exports[`toHaveReturnedWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toHaveReturnedWith() @@ -2093,6 +2215,12 @@ Expected mock function \\"named-mock\\" not to have returned, but it returned: 42" `; +exports[`toReturn incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toReturn() + +Expected mock function to have returned." +`; + exports[`toReturn passes when at least one call does not throw 1`] = ` "expect(jest.fn()).not.toReturn() @@ -2208,6 +2336,12 @@ exports[`toReturnTimes includes the custom mock name in the error message 1`] = Expected mock function \\"named-mock\\" to have returned one time, but it returned two times." `; +exports[`toReturnTimes incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).not.toReturnTimes(2) + +Expected mock function not to have returned two times, but it returned exactly two times." +`; + exports[`toReturnTimes only accepts a number argument 1`] = ` "expect(received)[.not].toReturnTimes(expected) @@ -2294,6 +2428,14 @@ Expected mock function \\"named-mock\\" to have returned: But it did not return." `; +exports[`toReturnWith incomplete recursive calls are handled properly 1`] = ` +"expect(jest.fn()).toReturnWith(expected) + +Expected mock function to have returned: + undefined +But it did not return." +`; + exports[`toReturnWith works only on spies or jest.fn 1`] = ` "expect(jest.fn())[.not].toReturnWith() diff --git a/packages/expect/src/__tests__/spyMatchers.test.js b/packages/expect/src/__tests__/spyMatchers.test.js index 3ae90bfe7b11..d90a959cafd0 100644 --- a/packages/expect/src/__tests__/spyMatchers.test.js +++ b/packages/expect/src/__tests__/spyMatchers.test.js @@ -491,6 +491,25 @@ const jestExpect = require('../'); jestExpect(fn).not[returned](), ).toThrowErrorMatchingSnapshot(); }); + + test(`incomplete recursive calls are handled properly`, () => { + // sums up all integers from 0 -> value, using recursion + const fn = jest.fn(value => { + if (value === 0) { + // Before returning from the base case of recursion, none of the + // calls have returned yet. + jestExpect(fn).not[returned](); + expect(() => + jestExpect(fn)[returned](), + ).toThrowErrorMatchingSnapshot(); + return 0; + } else { + return value + fn(value - 1); + } + }); + + fn(3); + }); }); }); @@ -641,6 +660,29 @@ const jestExpect = require('../'); jestExpect(fn)[returnedTimes](1), ).toThrowErrorMatchingSnapshot(); }); + + test(`incomplete recursive calls are handled properly`, () => { + // sums up all integers from 0 -> value, using recursion + const fn = jest.fn(value => { + if (value === 0) { + return 0; + } else { + const recursiveResult = fn(value - 1); + + if (value === 2) { + // Only 2 of the recursive calls have returned at this point + jestExpect(fn)[returnedTimes](2); + expect(() => + jestExpect(fn).not[returnedTimes](2), + ).toThrowErrorMatchingSnapshot(); + } + + return value + recursiveResult; + } + }); + + fn(3); + }); }); }); @@ -849,10 +891,32 @@ const jestExpect = require('../'); jestExpect(fn)[returnedWith]('bar'); }).toThrowErrorMatchingSnapshot(); }); + + test(`incomplete recursive calls are handled properly`, () => { + // sums up all integers from 0 -> value, using recursion + const fn = jest.fn(value => { + if (value === 0) { + // Before returning from the base case of recursion, none of the + // calls have returned yet. + // This test ensures that the incomplete calls are not incorrectly + // interpretted as have returned undefined + jestExpect(fn).not[returnedWith](undefined); + expect(() => + jestExpect(fn)[returnedWith](undefined), + ).toThrowErrorMatchingSnapshot(); + + return 0; + } else { + return value + fn(value - 1); + } + }); + + fn(3); + }); } - const nthCalled = ['toHaveNthReturnedWith', 'nthReturnedWith']; - if (nthCalled.indexOf(returnedWith) >= 0) { + const nthReturnedWith = ['toHaveNthReturnedWith', 'nthReturnedWith']; + if (nthReturnedWith.indexOf(returnedWith) >= 0) { test(`works with three calls`, () => { const fn = jest.fn(); fn.mockReturnValueOnce('foo1'); @@ -923,6 +987,80 @@ const jestExpect = require('../'); jestExpect(fn)[returnedWith](0.1, 'foo'); }).toThrowErrorMatchingSnapshot(); }); + + test(`incomplete recursive calls are handled properly`, () => { + // sums up all integers from 0 -> value, using recursion + const fn = jest.fn(value => { + if (value === 0) { + return 0; + } else { + const recursiveResult = fn(value - 1); + + if (value === 2) { + // Only 2 of the recursive calls have returned at this point + jestExpect(fn).not[returnedWith](1, 6); + jestExpect(fn).not[returnedWith](2, 3); + jestExpect(fn)[returnedWith](3, 1); + jestExpect(fn)[returnedWith](4, 0); + + expect(() => + jestExpect(fn)[returnedWith](1, 6), + ).toThrowErrorMatchingSnapshot(); + expect(() => + jestExpect(fn)[returnedWith](2, 3), + ).toThrowErrorMatchingSnapshot(); + expect(() => + jestExpect(fn).not[returnedWith](3, 1), + ).toThrowErrorMatchingSnapshot(); + expect(() => + jestExpect(fn).not[returnedWith](4, 0), + ).toThrowErrorMatchingSnapshot(); + } + + return value + recursiveResult; + } + }); + + fn(3); + }); + } + + const lastReturnedWith = ['toHaveLastReturnedWith', 'lastReturnedWith']; + if (lastReturnedWith.indexOf(returnedWith) >= 0) { + test(`works with three calls`, () => { + const fn = jest.fn(); + fn.mockReturnValueOnce('foo1'); + fn.mockReturnValueOnce('foo2'); + fn.mockReturnValueOnce('foo3'); + fn(); + fn(); + fn(); + + jestExpect(fn)[returnedWith]('foo3'); + + expect(() => { + jestExpect(fn).not[returnedWith]('foo3'); + }).toThrowErrorMatchingSnapshot(); + }); + + test(`incomplete recursive calls are handled properly`, () => { + // sums up all integers from 0 -> value, using recursion + const fn = jest.fn(value => { + if (value === 0) { + // Before returning from the base case of recursion, none of the + // calls have returned yet. + jestExpect(fn).not[returnedWith](0); + expect(() => + jestExpect(fn)[returnedWith](0), + ).toThrowErrorMatchingSnapshot(); + return 0; + } else { + return value + fn(value - 1); + } + }); + + fn(3); + }); } test(`includes the custom mock name in the error message`, () => { diff --git a/packages/expect/src/spyMatchers.js b/packages/expect/src/spyMatchers.js index 5571bd837c79..a494cc8b2368 100644 --- a/packages/expect/src/spyMatchers.js +++ b/packages/expect/src/spyMatchers.js @@ -69,10 +69,9 @@ const createToReturnMatcher = matcherName => (received, expected) => { ? 'mock function' : `mock function "${receivedName}"`; - // List of return values that correspond only to calls that did not throw - // an error + // List of return values that correspond only to calls that returned const returnValues = received.mock.results - .filter(result => !result.isThrow) + .filter(result => result.type === 'return') .map(result => result.value); const count = returnValues.length; @@ -140,9 +139,10 @@ const createToReturnTimesMatcher = (matcherName: string) => ( ? 'mock function' : `mock function "${receivedName}"`; - // List of return results that correspond only to calls that did not throw - // an error - const returnResults = received.mock.results.filter(result => !result.isThrow); + // List of return results that correspond only to calls that returned + const returnResults = received.mock.results.filter( + result => result.type === 'return', + ); const count = returnResults.length; const pass = count === expected; @@ -214,10 +214,9 @@ const createToReturnWithMatcher = matcherName => ( ? 'mock function' : `mock function "${receivedName}"`; - // List of return values that correspond only to calls that did not throw - // an error + // List of return values that correspond only to calls that returned const returnValues = received.mock.results - .filter(result => !result.isThrow) + .filter(result => result.type === 'return') .map(result => result.value); const [match] = partition(returnValues, value => @@ -295,7 +294,7 @@ const createLastReturnedMatcher = matcherName => ( const lastResult = results[results.length - 1]; const pass = !!lastResult && - !lastResult.isThrow && + lastResult.type === 'return' && equals(lastResult.value, expected, [iterableEquality]); const message = pass @@ -313,11 +312,13 @@ const createLastReturnedMatcher = matcherName => ( ` ${printExpected(expected)}\n` + (!lastResult ? `But it was ${RECEIVED_COLOR('not called')}` - : lastResult.isThrow - ? `But the last call ${RECEIVED_COLOR('threw an error')}` - : `But the last call returned:\n ${printReceived( - lastResult.value, - )}`); + : lastResult.type === 'incomplete' + ? `But the last call ${RECEIVED_COLOR('has not returned yet')}` + : lastResult.type === 'throw' + ? `But the last call ${RECEIVED_COLOR('threw an error')}` + : `But the last call returned:\n ${printReceived( + lastResult.value, + )}`); return {message, pass}; }; @@ -400,7 +401,7 @@ const createNthReturnedWithMatcher = (matcherName: string) => ( const nthResult = results[nth - 1]; const pass = !!nthResult && - !nthResult.isThrow && + nthResult.type === 'return' && equals(nthResult.value, expected, [iterableEquality]); const nthString = nthToString(nth); const message = pass @@ -420,11 +421,17 @@ const createNthReturnedWithMatcher = (matcherName: string) => ( ? `But it was ${RECEIVED_COLOR('not called')}` : nth > results.length ? `But it was only called ${printReceived(results.length)} times` - : nthResult.isThrow - ? `But the ${nthString} call ${RECEIVED_COLOR('threw an error')}` - : `But the ${nthString} call returned with:\n ${printReceived( - nthResult.value, - )}`); + : nthResult.type === 'incomplete' + ? `But the ${nthString} call ${RECEIVED_COLOR( + 'has not returned yet', + )}` + : nthResult.type === 'throw' + ? `But the ${nthString} call ${RECEIVED_COLOR( + 'threw an error', + )}` + : `But the ${nthString} call returned with:\n ${printReceived( + nthResult.value, + )}`); return {message, pass}; }; diff --git a/packages/jest-mock/src/__tests__/jest_mock.test.js b/packages/jest-mock/src/__tests__/jest_mock.test.js index 5b440f0728d5..1e678adb12d9 100644 --- a/packages/jest-mock/src/__tests__/jest_mock.test.js +++ b/packages/jest-mock/src/__tests__/jest_mock.test.js @@ -579,11 +579,11 @@ describe('moduleMocker', () => { expect(fn.mock.results).toEqual([ { - isThrow: false, + type: 'return', value: 2, }, { - isThrow: false, + type: 'return', value: 4, }, ]); @@ -598,11 +598,11 @@ describe('moduleMocker', () => { expect(fn.mock.results).toEqual([ { - isThrow: false, + type: 'return', value: 'MOCKED!', }, { - isThrow: false, + type: 'return', value: 4, }, ]); @@ -618,11 +618,11 @@ describe('moduleMocker', () => { expect(fn.mock.results).toEqual([ { - isThrow: false, + type: 'return', value: 2, }, { - isThrow: false, + type: 'return', value: 4, }, ]); @@ -662,15 +662,15 @@ describe('moduleMocker', () => { // Results are tracked expect(fn.mock.results).toEqual([ { - isThrow: false, + type: 'return', value: 8, }, { - isThrow: true, + type: 'throw', value: error, }, { - isThrow: false, + type: 'return', value: 18, }, ]); @@ -693,12 +693,130 @@ describe('moduleMocker', () => { // Results are tracked expect(fn.mock.results).toEqual([ { - isThrow: true, + type: 'throw', value: undefined, }, ]); }); + it('results of recursive calls are tracked properly', () => { + // sums up all integers from 0 -> value, using recursion + const fn = moduleMocker.fn(value => { + if (value === 0) { + return 0; + } else { + return value + fn(value - 1); + } + }); + + fn(4); + + // All call args tracked + expect(fn.mock.calls).toEqual([[4], [3], [2], [1], [0]]); + // Results are tracked + // (in correct order of calls, rather than order of returns) + expect(fn.mock.results).toEqual([ + { + type: 'return', + value: 10, + }, + { + type: 'return', + value: 6, + }, + { + type: 'return', + value: 3, + }, + { + type: 'return', + value: 1, + }, + { + type: 'return', + value: 0, + }, + ]); + }); + + it('test results of recursive calls from within the recursive call', () => { + // sums up all integers from 0 -> value, using recursion + const fn = moduleMocker.fn(value => { + if (value === 0) { + return 0; + } else { + const recursiveResult = fn(value - 1); + + if (value === 3) { + // All recursive calls have been made at this point. + expect(fn.mock.calls).toEqual([[4], [3], [2], [1], [0]]); + // But only the last 3 calls have returned at this point. + expect(fn.mock.results).toEqual([ + { + type: 'incomplete', + value: undefined, + }, + { + type: 'incomplete', + value: undefined, + }, + { + type: 'return', + value: 3, + }, + { + type: 'return', + value: 1, + }, + { + type: 'return', + value: 0, + }, + ]); + } + + return value + recursiveResult; + } + }); + + fn(4); + }); + + it('call mockClear inside recursive mock', () => { + // sums up all integers from 0 -> value, using recursion + const fn = moduleMocker.fn(value => { + if (value === 3) { + fn.mockClear(); + } + + if (value === 0) { + return 0; + } else { + return value + fn(value - 1); + } + }); + + fn(3); + + // All call args (after the call that cleared the mock) are tracked + expect(fn.mock.calls).toEqual([[2], [1], [0]]); + // Results (after the call that cleared the mock) are tracked + expect(fn.mock.results).toEqual([ + { + type: 'return', + value: 3, + }, + { + type: 'return', + value: 1, + }, + { + type: 'return', + value: 0, + }, + ]); + }); + describe('invocationCallOrder', () => { it('tracks invocationCallOrder made by mocks', () => { const fn1 = moduleMocker.fn(); diff --git a/packages/jest-mock/src/index.js b/packages/jest-mock/src/index.js index 4bde745a3c25..b3c901ecf64e 100644 --- a/packages/jest-mock/src/index.js +++ b/packages/jest-mock/src/index.js @@ -21,17 +21,27 @@ export type MockFunctionMetadata = { length?: number, }; +/** + * Possible types of a MockFunctionResult. + * 'return': The call completed by returning normally. + * 'throw': The call completed by throwing a value. + * 'incomplete': The call has not completed yet. This is possible if you read + * the mock function result from within the mock function itself + * (or a function called by the mock function). + */ +type MockFunctionResultType = 'return' | 'throw' | 'incomplete'; + /** * Represents the result of a single call to a mock function. */ type MockFunctionResult = { /** - * True if the function threw. - * False if the function returned. + * Indicates how the call completed. */ - isThrow: boolean, + type: MockFunctionResultType, /** * The value that was either thrown or returned by the function. + * Undefined when type === 'incomplete'. */ value: any, }; @@ -379,6 +389,15 @@ class ModuleMockerClass { const mockConfig = mocker._ensureMockConfig(f); mockState.instances.push(this); mockState.calls.push(Array.prototype.slice.call(arguments)); + // Create and record an "incomplete" mock result immediately upon + // calling rather than waiting for the mock to return. This avoids + // issues caused by recursion where results can be recorded in the + // wrong order. + const mockResult = { + type: 'incomplete', + value: undefined, + }; + mockState.results.push(mockResult); mockState.invocationCallOrder.push(mocker._invocationCallCounter++); // Will be set to the return value of the mock if an error is not thrown @@ -457,11 +476,12 @@ class ModuleMockerClass { callDidThrowError = true; throw error; } finally { - // Record the result of the function - mockState.results.push({ - isThrow: callDidThrowError, - value: callDidThrowError ? thrownError : finalReturnValue, - }); + // Record the result of the function. + // NOTE: Intentionally NOT pushing/indexing into the array of mock + // results here to avoid corrupting results data if mockClear() + // is called during the execution of the mock. + mockResult.type = callDidThrowError ? 'throw' : 'return'; + mockResult.value = callDidThrowError ? thrownError : finalReturnValue; } return finalReturnValue; diff --git a/packages/jest-snapshot/src/__tests__/__snapshots__/mock_serializer.test.js.snap b/packages/jest-snapshot/src/__tests__/__snapshots__/mock_serializer.test.js.snap index 95477e6fff5c..f1fa6c9bd478 100644 --- a/packages/jest-snapshot/src/__tests__/__snapshots__/mock_serializer.test.js.snap +++ b/packages/jest-snapshot/src/__tests__/__snapshots__/mock_serializer.test.js.snap @@ -24,7 +24,7 @@ Object { ], "results": Array [ Object { - "isThrow": false, + "type": "return", "value": undefined, }, ], @@ -43,7 +43,7 @@ exports[`mock with 1 calls in React element 1`] = ` ], "results": Array [ Object { - "isThrow": false, + "type": "return", "value": undefined, }, ], @@ -67,11 +67,11 @@ exports[`mock with 2 calls 1`] = ` ], "results": Array [ Object { - "isThrow": false, + "type": "return", "value": undefined, }, Object { - "isThrow": false, + "type": "return", "value": undefined, }, ], @@ -90,11 +90,11 @@ exports[`mock with 2 calls, 1 return, 1 throw 1`] = ` ], "results": Array [ Object { - "isThrow": false, + "type": "return", "value": 4, }, Object { - "isThrow": true, + "type": "throw", "value": [Error: Error Message!], }, ], diff --git a/packages/jest-snapshot/src/__tests__/mock_serializer.test.js b/packages/jest-snapshot/src/__tests__/mock_serializer.test.js index 986cff352f01..a2ff554e6548 100644 --- a/packages/jest-snapshot/src/__tests__/mock_serializer.test.js +++ b/packages/jest-snapshot/src/__tests__/mock_serializer.test.js @@ -101,7 +101,7 @@ test('indent option', () => { '],', '"results": Array [', 'Object {', - '"isThrow": false,', + '"type": "return",', '"value": Object {', '"key": "value",', '},', @@ -116,7 +116,7 @@ test('min option', () => { const fn = jest.fn(val => val); fn({key: 'value'}); const expected = - '[MockFunction] {"calls": [[{"key": "value"}]], "results": [{"isThrow": false, "value": {"key": "value"}}]}'; + '[MockFunction] {"calls": [[{"key": "value"}]], "results": [{"type": "return", "value": {"key": "value"}}]}'; expect(prettyFormat(fn, {min: true, plugins: [plugin]})).toBe(expected); }); @@ -150,7 +150,7 @@ test('maxDepth option', () => { ' ],', ' "results": Array [', // ++depth === 2 ' Object {', // ++depth === 3 - ' "isThrow": false,', + ' "type": "return",', ' "value": undefined,', ' },', ' ],', From 29ae86820eb0e53ef48a57cafac0fe50b2160c86 Mon Sep 17 00:00:00 2001 From: Andrea Rosales Date: Thu, 1 Nov 2018 02:23:51 -0500 Subject: [PATCH 23/45] Update naming convention in jest-watcher (#7315) ## Summary This is part of #4969. It standardizes file names in packages/jest-watcher under Facebook naming conventions. ## Test plan Running `yarn run clean-all` followed by `yarn` and `yarn test` is not completely clean on my machine, but it yields the same results in this branch and `master` --- CHANGELOG.md | 1 + .../src/{base_watch_plugin.js => BaseWatchPlugin.js} | 0 packages/jest-watcher/src/{jest_hooks.js => JestHooks.js} | 0 .../src/{pattern_prompt.js => PatternPrompt.js} | 0 packages/jest-watcher/src/index.js | 8 ++++---- ....test.js.snap => formatTestNameByPattern.test.js.snap} | 0 ...by_pattern.test.js => formatTestNameByPattern.test.js} | 2 +- .../lib/__tests__/{scroll_list.test.js => scroll.test.js} | 2 +- ...test_name_by_pattern.js => formatTestNameByPattern.js} | 0 .../{pattern_mode_helpers.js => patternModeHelpers.js} | 0 .../jest-watcher/src/lib/{scroll_list.js => scroll.js} | 0 11 files changed, 7 insertions(+), 6 deletions(-) rename packages/jest-watcher/src/{base_watch_plugin.js => BaseWatchPlugin.js} (100%) rename packages/jest-watcher/src/{jest_hooks.js => JestHooks.js} (100%) rename packages/jest-watcher/src/{pattern_prompt.js => PatternPrompt.js} (100%) rename packages/jest-watcher/src/lib/__tests__/__snapshots__/{format_test_name_by_pattern.test.js.snap => formatTestNameByPattern.test.js.snap} (100%) rename packages/jest-watcher/src/lib/__tests__/{format_test_name_by_pattern.test.js => formatTestNameByPattern.test.js} (97%) rename packages/jest-watcher/src/lib/__tests__/{scroll_list.test.js => scroll.test.js} (97%) rename packages/jest-watcher/src/lib/{format_test_name_by_pattern.js => formatTestNameByPattern.js} (100%) rename packages/jest-watcher/src/lib/{pattern_mode_helpers.js => patternModeHelpers.js} (100%) rename packages/jest-watcher/src/lib/{scroll_list.js => scroll.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a0b85b5fb40..e62cd0e6a7e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ ### Chore & Maintenance +- `[jest-watcher]` Standardize filenames ([#7314](https://github.com/facebook/jest/pull/7314)) - `[jest-circus]` Standardize file naming in `jest-circus` ([#7301](https://github.com/facebook/jest/pull/7301)) - `[docs]` Add synchronous test.each setup ([#7150](https://github.com/facebook/jest/pull/7150)) - `[docs]` Add `this.extend` to the Custom Matchers API reference ([#7130](https://github.com/facebook/jest/pull/7130)) diff --git a/packages/jest-watcher/src/base_watch_plugin.js b/packages/jest-watcher/src/BaseWatchPlugin.js similarity index 100% rename from packages/jest-watcher/src/base_watch_plugin.js rename to packages/jest-watcher/src/BaseWatchPlugin.js diff --git a/packages/jest-watcher/src/jest_hooks.js b/packages/jest-watcher/src/JestHooks.js similarity index 100% rename from packages/jest-watcher/src/jest_hooks.js rename to packages/jest-watcher/src/JestHooks.js diff --git a/packages/jest-watcher/src/pattern_prompt.js b/packages/jest-watcher/src/PatternPrompt.js similarity index 100% rename from packages/jest-watcher/src/pattern_prompt.js rename to packages/jest-watcher/src/PatternPrompt.js diff --git a/packages/jest-watcher/src/index.js b/packages/jest-watcher/src/index.js index fbe13be62b2c..ec145efba3bd 100644 --- a/packages/jest-watcher/src/index.js +++ b/packages/jest-watcher/src/index.js @@ -7,9 +7,9 @@ * @flow */ -export {default as BaseWatchPlugin} from './base_watch_plugin'; -export {default as JestHook} from './jest_hooks'; -export {default as PatternPrompt} from './pattern_prompt'; +export {default as BaseWatchPlugin} from './BaseWatchPlugin'; +export {default as JestHook} from './JestHooks'; +export {default as PatternPrompt} from './PatternPrompt'; export * from './constants'; export {default as Prompt} from './lib/Prompt'; -export * from './lib/pattern_mode_helpers'; +export * from './lib/patternModeHelpers'; diff --git a/packages/jest-watcher/src/lib/__tests__/__snapshots__/format_test_name_by_pattern.test.js.snap b/packages/jest-watcher/src/lib/__tests__/__snapshots__/formatTestNameByPattern.test.js.snap similarity index 100% rename from packages/jest-watcher/src/lib/__tests__/__snapshots__/format_test_name_by_pattern.test.js.snap rename to packages/jest-watcher/src/lib/__tests__/__snapshots__/formatTestNameByPattern.test.js.snap diff --git a/packages/jest-watcher/src/lib/__tests__/format_test_name_by_pattern.test.js b/packages/jest-watcher/src/lib/__tests__/formatTestNameByPattern.test.js similarity index 97% rename from packages/jest-watcher/src/lib/__tests__/format_test_name_by_pattern.test.js rename to packages/jest-watcher/src/lib/__tests__/formatTestNameByPattern.test.js index 08b688f77aae..16bea7d02681 100644 --- a/packages/jest-watcher/src/lib/__tests__/format_test_name_by_pattern.test.js +++ b/packages/jest-watcher/src/lib/__tests__/formatTestNameByPattern.test.js @@ -9,7 +9,7 @@ 'use strict'; -import formatTestNameByPattern from '../format_test_name_by_pattern'; +import formatTestNameByPattern from '../formatTestNameByPattern'; describe('for multiline test name returns', () => { const testNames = [ diff --git a/packages/jest-watcher/src/lib/__tests__/scroll_list.test.js b/packages/jest-watcher/src/lib/__tests__/scroll.test.js similarity index 97% rename from packages/jest-watcher/src/lib/__tests__/scroll_list.test.js rename to packages/jest-watcher/src/lib/__tests__/scroll.test.js index c63a357cb3f6..171e5c98b03e 100644 --- a/packages/jest-watcher/src/lib/__tests__/scroll_list.test.js +++ b/packages/jest-watcher/src/lib/__tests__/scroll.test.js @@ -1,6 +1,6 @@ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -import scroll from '../scroll_list'; +import scroll from '../scroll'; it('When offset is -1', () => { expect(scroll(25, {max: 10, offset: -1})).toEqual({ diff --git a/packages/jest-watcher/src/lib/format_test_name_by_pattern.js b/packages/jest-watcher/src/lib/formatTestNameByPattern.js similarity index 100% rename from packages/jest-watcher/src/lib/format_test_name_by_pattern.js rename to packages/jest-watcher/src/lib/formatTestNameByPattern.js diff --git a/packages/jest-watcher/src/lib/pattern_mode_helpers.js b/packages/jest-watcher/src/lib/patternModeHelpers.js similarity index 100% rename from packages/jest-watcher/src/lib/pattern_mode_helpers.js rename to packages/jest-watcher/src/lib/patternModeHelpers.js diff --git a/packages/jest-watcher/src/lib/scroll_list.js b/packages/jest-watcher/src/lib/scroll.js similarity index 100% rename from packages/jest-watcher/src/lib/scroll_list.js rename to packages/jest-watcher/src/lib/scroll.js From f9fd98fd4e38978e96a86f1c8796593cad7ac470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 1 Nov 2018 09:23:51 +0100 Subject: [PATCH 24/45] fix: unable to resolve path to mapped file with custom platform (#7312) --- CHANGELOG.md | 3 ++- .../__snapshots__/module_name_mapper.test.js.snap | 2 +- e2e/resolve/__tests__/resolve.test.js | 5 +++++ e2e/resolve/package.json | 9 +++++++-- e2e/resolve/test2mapper.js | 8 ++++++++ e2e/resolve/test2mapper.native.js | 8 ++++++++ .../jest-resolve/src/__tests__/resolve.test.js | 1 + packages/jest-resolve/src/index.js | 15 ++++++++++++++- 8 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 e2e/resolve/test2mapper.js create mode 100644 e2e/resolve/test2mapper.native.js diff --git a/CHANGELOG.md b/CHANGELOG.md index e62cd0e6a7e7..1385882907c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,7 +61,8 @@ - `[jest-config]` Use strings instead of `RegExp` instances in normalized configuration ([#7251](https://github.com/facebook/jest/pull/7251)) - `[jest-circus]` Make sure to display real duration even if time is mocked ([#7264](https://github.com/facebook/jest/pull/7264)) - `[expect]` Improves the failing message for `toStrictEqual` matcher. ([#7224](https://github.com/facebook/jest/pull/7224)) -- `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381) +- `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381)) +- `[jest-resolve]` Fix not being able to resolve path to mapped file with custom platform ([#7312](https://github.com/facebook/jest/pull/7312)) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/module_name_mapper.test.js.snap b/e2e/__tests__/__snapshots__/module_name_mapper.test.js.snap index 9f692951261f..0f917a0aad15 100644 --- a/e2e/__tests__/__snapshots__/module_name_mapper.test.js.snap +++ b/e2e/__tests__/__snapshots__/module_name_mapper.test.js.snap @@ -32,7 +32,7 @@ exports[`moduleNameMapper wrong configuration 1`] = ` 12 | module.exports = () => 'test'; 13 | - at packages/jest-resolve/build/index.js:410:17 + at packages/jest-resolve/build/index.js:429:17 at index.js:10:1 " diff --git a/e2e/resolve/__tests__/resolve.test.js b/e2e/resolve/__tests__/resolve.test.js index 41a840c2d56d..e8a5571f59ef 100644 --- a/e2e/resolve/__tests__/resolve.test.js +++ b/e2e/resolve/__tests__/resolve.test.js @@ -47,6 +47,11 @@ test('should resolve filename.native.js', () => { expect(platform.extension).toBe('native.js'); }); +test('should resolve filename.native.js with moduleNameMapper', () => { + expect(testRequire('test2mapper')).not.toThrow(); + expect(platform.extension).toBe('native.js'); +}); + test('should resolve filename.js', () => { expect(testRequire('../test3')).not.toThrow(); expect(platform.extension).toBe('js'); diff --git a/e2e/resolve/package.json b/e2e/resolve/package.json index 743e0a83f202..f3feb16b420f 100644 --- a/e2e/resolve/package.json +++ b/e2e/resolve/package.json @@ -2,9 +2,14 @@ "name": "custom-resolve", "jest": { "haste": { - "platforms": ["native"], + "platforms": [ + "native" + ], "defaultPlatform": "android" }, - "testEnvironment": "node" + "testEnvironment": "node", + "moduleNameMapper": { + "test2mapper": "/test2mapper" + } } } diff --git a/e2e/resolve/test2mapper.js b/e2e/resolve/test2mapper.js new file mode 100644 index 000000000000..a265d4b021c8 --- /dev/null +++ b/e2e/resolve/test2mapper.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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 = {extension: '.js'}; diff --git a/e2e/resolve/test2mapper.native.js b/e2e/resolve/test2mapper.native.js new file mode 100644 index 000000000000..68a290a4b715 --- /dev/null +++ b/e2e/resolve/test2mapper.native.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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 = {extension: 'native.js'}; diff --git a/packages/jest-resolve/src/__tests__/resolve.test.js b/packages/jest-resolve/src/__tests__/resolve.test.js index f4c75c4e6927..8d3b91d9bfb9 100644 --- a/packages/jest-resolve/src/__tests__/resolve.test.js +++ b/packages/jest-resolve/src/__tests__/resolve.test.js @@ -161,6 +161,7 @@ describe('getMockModule', () => { const moduleMap = ModuleMap.create('/'); const resolver = new Resolver(moduleMap, { + extensions: ['.js'], moduleNameMapper: [ { moduleName: '$1', diff --git a/packages/jest-resolve/src/index.js b/packages/jest-resolve/src/index.js index 7ad9ea1e960d..cf3ba0d85093 100644 --- a/packages/jest-resolve/src/index.js +++ b/packages/jest-resolve/src/index.js @@ -341,10 +341,23 @@ class Resolver { _resolveStubModuleName(from: Path, moduleName: string): ?Path { const dirname = path.dirname(from); const paths = this._options.modulePaths; - const extensions = this._options.extensions; + const extensions = this._options.extensions.slice(); const moduleDirectory = this._options.moduleDirectories; const moduleNameMapper = this._options.moduleNameMapper; const resolver = this._options.resolver; + const defaultPlatform = this._options.defaultPlatform; + + if (this._supportsNativePlatform) { + extensions.unshift( + ...this._options.extensions.map(ext => '.' + NATIVE_PLATFORM + ext), + ); + } + + if (defaultPlatform) { + extensions.unshift( + ...this._options.extensions.map(ext => '.' + defaultPlatform + ext), + ); + } if (moduleNameMapper) { for (const {moduleName: mappedModuleName, regex} of moduleNameMapper) { From 223c3dbc4b2c4a48ff3b3b840b550e874906b9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 1 Nov 2018 11:37:31 -0700 Subject: [PATCH 25/45] Add support for custom dependency extractors (#7313) --- CHANGELOG.md | 1 + docs/Configuration.md | 8 ++++ .../__snapshots__/show_config.test.js.snap | 1 + e2e/__tests__/find_related_files.test.js | 40 +++++++++++++++++++ jest.config.js | 1 + .../__tests__/__snapshots__/init.test.js.snap | 3 ++ packages/jest-config/src/Defaults.js | 1 + packages/jest-config/src/Descriptions.js | 1 + packages/jest-config/src/ValidConfig.js | 1 + packages/jest-config/src/index.js | 1 + packages/jest-config/src/normalize.js | 1 + .../src/__tests__/dependencyExtractor.js | 31 ++++++++++++++ .../src/__tests__/index.test.js | 8 ++++ .../src/__tests__/worker.test.js | 16 +++++++- packages/jest-haste-map/src/index.js | 5 +++ .../src/lib/__tests__/extractRequires.test.js | 30 ++++++++------ .../jest-haste-map/src/lib/extractRequires.js | 4 +- packages/jest-haste-map/src/types.js | 1 + packages/jest-haste-map/src/worker.js | 8 +++- packages/jest-runtime/src/index.js | 1 + types/Config.js | 3 ++ 21 files changed, 149 insertions(+), 17 deletions(-) create mode 100644 packages/jest-haste-map/src/__tests__/dependencyExtractor.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 1385882907c5..4a9eeb537f3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203)) - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) +- `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313)) ### Fixes diff --git a/docs/Configuration.md b/docs/Configuration.md index 35bddeccbdf6..8035bb5c8278 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -257,6 +257,14 @@ Jest will fail if: - The `./src/api/very-important-module.js` file has less than 100% coverage. - Every remaining file combined has less than 50% coverage (`global`). +### `dependencyExtractor` [string] + +Default: `undefined` + +This option allows the use of a custom dependency extractor. It must be a node module that exports a function expecting a string as the first argument for the code to analyze and Jest's dependency extractor as the second argument (in case you only want to extend it). + +The function should return an iterable (`Array`, `Set`, etc.) with the dependencies found in the code. + ### `errorOnDeprecated` [boolean] Default: `false` diff --git a/e2e/__tests__/__snapshots__/show_config.test.js.snap b/e2e/__tests__/__snapshots__/show_config.test.js.snap index f3982dde87f3..cf77d55b5751 100644 --- a/e2e/__tests__/__snapshots__/show_config.test.js.snap +++ b/e2e/__tests__/__snapshots__/show_config.test.js.snap @@ -13,6 +13,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` \\"/node_modules/\\" ], \\"cwd\\": \\"<>\\", + \\"dependencyExtractor\\": null, \\"detectLeaks\\": false, \\"detectOpenHandles\\": false, \\"errorOnDeprecated\\": false, diff --git a/e2e/__tests__/find_related_files.test.js b/e2e/__tests__/find_related_files.test.js index 2024e1dd97e5..f7ba19cf16bf 100644 --- a/e2e/__tests__/find_related_files.test.js +++ b/e2e/__tests__/find_related_files.test.js @@ -41,6 +41,46 @@ describe('--findRelatedTests flag', () => { expect(stderr).toMatch(summaryMsg); }); + test('runs tests related to filename with a custom dependency extractor', () => { + writeFiles(DIR, { + '.watchmanconfig': '', + '__tests__/test.test.js': ` + const dynamicImport = path => Promise.resolve(require(path)); + test('a', () => dynamicImport('../a').then(a => { + expect(a.foo).toBe(5); + })); + `, + 'a.js': 'module.exports = {foo: 5};', + 'dependencyExtractor.js': ` + const DYNAMIC_IMPORT_RE = /(?:^|[^.]\\s*)(\\bdynamicImport\\s*?\\(\\s*?)([\`'"])([^\`'"]+)(\\2\\s*?\\))/g; + module.exports = function dependencyExtractor(code) { + const dependencies = new Set(); + const addDependency = (match, pre, quot, dep, post) => { + dependencies.add(dep); + return match; + }; + code.replace(DYNAMIC_IMPORT_RE, addDependency); + return dependencies; + }; + `, + 'package.json': JSON.stringify({ + jest: { + dependencyExtractor: '/dependencyExtractor.js', + testEnvironment: 'node', + }, + }), + }); + + const {stdout} = runJest(DIR, ['a.js']); + expect(stdout).toMatch(''); + + const {stderr} = runJest(DIR, ['--findRelatedTests', 'a.js']); + expect(stderr).toMatch('PASS __tests__/test.test.js'); + + const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; + expect(stderr).toMatch(summaryMsg); + }); + test('generates coverage report for filename', () => { writeFiles(DIR, { '.watchmanconfig': '', diff --git a/jest.config.js b/jest.config.js index 06cb6ca2e84c..9c16175c878b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -40,6 +40,7 @@ module.exports = { '/packages/jest-cli/src/__tests__/__fixtures__/', '/packages/jest-cli/src/lib/__tests__/fixtures/', '/packages/jest-haste-map/src/__tests__/haste_impl.js', + '/packages/jest-haste-map/src/__tests__/dependencyExtractor.js', '/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/', '/packages/jest-runtime/src/__tests__/defaultResolver.js', '/packages/jest-runtime/src/__tests__/module_dir/', diff --git a/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap index 8f49360f6ebc..d0b63fa1c18a 100644 --- a/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap @@ -63,6 +63,9 @@ module.exports = { // An object that configures minimum threshold enforcement for coverage results // coverageThreshold: null, + // A path to a custom dependency extractor + // dependencyExtractor: null, + // Make calling deprecated APIs throw helpful error messages // errorOnDeprecated: false, diff --git a/packages/jest-config/src/Defaults.js b/packages/jest-config/src/Defaults.js index b6aafa6e13ad..ea40b3cf4e05 100644 --- a/packages/jest-config/src/Defaults.js +++ b/packages/jest-config/src/Defaults.js @@ -30,6 +30,7 @@ export default ({ coverageReporters: ['json', 'text', 'lcov', 'clover'], coverageThreshold: null, cwd: process.cwd(), + dependencyExtractor: null, detectLeaks: false, detectOpenHandles: false, errorOnDeprecated: false, diff --git a/packages/jest-config/src/Descriptions.js b/packages/jest-config/src/Descriptions.js index 48c3b2d321ad..6ff881d1501d 100644 --- a/packages/jest-config/src/Descriptions.js +++ b/packages/jest-config/src/Descriptions.js @@ -26,6 +26,7 @@ export default ({ 'A list of reporter names that Jest uses when writing coverage reports', coverageThreshold: 'An object that configures minimum threshold enforcement for coverage results', + dependencyExtractor: 'A path to a custom dependency extractor', errorOnDeprecated: 'Make calling deprecated APIs throw helpful error messages', forceCoverageMatch: diff --git a/packages/jest-config/src/ValidConfig.js b/packages/jest-config/src/ValidConfig.js index cb732dc76555..2d2d4128bc48 100644 --- a/packages/jest-config/src/ValidConfig.js +++ b/packages/jest-config/src/ValidConfig.js @@ -40,6 +40,7 @@ export default ({ statements: 100, }, }, + dependencyExtractor: '/dependencyExtractor.js', displayName: 'project-name', errorOnDeprecated: false, expand: false, diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index ec6a856c75f0..b1832b94af6a 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -160,6 +160,7 @@ const groupOptions = ( clearMocks: options.clearMocks, coveragePathIgnorePatterns: options.coveragePathIgnorePatterns, cwd: options.cwd, + dependencyExtractor: options.dependencyExtractor, detectLeaks: options.detectLeaks, detectOpenHandles: options.detectOpenHandles, displayName: options.displayName, diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index fc04dd34deec..ef6886ce2a3b 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -483,6 +483,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { replaceRootDirInPath(options.rootDir, options[key]), ); break; + case 'dependencyExtractor': case 'globalSetup': case 'globalTeardown': case 'moduleLoader': diff --git a/packages/jest-haste-map/src/__tests__/dependencyExtractor.js b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js new file mode 100644 index 000000000000..3e872ae3227e --- /dev/null +++ b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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 blockCommentRe = /\/\*[^]*?\*\//g; +const lineCommentRe = /\/\/.*/g; +const LOAD_MODULE_RE = /(?:^|[^.]\s*)(\bloadModule\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g; + +module.exports = function dependencyExtractor( + code, + defaultDependencyExtractor, +) { + const dependencies = defaultDependencyExtractor(code); + + const addDependency = (match, pre, quot, dep, post) => { + dependencies.add(dep); + return match; + }; + + code + .replace(blockCommentRe, '') + .replace(lineCommentRe, '') + .replace(LOAD_MODULE_RE, addDependency); + + return dependencies; +}; diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index df716c9f0c09..3b1a49f37626 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -885,8 +885,11 @@ describe('HasteMap', () => { it('distributes work across workers', () => { const jestWorker = require('jest-worker'); + const path = require('path'); + const dependencyExtractor = path.join(__dirname, 'dependencyExtractor.js'); return new HasteMap( Object.assign({}, defaultConfig, { + dependencyExtractor, hasteImplModulePath: undefined, maxWorkers: 4, }), @@ -902,6 +905,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, + dependencyExtractor, filePath: '/project/fruits/Banana.js', hasteImplModulePath: undefined, rootDir: '/project', @@ -911,6 +915,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, + dependencyExtractor, filePath: '/project/fruits/Pear.js', hasteImplModulePath: undefined, rootDir: '/project', @@ -920,6 +925,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, + dependencyExtractor, filePath: '/project/fruits/Strawberry.js', hasteImplModulePath: undefined, rootDir: '/project', @@ -929,6 +935,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, + dependencyExtractor, filePath: '/project/fruits/__mocks__/Pear.js', hasteImplModulePath: undefined, rootDir: '/project', @@ -938,6 +945,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, + dependencyExtractor, filePath: '/project/vegetables/Melon.js', hasteImplModulePath: undefined, rootDir: '/project', diff --git a/packages/jest-haste-map/src/__tests__/worker.test.js b/packages/jest-haste-map/src/__tests__/worker.test.js index 426502dd3d92..3c044a3668c3 100644 --- a/packages/jest-haste-map/src/__tests__/worker.test.js +++ b/packages/jest-haste-map/src/__tests__/worker.test.js @@ -32,6 +32,7 @@ describe('worker', () => { '/project/fruits/Pear.js': ` const Banana = require("Banana"); const Strawberry = require('Strawberry'); + const Lime = loadModule('Lime'); `, '/project/fruits/Strawberry.js': ` // Strawberry! @@ -95,6 +96,19 @@ describe('worker', () => { }); }); + it('accepts a custom dependency extractor', async () => { + expect( + await worker({ + computeDependencies: true, + dependencyExtractor: path.join(__dirname, 'dependencyExtractor.js'), + filePath: '/project/fruits/Pear.js', + rootDir, + }), + ).toEqual({ + dependencies: ['Banana', 'Strawberry', 'Lime'], + }); + }); + it('delegates to hasteImplModulePath for getting the id', async () => { expect( await worker({ @@ -179,7 +193,7 @@ describe('worker', () => { filePath: '/project/fruits/Pear.js', rootDir, }), - ).toEqual({sha1: '0cb0930919e068f146da84d9a0ad0182e4bdb673'}); + ).toEqual({sha1: 'c7a7a68a1c8aaf452669dd2ca52ac4a434d25552'}); await expect( getSha1({computeSha1: true, filePath: '/i/dont/exist.js', rootDir}), diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index f7acf0cbfee4..fabadb3b33ee 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -52,6 +52,7 @@ type Options = { computeDependencies?: boolean, computeSha1?: boolean, console?: Console, + dependencyExtractor?: string, extensions: Array, forceNodeFilesystemAPI?: boolean, hasteImplModulePath?: string, @@ -75,6 +76,7 @@ type InternalOptions = { cacheDirectory: string, computeDependencies: boolean, computeSha1: boolean, + dependencyExtractor?: string, extensions: Array, forceNodeFilesystemAPI: boolean, hasteImplModulePath?: string, @@ -233,6 +235,7 @@ class HasteMap extends EventEmitter { ? true : options.computeDependencies, computeSha1: options.computeSha1 || false, + dependencyExtractor: options.dependencyExtractor, extensions: options.extensions, forceNodeFilesystemAPI: !!options.forceNodeFilesystemAPI, hasteImplModulePath: options.hasteImplModulePath, @@ -504,6 +507,7 @@ class HasteMap extends EventEmitter { .getSha1({ computeDependencies: this._options.computeDependencies, computeSha1, + dependencyExtractor: this._options.dependencyExtractor, filePath, hasteImplModulePath: this._options.hasteImplModulePath, rootDir, @@ -567,6 +571,7 @@ class HasteMap extends EventEmitter { .worker({ computeDependencies: this._options.computeDependencies, computeSha1, + dependencyExtractor: this._options.dependencyExtractor, filePath, hasteImplModulePath: this._options.hasteImplModulePath, rootDir, diff --git a/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js b/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js index a6172e0dcb8e..a349d083735e 100644 --- a/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js @@ -18,7 +18,9 @@ it('extracts both requires and imports from code', () => { import('module3').then(module3 => {})'; `; - expect(extractRequires(code)).toEqual(['module1', 'module2', 'module3']); + expect(extractRequires(code)).toEqual( + new Set(['module1', 'module2', 'module3']), + ); }); it('extracts requires in order', () => { @@ -28,13 +30,15 @@ it('extracts requires in order', () => { const module3 = require('module3'); `; - expect(extractRequires(code)).toEqual(['module1', 'module2', 'module3']); + expect(extractRequires(code)).toEqual( + new Set(['module1', 'module2', 'module3']), + ); }); it('strips out comments from code', () => { const code = `// comment const module2 = require('module2');`; - expect(extractRequires(code)).toEqual([]); + expect(extractRequires(code)).toEqual(new Set([])); }); it('ignores requires in comments', () => { @@ -45,7 +49,7 @@ it('ignores requires in comments', () => { ' */', ].join('\n'); - expect(extractRequires(code)).toEqual([]); + expect(extractRequires(code)).toEqual(new Set([])); }); it('ignores requires in comments with Windows line endings', () => { @@ -56,7 +60,7 @@ it('ignores requires in comments with Windows line endings', () => { ' */', ].join('\r\n'); - expect(extractRequires(code)).toEqual([]); + expect(extractRequires(code)).toEqual(new Set([])); }); it('ignores requires in comments with unicode line endings', () => { @@ -68,7 +72,7 @@ it('ignores requires in comments with unicode line endings', () => { ' */', ].join(''); - expect(extractRequires(code)).toEqual([]); + expect(extractRequires(code)).toEqual(new Set([])); }); it('does not contain duplicates', () => { @@ -77,7 +81,7 @@ it('does not contain duplicates', () => { const module1Dup = require('module1'); `; - expect(extractRequires(code)).toEqual(['module1']); + expect(extractRequires(code)).toEqual(new Set(['module1'])); }); it('ignores type imports', () => { @@ -89,7 +93,7 @@ it('ignores type imports', () => { "} from 'wham'", ].join('\r\n'); - expect(extractRequires(code)).toEqual([]); + expect(extractRequires(code)).toEqual(new Set([])); }); it('ignores type exports', () => { @@ -99,25 +103,25 @@ it('ignores type exports', () => { "export * from 'module1'", ].join('\r\n'); - expect(extractRequires(code)).toEqual(['module1']); + expect(extractRequires(code)).toEqual(new Set(['module1'])); }); it('understands require.requireActual', () => { const code = `require.requireActual('pizza');`; - expect(extractRequires(code)).toEqual(['pizza']); + expect(extractRequires(code)).toEqual(new Set(['pizza'])); }); it('understands jest.requireActual', () => { const code = `jest.requireActual('whiskey');`; - expect(extractRequires(code)).toEqual(['whiskey']); + expect(extractRequires(code)).toEqual(new Set(['whiskey'])); }); it('understands require.requireMock', () => { const code = `require.requireMock('cheeseburger');`; - expect(extractRequires(code)).toEqual(['cheeseburger']); + expect(extractRequires(code)).toEqual(new Set(['cheeseburger'])); }); it('understands jest.requireMock', () => { const code = `jest.requireMock('scotch');`; - expect(extractRequires(code)).toEqual(['scotch']); + expect(extractRequires(code)).toEqual(new Set(['scotch'])); }); diff --git a/packages/jest-haste-map/src/lib/extractRequires.js b/packages/jest-haste-map/src/lib/extractRequires.js index 7457f44b6236..dfdcece33a29 100644 --- a/packages/jest-haste-map/src/lib/extractRequires.js +++ b/packages/jest-haste-map/src/lib/extractRequires.js @@ -18,7 +18,7 @@ const replacePatterns = { REQUIRE_RE: /(?:^|[^.]\s*)(\brequire\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g, }; -export default function extractRequires(code: string): Array { +export default function extractRequires(code: string): Set { const dependencies = new Set(); const addDependency = (match, pre, quot, dep, post) => { dependencies.add(dep); @@ -34,5 +34,5 @@ export default function extractRequires(code: string): Array { .replace(replacePatterns.REQUIRE_RE, addDependency) .replace(replacePatterns.DYNAMIC_IMPORT_RE, addDependency); - return Array.from(dependencies); + return dependencies; } diff --git a/packages/jest-haste-map/src/types.js b/packages/jest-haste-map/src/types.js index caba081b9a9a..8ee12a279fb5 100644 --- a/packages/jest-haste-map/src/types.js +++ b/packages/jest-haste-map/src/types.js @@ -15,6 +15,7 @@ export type Mapper = (item: string) => ?Array; export type WorkerMessage = { computeDependencies: boolean, computeSha1: boolean, + dependencyExtractor?: string, rootDir: string, filePath: string, hasteImplModulePath?: string, diff --git a/packages/jest-haste-map/src/worker.js b/packages/jest-haste-map/src/worker.js index acf575098e8f..6096372a6aa2 100644 --- a/packages/jest-haste-map/src/worker.js +++ b/packages/jest-haste-map/src/worker.js @@ -77,7 +77,13 @@ export async function worker(data: WorkerMessage): Promise { } if (computeDependencies) { - dependencies = extractRequires(getContent()); + const content = getContent(); + dependencies = Array.from( + data.dependencyExtractor + ? // $FlowFixMe + require(data.dependencyExtractor)(content, extractRequires) + : extractRequires(content), + ); } if (id) { diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index a24ed1712fd3..f60b33b0dae6 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -237,6 +237,7 @@ class Runtime { return new HasteMap({ cacheDirectory: config.cacheDirectory, console: options && options.console, + dependencyExtractor: config.dependencyExtractor, extensions: [Snapshot.EXTENSION].concat(config.moduleFileExtensions), hasteImplModulePath: config.haste.hasteImplModulePath, ignorePattern, diff --git a/types/Config.js b/types/Config.js index c152976c0957..957cb3afeaab 100644 --- a/types/Config.js +++ b/types/Config.js @@ -36,6 +36,7 @@ export type DefaultOptions = {| coverageReporters: Array, coverageThreshold: ?{global: {[key: string]: number}}, cwd: Path, + dependencyExtractor: ?string, errorOnDeprecated: boolean, expand: boolean, filter: ?Path, @@ -104,6 +105,7 @@ export type InitialOptions = { coveragePathIgnorePatterns?: Array, coverageReporters?: Array, coverageThreshold?: {global: {[key: string]: number}}, + dependencyExtractor?: string, detectLeaks?: boolean, detectOpenHandles?: boolean, displayName?: string, @@ -249,6 +251,7 @@ export type ProjectConfig = {| clearMocks: boolean, coveragePathIgnorePatterns: Array, cwd: Path, + dependencyExtractor?: string, detectLeaks: boolean, detectOpenHandles: boolean, displayName: ?string, From dd6f79b66c7b9b90857d3a372c53df7f1b09d0c6 Mon Sep 17 00:00:00 2001 From: Kunio Ozawa Date: Fri, 2 Nov 2018 22:58:01 +0900 Subject: [PATCH 26/45] Update MongoDB.md (#7305) --- docs/MongoDB.md | 6 +++--- website/versioned_docs/version-22.3/MongoDB.md | 6 +++--- website/versioned_docs/version-23.0/MongoDB.md | 6 +++--- website/versioned_docs/version-23.2/MongoDB.md | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/MongoDB.md b/docs/MongoDB.md index 6d4fcbf88108..2950c2a9c604 100644 --- a/docs/MongoDB.md +++ b/docs/MongoDB.md @@ -26,7 +26,7 @@ const {MongoMemoryServer} = require('mongodb-memory-server'); const globalConfigPath = path.join(__dirname, 'globalConfig.json'); -const mongoServer = new MongoMemoryServer({ +const mongod = new MongoMemoryServer({ autoStart: false, }); @@ -37,14 +37,14 @@ module.exports = async () => { const mongoConfig = { mongoDBName: 'jest', - mongoUri: await mongoServer.getConnectionString(), + mongoUri: await mongod.getConnectionString(), }; // Write global config to disk because all tests run in different contexts. fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig)); // Set reference to mongod in order to close the server during teardown. - global.__MONGOD__ = mongoServer; + global.__MONGOD__ = mongod; }; ``` diff --git a/website/versioned_docs/version-22.3/MongoDB.md b/website/versioned_docs/version-22.3/MongoDB.md index edbbf86e44c3..3a9285891dd2 100644 --- a/website/versioned_docs/version-22.3/MongoDB.md +++ b/website/versioned_docs/version-22.3/MongoDB.md @@ -27,7 +27,7 @@ const {MongoMemoryServer} = require('mongodb-memory-server'); const globalConfigPath = path.join(__dirname, 'globalConfig.json'); -const mongoServer = new MongoMemoryServer({ +const mongod = new MongoMemoryServer({ autoStart: false, }); @@ -38,14 +38,14 @@ module.exports = async () => { const mongoConfig = { mongoDBName: 'jest', - mongoUri: await mongoServer.getConnectionString(), + mongoUri: await mongod.getConnectionString(), }; // Write global config to disk because all tests run in different contexts. fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig)); // Set reference to mongod in order to close the server during teardown. - global.__MONGOD__ = mongoServer; + global.__MONGOD__ = mongod; }; ``` diff --git a/website/versioned_docs/version-23.0/MongoDB.md b/website/versioned_docs/version-23.0/MongoDB.md index f12a6d257b31..c73ae02b0623 100644 --- a/website/versioned_docs/version-23.0/MongoDB.md +++ b/website/versioned_docs/version-23.0/MongoDB.md @@ -27,7 +27,7 @@ const {MongoMemoryServer} = require('mongodb-memory-server'); const globalConfigPath = path.join(__dirname, 'globalConfig.json'); -const mongoServer = new MongoMemoryServer({ +const mongod = new MongoMemoryServer({ autoStart: false, }); @@ -38,14 +38,14 @@ module.exports = async () => { const mongoConfig = { mongoDBName: 'jest', - mongoUri: await mongoServer.getConnectionString(), + mongoUri: await mongod.getConnectionString(), }; // Write global config to disk because all tests run in different contexts. fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig)); // Set reference to mongod in order to close the server during teardown. - global.__MONGOD__ = mongoServer; + global.__MONGOD__ = mongod; }; ``` diff --git a/website/versioned_docs/version-23.2/MongoDB.md b/website/versioned_docs/version-23.2/MongoDB.md index e229d0fa0798..a05fbe53a526 100644 --- a/website/versioned_docs/version-23.2/MongoDB.md +++ b/website/versioned_docs/version-23.2/MongoDB.md @@ -27,7 +27,7 @@ const {MongoMemoryServer} = require('mongodb-memory-server'); const globalConfigPath = path.join(__dirname, 'globalConfig.json'); -const mongoServer = new MongoMemoryServer({ +const mongod = new MongoMemoryServer({ autoStart: false, }); @@ -38,14 +38,14 @@ module.exports = async () => { const mongoConfig = { mongoDBName: 'jest', - mongoUri: await mongoServer.getConnectionString(), + mongoUri: await mongod.getConnectionString(), }; // Write global config to disk because all tests run in different contexts. fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig)); // Set reference to mongod in order to close the server during teardown. - global.__MONGOD__ = mongoServer; + global.__MONGOD__ = mongod; }; ``` From 322efc3512ddaa117de6cc7d63d5341c8fdc85ed Mon Sep 17 00:00:00 2001 From: Rafael de Oleza Date: Fri, 2 Nov 2018 09:22:34 -0700 Subject: [PATCH 27/45] Make getFileIterator() return relative paths (#7321) --- CHANGELOG.md | 1 + packages/jest-haste-map/src/HasteFS.js | 12 ++++++++---- packages/jest-resolve-dependencies/src/index.js | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a9eeb537f3c..79853f757e56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) - `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313)) +- `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321)) ### Fixes diff --git a/packages/jest-haste-map/src/HasteFS.js b/packages/jest-haste-map/src/HasteFS.js index 69df848a5975..03b60a1e946e 100644 --- a/packages/jest-haste-map/src/HasteFS.js +++ b/packages/jest-haste-map/src/HasteFS.js @@ -43,10 +43,14 @@ export default class HasteFS { } getAllFiles(): Array { - return Array.from(this.getFileIterator()); + return Array.from(this.getAbsoluteFileIterator()); } - *getFileIterator(): Iterator { + getFileIterator(): Iterator { + return this._files.keys(); + } + + *getAbsoluteFileIterator(): Iterator { for (const file of this._files.keys()) { yield fastPath.resolve(this._rootDir, file); } @@ -57,7 +61,7 @@ export default class HasteFS { pattern = new RegExp(pattern); } const files = []; - for (const file of this.getFileIterator()) { + for (const file of this.getAbsoluteFileIterator()) { if (pattern.test(file)) { files.push(file); } @@ -67,7 +71,7 @@ export default class HasteFS { matchFilesWithGlob(globs: Array, root: ?Path): Set { const files = new Set(); - for (const file of this.getFileIterator()) { + for (const file of this.getAbsoluteFileIterator()) { const filePath = root ? fastPath.relative(root, file) : file; if (micromatch([filePath], globs).length) { files.add(file); diff --git a/packages/jest-resolve-dependencies/src/index.js b/packages/jest-resolve-dependencies/src/index.js index b5e5f5a4efbc..64e3474037df 100644 --- a/packages/jest-resolve-dependencies/src/index.js +++ b/packages/jest-resolve-dependencies/src/index.js @@ -97,7 +97,7 @@ class DependencyResolver { } } const modules = []; - for (const file of this._hasteFS.getFileIterator()) { + for (const file of this._hasteFS.getAbsoluteFileIterator()) { modules.push({ dependencies: this.resolve(file, options), file, From f2b51c1d9cb3e5d8b99e015601ca71f277b616aa Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Fri, 2 Nov 2018 14:29:40 -0700 Subject: [PATCH 28/45] Improve message/stack parsing for Babel code frame errors (#7319) Previously, _addMissingMessageToStack decides not to add in the message to what we display, because it can't identify it as a stack. If we fix that by setting stack to include the message upfront (as many browsers do anyway), then it is printed but not prominently -- it is grayed out and with the stack with still only "Error" on the first line. Now if separateMessageFromStack can't tell where the stack begins, we assume the first line is the message -- which will cause it to be displayed more prominently. We could also try to detect code frames in separateMessageFromStack specifically (as we do stacks) but that doesn't seem trivial, in part because the code frame has already been colorized by the time it gets here. Before: ![before screenshot](https://user-images.githubusercontent.com/6820/47889870-6d064700-de09-11e8-8d4a-a044f2ad278b.png) After: ![after screenshot](https://user-images.githubusercontent.com/6820/47889756-cae65f00-de08-11e8-99c1-acfc6e7cb90c.png) --- CHANGELOG.md | 2 ++ .../expect-async-matcher.test.js.snap | 6 ++-- .../__snapshots__/failures.test.js.snap | 4 +-- .../__snapshots__/messages.test.js.snap | 16 +++++++++ .../src/__tests__/messages.test.js | 33 +++++++++++++++++++ packages/jest-message-util/src/index.js | 20 ++++++----- .../jest-runtime/src/script_transformer.js | 2 +- 7 files changed, 67 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79853f757e56..6b54edd13c71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ - `[expect]` Improves the failing message for `toStrictEqual` matcher. ([#7224](https://github.com/facebook/jest/pull/7224)) - `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381)) - `[jest-resolve]` Fix not being able to resolve path to mapped file with custom platform ([#7312](https://github.com/facebook/jest/pull/7312)) +- `[jest-message-util]` Improve parsing of error messages for unusually formatted stack traces ([#7319](https://github.com/facebook/jest/pull/7319)) +- `[jest-runtime]` Ensure error message text is not lost on errors with code frames ([#7319](https://github.com/facebook/jest/pull/7319)) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/expect-async-matcher.test.js.snap b/e2e/__tests__/__snapshots__/expect-async-matcher.test.js.snap index 2b179d34966a..21c961f43033 100644 --- a/e2e/__tests__/__snapshots__/expect-async-matcher.test.js.snap +++ b/e2e/__tests__/__snapshots__/expect-async-matcher.test.js.snap @@ -9,9 +9,8 @@ exports[`shows the correct errors in stderr when failing tests 1`] = ` ● fail with expected non promise values - Error + Expected value to have length: - Error: Expected value to have length: 2 Received: 1 @@ -20,9 +19,8 @@ exports[`shows the correct errors in stderr when failing tests 1`] = ` ● fail with expected non promise values and not - Error + Expected value to not have length: - Error: Expected value to not have length: 2 Received: 1,2 diff --git a/e2e/__tests__/__snapshots__/failures.test.js.snap b/e2e/__tests__/__snapshots__/failures.test.js.snap index 274061f1e37b..ab3f4c76b947 100644 --- a/e2e/__tests__/__snapshots__/failures.test.js.snap +++ b/e2e/__tests__/__snapshots__/failures.test.js.snap @@ -13,9 +13,7 @@ exports[`not throwing Error objects 2`] = ` "FAIL __tests__/throw_string.test.js ● Test suite failed to run - Error - - banana + banana " `; diff --git a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap index a39921bd1894..4cf7e417890e 100644 --- a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap +++ b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap @@ -22,6 +22,22 @@ exports[`formatStackTrace should strip node internals 1`] = ` " `; +exports[`retains message in babel code frame error 1`] = ` +" Babel test + + + packages/react/src/forwardRef.js: Unexpected token, expected , (20:10) + + 18 | false, + 19 | 'forwardRef requires a render function but received a \`memo\` ' + > 20 | 'component. Instead of forwardRef(memo(...)), use ' + + | ^ + 21 | 'memo(forwardRef(...)).', + 22 | ); + 23 | } else if (typeof render !== 'function') { +" +`; + exports[`should exclude jasmine from stack trace for Unix paths. 1`] = ` " Unix test diff --git a/packages/jest-message-util/src/__tests__/messages.test.js b/packages/jest-message-util/src/__tests__/messages.test.js index 6f8c9964e0c6..0a2078ca299c 100644 --- a/packages/jest-message-util/src/__tests__/messages.test.js +++ b/packages/jest-message-util/src/__tests__/messages.test.js @@ -58,6 +58,19 @@ const vendorStack = at Object.asyncFn (__tests__/vendor/sulu/node_modules/sulu-content-bundle/best_component.js:1:5) `; +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[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 + \u001b[90m 22 | \u001b[39m )\u001b[33m;\u001b[39m + \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 +`; + it('should exclude jasmine from stack trace for Unix paths.', () => { const messages = formatResultsErrors( [ @@ -134,3 +147,23 @@ it('should not exclude vendor from stack trace', () => { expect(messages).toMatchSnapshot(); }); + +it('retains message in babel code frame error', () => { + const messages = formatResultsErrors( + [ + { + ancestorTitles: [], + failureMessages: [babelStack], + title: 'Babel test', + }, + ], + { + rootDir: '', + }, + { + noStackTrace: false, + }, + ); + + expect(messages).toMatchSnapshot(); +}); diff --git a/packages/jest-message-util/src/index.js b/packages/jest-message-util/src/index.js index 1f8f4d5f62ba..c09af5c3f84f 100644 --- a/packages/jest-message-util/src/index.js +++ b/packages/jest-message-util/src/index.js @@ -62,7 +62,6 @@ const TITLE_BULLET = chalk.bold('\u25cf '); const STACK_TRACE_COLOR = chalk.dim; const STACK_PATH_REGEXP = /\s*at.*\(?(\:\d*\:\d*|native)\)?/; const EXEC_ERROR_MESSAGE = 'Test suite failed to run'; -const ERROR_TEXT = 'Error: '; const NOT_EMPTY_LINE_REGEXP = /^(?!$)/gm; const indentAllLines = (lines: string, indent: string) => @@ -335,13 +334,18 @@ export const separateMessageFromStack = (content: string) => { return {message: '', stack: ''}; } - const messageMatch = content.match(/(^(.|\n)*?(?=\n\s*at\s.*\:\d*\:\d*))/); - let message = messageMatch ? messageMatch[0] : 'Error'; - const stack = messageMatch ? content.slice(message.length) : content; - // If the error is a plain error instead of a SyntaxError or TypeError - // we remove it from the message because it is generally not useful. - if (message.startsWith(ERROR_TEXT)) { - message = message.substr(ERROR_TEXT.length); + // All lines up to what looks like a stack -- or if nothing looks like a stack + // (maybe it's a code frame instead), just the first non-empty line. + // If the error is a plain "Error:" instead of a SyntaxError or TypeError we + // remove the prefix from the message because it is generally not useful. + const messageMatch = content.match( + /^(?:Error: )?([\s\S]*?(?=\n\s*at\s.*\:\d*\:\d*)|\s*.*)([\s\S]*)$/, + ); + if (!messageMatch) { + // For flow + throw new Error('If you hit this error, the regex above is buggy.'); } + const message = messageMatch[1]; + const stack = messageMatch[2]; return {message, stack}; }; diff --git a/packages/jest-runtime/src/script_transformer.js b/packages/jest-runtime/src/script_transformer.js index 96014c5ba088..a25683156afd 100644 --- a/packages/jest-runtime/src/script_transformer.js +++ b/packages/jest-runtime/src/script_transformer.js @@ -329,7 +329,7 @@ export default class ScriptTransformer { }; } catch (e) { if (e.codeFrame) { - e.stack = e.codeFrame; + e.stack = e.message + '\n' + e.codeFrame; } if ( From 9812e1b095861dcf992a32a2af137b67deec88fc Mon Sep 17 00:00:00 2001 From: yamatatsu Date: Sat, 3 Nov 2018 14:10:44 +0900 Subject: [PATCH 29/45] fix: get relative path in haste map (#7324) * fix: get relative path in haste map * CHANGELOG --- CHANGELOG.md | 1 + .../jest-haste-map/src/lib/__tests__/fast_path.test.js | 7 +++++++ packages/jest-haste-map/src/lib/fast_path.js | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b54edd13c71..c5744f75cd03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ - `[jest-resolve]` Fix not being able to resolve path to mapped file with custom platform ([#7312](https://github.com/facebook/jest/pull/7312)) - `[jest-message-util]` Improve parsing of error messages for unusually formatted stack traces ([#7319](https://github.com/facebook/jest/pull/7319)) - `[jest-runtime]` Ensure error message text is not lost on errors with code frames ([#7319](https://github.com/facebook/jest/pull/7319)) +- `[jest-haste-map]` Fix to resolve path that is start with words same as rootDir ([#7324](https://github.com/facebook/jest/pull/7324)) ### Chore & Maintenance diff --git a/packages/jest-haste-map/src/lib/__tests__/fast_path.test.js b/packages/jest-haste-map/src/lib/__tests__/fast_path.test.js index d6872fec82de..5eaae66edb0d 100644 --- a/packages/jest-haste-map/src/lib/__tests__/fast_path.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/fast_path.test.js @@ -26,6 +26,13 @@ describe('fastPath.relative', () => { const relativeFilename = path.join('..', 'baz', 'foobar'); expect(relative(root, filename)).toBe(relativeFilename); }); + + it('should get relative paths outside the root when start with same word', () => { + const root = path.join(__dirname, 'foo', 'bar'); + const filename = path.join(__dirname, 'foo', 'barbaz', 'foobar'); + const relativeFilename = path.join('..', 'barbaz', 'foobar'); + expect(relative(root, filename)).toBe(relativeFilename); + }); }); describe('fastPath.resolve', () => { diff --git a/packages/jest-haste-map/src/lib/fast_path.js b/packages/jest-haste-map/src/lib/fast_path.js index f161ae48bf9e..1f05b4ffb0cc 100644 --- a/packages/jest-haste-map/src/lib/fast_path.js +++ b/packages/jest-haste-map/src/lib/fast_path.js @@ -11,7 +11,7 @@ import path from 'path'; // rootDir and filename must be absolute paths (resolved) export function relative(rootDir: string, filename: string): string { - return filename.indexOf(rootDir) === 0 + return filename.indexOf(rootDir + path.sep) === 0 ? filename.substr(rootDir.length + 1) : path.relative(rootDir, filename); } From 48596004725ecbdccea921fb9c6d5af45cf96c5d Mon Sep 17 00:00:00 2001 From: Ryan Oglesby Date: Tue, 6 Nov 2018 20:06:32 -0500 Subject: [PATCH 30/45] handle objects with no constructor in hasOwnProperty (#7334) * handle objects with no constructor in hasOwnProperty Closes #6730 * update changelog --- CHANGELOG.md | 1 + .../__snapshots__/matchers.test.js.snap | 26 +++++++++++++++++++ .../expect/src/__tests__/matchers.test.js | 2 ++ packages/expect/src/utils.js | 14 +++++++--- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5744f75cd03..f1f08794bd71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ - `[jest-message-util]` Improve parsing of error messages for unusually formatted stack traces ([#7319](https://github.com/facebook/jest/pull/7319)) - `[jest-runtime]` Ensure error message text is not lost on errors with code frames ([#7319](https://github.com/facebook/jest/pull/7319)) - `[jest-haste-map]` Fix to resolve path that is start with words same as rootDir ([#7324](https://github.com/facebook/jest/pull/7324)) +- `[expect]` Fix toMatchObject matcher when used with `Object.create(null)` ([#7334](https://github.com/facebook/jest/pull/7334)) ### Chore & Maintenance diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index 5a3e468bb84b..6e9c035453aa 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -3688,6 +3688,23 @@ Difference: }" `; +exports[`toMatchObject() {pass: false} expect({"a": "b"}).toMatchObject({"c": "d"}) 1`] = ` +"expect(received).toMatchObject(expected) + +Expected value to match object: + {\\"c\\": \\"d\\"} +Received: + {\\"a\\": \\"b\\"} +Difference: +- Expected ++ Received + + Object { +- \\"c\\": \\"d\\", ++ \\"a\\": \\"b\\", + }" +`; + exports[`toMatchObject() {pass: false} expect({"a": [{"a": "a", "b": "b"}]}).toMatchObject({"a": [{"a": "c"}]}) 1`] = ` "expect(received).toMatchObject(expected) @@ -4026,6 +4043,15 @@ Received: {\\"a\\": \\"b\\", \\"t\\": {\\"x\\": {\\"r\\": \\"r\\"}, \\"z\\": \\"z\\"}}" `; +exports[`toMatchObject() {pass: true} expect({"a": "b"}).toMatchObject({"a": "b"}) 1`] = ` +"expect(received).not.toMatchObject(expected) + +Expected value not to match object: + {\\"a\\": \\"b\\"} +Received: + {\\"a\\": \\"b\\"}" +`; + exports[`toMatchObject() {pass: true} expect({"a": [{"a": "a", "b": "b"}]}).toMatchObject({"a": [{"a": "a"}]}) 1`] = ` "expect(received).not.toMatchObject(expected) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 344e451b55e4..83662ae03c41 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -1142,6 +1142,7 @@ describe('toMatchObject()', () => { [new Error('foo'), new Error('foo')], [new Error('bar'), {message: 'bar'}], [new Foo(), {a: undefined, b: 'b'}], + [Object.assign(Object.create(null), {a: 'b'}), {a: 'b'}], ].forEach(([n1, n2]) => { it(`{pass: true} expect(${stringify(n1)}).toMatchObject(${stringify( n2, @@ -1178,6 +1179,7 @@ describe('toMatchObject()', () => { [[1, 2, 3], [2, 3, 1]], [[1, 2, 3], [1, 2, 2]], [new Error('foo'), new Error('bar')], + [Object.assign(Object.create(null), {a: 'b'}), {c: 'd'}], ].forEach(([n1, n2]) => { it(`{pass: false} expect(${stringify(n1)}).toMatchObject(${stringify( n2, diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index 2c7de7ab2237..24197cc2c50f 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -21,9 +21,17 @@ type GetPath = { value?: any, }; -export const hasOwnProperty = (object: Object, value: string) => - Object.prototype.hasOwnProperty.call(object, value) || - Object.prototype.hasOwnProperty.call(object.constructor.prototype, value); +export const hasOwnProperty = (object: Object, value: string) => { + // Account for objects created using unconventional means such as + // `Object.create(null)`, in which case the `object.constructor` is undefined + // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Custom_and_Null_objects + const objectConstructor = object.constructor || Object; + + return ( + Object.prototype.hasOwnProperty.call(object, value) || + Object.prototype.hasOwnProperty.call(objectConstructor.prototype, value) + ); +}; export const getPath = ( object: Object, From fa0e81443a5b97281f1d1c22a0b857c289a004ad Mon Sep 17 00:00:00 2001 From: Rafael de Oleza Date: Wed, 7 Nov 2018 16:43:22 +0000 Subject: [PATCH 31/45] Fix recovery of haste collisions (#7329) --- CHANGELOG.md | 1 + packages/jest-haste-map/src/ModuleMap.js | 35 +++++---- .../src/__tests__/index.test.js | 75 ++++++++++++++++--- packages/jest-haste-map/src/index.js | 48 +++++++----- types/HasteMap.js | 10 +-- 5 files changed, 116 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1f08794bd71..669a81e49efd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ - `[jest-runtime]` Ensure error message text is not lost on errors with code frames ([#7319](https://github.com/facebook/jest/pull/7319)) - `[jest-haste-map]` Fix to resolve path that is start with words same as rootDir ([#7324](https://github.com/facebook/jest/pull/7324)) - `[expect]` Fix toMatchObject matcher when used with `Object.create(null)` ([#7334](https://github.com/facebook/jest/pull/7334)) +- `[jest-haste-map]` [**BREAKING**] Recover files correctly after haste name collisions are fixed ([#7329](https://github.com/facebook/jest/pull/7329)) ### Chore & Maintenance diff --git a/packages/jest-haste-map/src/ModuleMap.js b/packages/jest-haste-map/src/ModuleMap.js index a305d04c720a..1f5351613ed4 100644 --- a/packages/jest-haste-map/src/ModuleMap.js +++ b/packages/jest-haste-map/src/ModuleMap.js @@ -21,7 +21,8 @@ import type { import * as fastPath from './lib/fast_path'; import H from './constants'; -const EMPTY_MAP = {}; +const EMPTY_OBJ = {}; +const EMPTY_MAP = new Map(); export opaque type SerializableModuleMap = { // There is no easier way to extract the type of the entries of a Map @@ -117,14 +118,14 @@ export default class ModuleMap { platform: ?string, supportsNativePlatform: boolean, ): ?ModuleMetaData { - const map = this._raw.map.get(name) || EMPTY_MAP; + const map = this._raw.map.get(name) || EMPTY_OBJ; const dupMap = this._raw.duplicates.get(name) || EMPTY_MAP; if (platform != null) { this._assertNoDuplicates( name, platform, supportsNativePlatform, - dupMap[platform], + dupMap.get(platform), ); if (map[platform] != null) { return map[platform]; @@ -135,7 +136,7 @@ export default class ModuleMap { name, H.NATIVE_PLATFORM, supportsNativePlatform, - dupMap[H.NATIVE_PLATFORM], + dupMap.get(H.NATIVE_PLATFORM), ); if (map[H.NATIVE_PLATFORM]) { return map[H.NATIVE_PLATFORM]; @@ -145,7 +146,7 @@ export default class ModuleMap { name, H.GENERIC_PLATFORM, supportsNativePlatform, - dupMap[H.GENERIC_PLATFORM], + dupMap.get(H.GENERIC_PLATFORM), ); if (map[H.GENERIC_PLATFORM]) { return map[H.GENERIC_PLATFORM]; @@ -163,17 +164,19 @@ export default class ModuleMap { return; } // Force flow refinement - const previousSet: DuplicatesSet = relativePathSet; - const set = Object.keys(previousSet).reduce((set, relativePath) => { + const previousSet = relativePathSet; + const duplicates = new Map(); + + for (const [relativePath, type] of previousSet) { const duplicatePath = fastPath.resolve(this._raw.rootDir, relativePath); - set[duplicatePath] = previousSet[relativePath]; - return set; - }, Object.create(null)); + duplicates.set(duplicatePath, type); + } + throw new DuplicateHasteCandidatesError( name, platform, supportsNativePlatform, - set, + duplicates, ); } @@ -206,12 +209,12 @@ class DuplicateHasteCandidatesError extends Error { `files, or packages, that provide a module for ` + `that particular name and platform. ${platformMessage} You must ` + `delete or blacklist files until there remains only one of these:\n\n` + - Object.keys(duplicatesSet) + Array.from(duplicatesSet) + .map( + ([dupFilePath, dupFileType]) => + ` * \`${dupFilePath}\` (${getTypeMessage(dupFileType)})\n`, + ) .sort() - .map(dupFilePath => { - const typeMessage = getTypeMessage(duplicatesSet[dupFilePath]); - return ` * \`${dupFilePath}\` (${typeMessage})\n`; - }) .join(''), ); this.hasteName = name; diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index 3b1a49f37626..ad07671d329f 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -783,9 +783,12 @@ describe('HasteMap', () => { ).build(); expect(normalizeMap(data.duplicates)).toEqual( createMap({ - Strawberry: { - g: {'fruits/Strawberry.js': 0, 'fruits/another/Strawberry.js': 0}, - }, + Strawberry: createMap({ + g: createMap({ + 'fruits/Strawberry.js': H.MODULE, + 'fruits/another/Strawberry.js': H.MODULE, + }), + }), }), ); expect(data.map.get('Strawberry')).toEqual({}); @@ -806,10 +809,54 @@ describe('HasteMap', () => { ).build(); expect(normalizeMap(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/Strawberry.js', 0], + g: ['fruits/Strawberry.js', H.MODULE], }); // Make sure the other files are not affected. - expect(data.map.get('Banana')).toEqual({g: ['fruits/Banana.js', 0]}); + expect(data.map.get('Banana')).toEqual({ + g: ['fruits/Banana.js', H.MODULE], + }); + }); + + it('recovers with the correct type when a duplicate file is deleted', async () => { + mockFs['/project/fruits/strawberryPackage/package.json'] = ` + {"name": "Strawberry"} + `; + + const {__hasteMapForTest: data} = await new HasteMap( + defaultConfig, + ).build(); + + expect(normalizeMap(data.duplicates)).toEqual( + createMap({ + Strawberry: createMap({ + g: createMap({ + 'fruits/Strawberry.js': H.MODULE, + 'fruits/another/Strawberry.js': H.MODULE, + 'fruits/strawberryPackage/package.json': H.PACKAGE, + }), + }), + }), + ); + + delete mockFs['/project/fruits/another/Strawberry.js']; + delete mockFs['/project/fruits/strawberryPackage/package.json']; + + mockChangedFiles = object({ + '/project/fruits/another/Strawberry.js': null, + '/project/fruits/strawberryPackage/package.json': null, + }); + mockClocks = createMap({ + fruits: 'c:fake-clock:4', + }); + + const {__hasteMapForTest: correctData} = await new HasteMap( + defaultConfig, + ).build(); + + expect(normalizeMap(correctData.duplicates)).toEqual(new Map()); + expect(correctData.map.get('Strawberry')).toEqual({ + g: ['fruits/Strawberry.js', H.MODULE], + }); }); it('recovers when a duplicate module is renamed', async () => { @@ -829,13 +876,15 @@ describe('HasteMap', () => { ).build(); expect(normalizeMap(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/Strawberry.js', 0], + g: ['fruits/Strawberry.js', H.MODULE], }); expect(data.map.get('Pineapple')).toEqual({ - g: ['fruits/another/Pineapple.js', 0], + g: ['fruits/another/Pineapple.js', H.MODULE], }); // Make sure the other files are not affected. - expect(data.map.get('Banana')).toEqual({g: ['fruits/Banana.js', 0]}); + expect(data.map.get('Banana')).toEqual({ + g: ['fruits/Banana.js', H.MODULE], + }); }); }); @@ -1243,10 +1292,12 @@ describe('HasteMap', () => { expect(error.hasteName).toBe('Pear'); expect(error.platform).toBe('g'); expect(error.supportsNativePlatform).toBe(false); - expect(error.duplicatesSet).toEqual({ - '/project/fruits/Pear.js': 0, - '/project/fruits/another/Pear.js': 0, - }); + expect(error.duplicatesSet).toEqual( + createMap({ + '/project/fruits/Pear.js': H.MODULE, + '/project/fruits/another/Pear.js': H.MODULE, + }), + ); expect(error.message).toMatchSnapshot(); } } diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index fabadb3b33ee..46cf53458f43 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -430,20 +430,24 @@ class HasteMap extends EventEmitter { } let dupsByPlatform = hasteMap.duplicates.get(id); if (dupsByPlatform == null) { - dupsByPlatform = Object.create(null); + dupsByPlatform = new Map(); hasteMap.duplicates.set(id, dupsByPlatform); } - const dups = (dupsByPlatform[platform] = Object.create(null)); - dups[module[H.PATH]] = module[H.TYPE]; - dups[existingModule[H.PATH]] = existingModule[H.TYPE]; + + const dups = new Map([ + [module[H.PATH], module[H.TYPE]], + [existingModule[H.PATH], existingModule[H.TYPE]], + ]); + dupsByPlatform.set(platform, dups); + return; } const dupsByPlatform = hasteMap.duplicates.get(id); if (dupsByPlatform != null) { - const dups = dupsByPlatform[platform]; + const dups = dupsByPlatform.get(platform); if (dups != null) { - dups[module[H.PATH]] = module[H.TYPE]; + dups.set(module[H.PATH], module[H.TYPE]); } return; } @@ -928,31 +932,37 @@ class HasteMap extends EventEmitter { const platform = getPlatformExtension(relativeFilePath, this._options.platforms) || H.GENERIC_PLATFORM; - let dups = dupsByPlatform[platform]; + let dups = dupsByPlatform.get(platform); if (dups == null) { return; } - dupsByPlatform = copy(dupsByPlatform); + dupsByPlatform = copyMap(dupsByPlatform); hasteMap.duplicates.set(moduleName, dupsByPlatform); - dups = copy(dups); - dupsByPlatform[platform] = dups; - const dedupType = dups[relativeFilePath]; - delete dups[relativeFilePath]; - const filePaths = Object.keys(dups); - if (filePaths.length > 1) { + dups = copyMap(dups); + dupsByPlatform.set(platform, dups); + dups.delete(relativeFilePath); + + if (dups.size !== 1) { + return; + } + + const uniqueModule = dups.entries().next().value; + + if (!uniqueModule) { return; } let dedupMap = hasteMap.map.get(moduleName); + if (dedupMap == null) { dedupMap = Object.create(null); hasteMap.map.set(moduleName, dedupMap); } - dedupMap[platform] = [filePaths[0], dedupType]; - delete dupsByPlatform[platform]; - if (Object.keys(dupsByPlatform).length === 0) { + dedupMap[platform] = uniqueModule; + dupsByPlatform.delete(platform); + if (dupsByPlatform.size === 0) { hasteMap.duplicates.delete(moduleName); } } @@ -1026,6 +1036,10 @@ class HasteMap extends EventEmitter { const copy = object => Object.assign(Object.create(null), object); +function copyMap(input: Map): Map { + return new Map(input); +} + HasteMap.H = H; HasteMap.ModuleMap = HasteModuleMap; diff --git a/types/HasteMap.js b/types/HasteMap.js index 01865ad57790..ed9825535b4f 100644 --- a/types/HasteMap.js +++ b/types/HasteMap.js @@ -24,14 +24,8 @@ export type ModuleMapData = Map; export type WatchmanClocks = Map; export type HasteRegExp = RegExp | ((str: string) => boolean); -export type DuplicatesSet = { - [filePath: string]: /* type */ number, - __proto__: null, -}; -export type DuplicatesIndex = Map< - string, - {[platform: string]: DuplicatesSet, __proto__: null}, ->; +export type DuplicatesSet = Map; +export type DuplicatesIndex = Map>; export type InternalHasteMap = {| clocks: WatchmanClocks, From 2b18a2633e06077d230f8747a32c9da18525bda3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Wed, 7 Nov 2018 14:58:43 -0500 Subject: [PATCH 32/45] Fix duplicate module detection (#7333) * Fix duplicate module detection in haste map * Fix failing test due to differences in contexts --- CHANGELOG.md | 1 + .../src/__tests__/index.test.js | 71 ++++++++++++------- packages/jest-haste-map/src/index.js | 7 +- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 669a81e49efd..14931240dd4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ - `[jest-haste-map]` Fix to resolve path that is start with words same as rootDir ([#7324](https://github.com/facebook/jest/pull/7324)) - `[expect]` Fix toMatchObject matcher when used with `Object.create(null)` ([#7334](https://github.com/facebook/jest/pull/7334)) - `[jest-haste-map]` [**BREAKING**] Recover files correctly after haste name collisions are fixed ([#7329](https://github.com/facebook/jest/pull/7329)) +- `[jest-haste-map]` Remove legacy condition for duplicate module detection ([#7333](https://github.com/facebook/jest/pull/7333)) ### Chore & Maintenance diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index ad07671d329f..0429634bdf42 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -108,18 +108,25 @@ const object = data => Object.assign(Object.create(null), data); const createMap = obj => new Map(Object.keys(obj).map(key => [key, obj[key]])); // Jest toEqual does not match Map instances from different contexts -const normalizePersisted = hasteMap => ({ - clocks: normalizeMap(hasteMap.clocks), - duplicates: normalizeMap(hasteMap.duplicates), - files: normalizeMap(hasteMap.files), - map: normalizeMap(hasteMap.map), - mocks: normalizeMap(hasteMap.mocks), -}); -const normalizeMap = map => { - if (Object.prototype.toString.call(map) !== '[object Map]') { - throw new TypeError('expected map instance'); +// This normalizes them for the uses cases in this test +const useBuitinsInContext = value => { + const stringTag = Object.prototype.toString.call(value); + switch (stringTag) { + case '[object Map]': + return new Map( + Array.from(value).map(([k, v]) => [ + useBuitinsInContext(k), + useBuitinsInContext(v), + ]), + ); + case '[object Object]': + return Object.keys(value).reduce((obj, key) => { + obj[key] = useBuitinsInContext(value[key]); + return obj; + }, {}); + default: + return value; } - return new Map(map); }; let consoleWarn; @@ -359,7 +366,7 @@ describe('HasteMap', () => { // The cache file must exactly mirror the data structure returned from a // build - expect(normalizePersisted(hasteMap.read())).toEqual(data); + expect(useBuitinsInContext(hasteMap.read())).toEqual(data); }); }); @@ -433,7 +440,7 @@ describe('HasteMap', () => { }), ); - expect(normalizePersisted(hasteMap.read())).toEqual(data); + expect(useBuitinsInContext(hasteMap.read())).toEqual(data); }); }); }); @@ -523,6 +530,18 @@ describe('HasteMap', () => { }); }); + it('warns on duplicate module ids only once', async () => { + mockFs['/project/fruits/other/Strawberry.js'] = ` + const Banana = require("Banana"); + `; + + await new HasteMap(defaultConfig).build(); + expect(console.warn).toHaveBeenCalledTimes(1); + + await new HasteMap(defaultConfig).build(); + expect(console.warn).toHaveBeenCalledTimes(1); + }); + it('throws on duplicate module ids if "throwOnModuleCollision" is set to true', () => { // Raspberry thinks it is a Strawberry mockFs['/project/fruits/another/Strawberry.js'] = ` @@ -615,9 +634,9 @@ describe('HasteMap', () => { } else { expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8'); } - expect(normalizeMap(data.clocks)).toEqual(mockClocks); - expect(normalizeMap(data.files)).toEqual(initialData.files); - expect(normalizeMap(data.map)).toEqual(initialData.map); + expect(useBuitinsInContext(data.clocks)).toEqual(mockClocks); + expect(useBuitinsInContext(data.files)).toEqual(initialData.files); + expect(useBuitinsInContext(data.map)).toEqual(initialData.map); }); })); @@ -655,15 +674,15 @@ describe('HasteMap', () => { 'utf8', ); - expect(normalizeMap(data.clocks)).toEqual(mockClocks); + expect(useBuitinsInContext(data.clocks)).toEqual(mockClocks); const files = new Map(initialData.files); files.set('fruits/Banana.js', ['Banana', 32, 1, ['Kiwi'], null]); - expect(normalizeMap(data.files)).toEqual(files); + expect(useBuitinsInContext(data.files)).toEqual(files); const map = new Map(initialData.map); - expect(normalizeMap(data.map)).toEqual(map); + expect(useBuitinsInContext(data.map)).toEqual(map); }); })); @@ -690,11 +709,11 @@ describe('HasteMap', () => { .then(({__hasteMapForTest: data}) => { const files = new Map(initialData.files); files.delete('fruits/Banana.js'); - expect(normalizeMap(data.files)).toEqual(files); + expect(useBuitinsInContext(data.files)).toEqual(files); const map = new Map(initialData.map); map.delete('Banana'); - expect(normalizeMap(data.map)).toEqual(map); + expect(useBuitinsInContext(data.map)).toEqual(map); }); })); @@ -781,7 +800,7 @@ describe('HasteMap', () => { const {__hasteMapForTest: data} = await new HasteMap( defaultConfig, ).build(); - expect(normalizeMap(data.duplicates)).toEqual( + expect(useBuitinsInContext(data.duplicates)).toEqual( createMap({ Strawberry: createMap({ g: createMap({ @@ -807,7 +826,7 @@ describe('HasteMap', () => { const {__hasteMapForTest: data} = await new HasteMap( defaultConfig, ).build(); - expect(normalizeMap(data.duplicates)).toEqual(new Map()); + expect(useBuitinsInContext(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ g: ['fruits/Strawberry.js', H.MODULE], }); @@ -826,7 +845,7 @@ describe('HasteMap', () => { defaultConfig, ).build(); - expect(normalizeMap(data.duplicates)).toEqual( + expect(useBuitinsInContext(data.duplicates)).toEqual( createMap({ Strawberry: createMap({ g: createMap({ @@ -853,7 +872,7 @@ describe('HasteMap', () => { defaultConfig, ).build(); - expect(normalizeMap(correctData.duplicates)).toEqual(new Map()); + expect(useBuitinsInContext(correctData.duplicates)).toEqual(new Map()); expect(correctData.map.get('Strawberry')).toEqual({ g: ['fruits/Strawberry.js', H.MODULE], }); @@ -874,7 +893,7 @@ describe('HasteMap', () => { const {__hasteMapForTest: data} = await new HasteMap( defaultConfig, ).build(); - expect(normalizeMap(data.duplicates)).toEqual(new Map()); + expect(useBuitinsInContext(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ g: ['fruits/Strawberry.js', H.MODULE], }); diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index 46cf53458f43..d31d8f2188ff 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -375,10 +375,9 @@ class HasteMap extends EventEmitter { cachedFiles.push({moduleName, path: relativeFilePath}); } return this._crawl(cachedHasteMap).then(hasteMap => { - const deprecatedFiles = cachedFiles.filter(file => { - const fileData = hasteMap.files.get(file.path); - return fileData == null || file.moduleName !== fileData[H.ID]; - }); + const deprecatedFiles = cachedFiles.filter( + file => !hasteMap.files.has(file.path), + ); return {deprecatedFiles, hasteMap}; }); }); From 62d3d2e08fe52f960146014ddbd066341507442c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 8 Nov 2018 11:31:49 +0000 Subject: [PATCH 33/45] Mark change as breaking in changelog (#7343) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14931240dd4c..1ad636132af1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ - `[expect]` Standardize file naming in `expect` ([#7306](https://github.com/facebook/jest/pull/7306)) - `[jest-each]` Add empty array validation check ([#7249](https://github.com/facebook/jest/pull/7249)) - `[jest-cli]` Interrupt tests if interactive watch plugin key is pressed ([#7222](https://github.com/facebook/jest/pull/7222)) -- `[jest-cli]` Fix coverage summary reporting ([#7058](https://github.com/facebook/jest/pull/7058)) +- `[jest-cli]` [**BREAKING**] Do not use `text` coverage reporter by default if other reporters are configured ([#7058](https://github.com/facebook/jest/pull/7058)) - `[jest-each]` Add each array validation check ([#7033](https://github.com/facebook/jest/pull/7033)) - `[jest-haste-map]` Do not visit again files with the same sha-1 ([#6990](https://github.com/facebook/jest/pull/6990)) - `[jest-jasmine2]` Fix memory leak in Error objects hold by the framework ([#6965](https://github.com/facebook/jest/pull/6965)) From b44e7f289db43729bd2d75030e45b17b116c5553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 8 Nov 2018 13:18:15 +0000 Subject: [PATCH 34/45] Fix coverage reporter name in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ad636132af1..1df683e1edfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ - `[expect]` Standardize file naming in `expect` ([#7306](https://github.com/facebook/jest/pull/7306)) - `[jest-each]` Add empty array validation check ([#7249](https://github.com/facebook/jest/pull/7249)) - `[jest-cli]` Interrupt tests if interactive watch plugin key is pressed ([#7222](https://github.com/facebook/jest/pull/7222)) -- `[jest-cli]` [**BREAKING**] Do not use `text` coverage reporter by default if other reporters are configured ([#7058](https://github.com/facebook/jest/pull/7058)) +- `[jest-cli]` [**BREAKING**] Do not use `text-summary` coverage reporter by default if other reporters are configured ([#7058](https://github.com/facebook/jest/pull/7058)) - `[jest-each]` Add each array validation check ([#7033](https://github.com/facebook/jest/pull/7033)) - `[jest-haste-map]` Do not visit again files with the same sha-1 ([#6990](https://github.com/facebook/jest/pull/6990)) - `[jest-jasmine2]` Fix memory leak in Error objects hold by the framework ([#6965](https://github.com/facebook/jest/pull/6965)) From 46914f837bce5d9b18ee228177b20f2e893fd42e Mon Sep 17 00:00:00 2001 From: Explorer / <39474131+open-source-explorer@users.noreply.github.com> Date: Fri, 9 Nov 2018 03:33:56 +0530 Subject: [PATCH 35/45] Add PR welcoming badge (#7340) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index abd3c72492a9..2ca15b7089d5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ npm version SemVer Blazing Fast + PR's welcome

Backers on Open Collective From af33d14e777c9fb51b89ab9562ecfd50d3c11c2f Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 8 Nov 2018 05:53:53 +1000 Subject: [PATCH 36/45] chore: upgrade eslint-plugin-jest --- package.json | 2 +- packages/eslint-config-fb-strict/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1a1dff05b021..238af5ff7b8a 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "eslint-plugin-babel": "^5.1.0", "eslint-plugin-flowtype": "^2.35.0", "eslint-plugin-import": "^2.6.0", - "eslint-plugin-jest": "^21.0.0", + "eslint-plugin-jest": "^22.0.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-markdown": "^1.0.0-beta.6", "eslint-plugin-prettier": "^2.3.1", diff --git a/packages/eslint-config-fb-strict/package.json b/packages/eslint-config-fb-strict/package.json index ab66821e3269..732f93013020 100644 --- a/packages/eslint-config-fb-strict/package.json +++ b/packages/eslint-config-fb-strict/package.json @@ -14,7 +14,7 @@ "eslint": "^4.2.0 || ^5.0.0", "eslint-plugin-babel": "^4.1.1 || ^5.0.0", "eslint-plugin-flowtype": "^2.35.0", - "eslint-plugin-jest": "^21.0.0", + "eslint-plugin-jest": "^21.0.0 || ^22.0.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "~0.0.8" diff --git a/yarn.lock b/yarn.lock index b20d4a6f2266..d6dccc600b98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5336,10 +5336,10 @@ eslint-plugin-import@^2.6.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-jest@^21.0.0: - version "21.25.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-21.25.1.tgz#166c6b9d33bd7bc5b8ece62cff878ba207600bb6" - integrity sha512-mmphmAD/WihjFGq1IUHLSZWQPcd8U9w/SeFCHf3p0V3Q3MBxmj1ZKnh41hID44guIACLuwos/LhVWIr4phN4yg== +eslint-plugin-jest@^22.0.0: + version "22.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.0.0.tgz#87dc52bbdd47f37f23bf2b10bb8469458bb3ed68" + integrity sha512-YOj8cYI5ZXEZUrX2kUBLachR1ffjQiicIMBoivN7bXXHnxi8RcwNvmVzwlu3nTmjlvk5AP3kIpC5i8HcinmhPA== eslint-plugin-jsx-a11y@^6.0.2: version "6.1.1" From 2c18a53e8ff2437bba5fcb8076b754ac5f79f9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 9 Nov 2018 01:15:56 +0000 Subject: [PATCH 37/45] Add computeSha1 option (#7345) --- CHANGELOG.md | 1 + e2e/__tests__/__snapshots__/show_config.test.js.snap | 1 + packages/jest-config/src/Defaults.js | 1 + packages/jest-config/src/ValidConfig.js | 1 + packages/jest-runtime/src/index.js | 1 + types/Config.js | 1 + 6 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1df683e1edfd..4e5e2d08c8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) - `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313)) - `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321)) +- `[jest-config]` Add `haste.computeSha1` option to compute the sha-1 of the files in the haste map ([#7345](https://github.com/facebook/jest/pull/7345)) ### Fixes diff --git a/e2e/__tests__/__snapshots__/show_config.test.js.snap b/e2e/__tests__/__snapshots__/show_config.test.js.snap index cf77d55b5751..24f419707d6d 100644 --- a/e2e/__tests__/__snapshots__/show_config.test.js.snap +++ b/e2e/__tests__/__snapshots__/show_config.test.js.snap @@ -21,6 +21,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` \\"forceCoverageMatch\\": [], \\"globals\\": {}, \\"haste\\": { + \\"computeSha1\\": false, \\"providesModuleNodeModules\\": [] }, \\"moduleDirectories\\": [ diff --git a/packages/jest-config/src/Defaults.js b/packages/jest-config/src/Defaults.js index ea40b3cf4e05..85b29b28f577 100644 --- a/packages/jest-config/src/Defaults.js +++ b/packages/jest-config/src/Defaults.js @@ -41,6 +41,7 @@ export default ({ globalTeardown: null, globals: {}, haste: { + computeSha1: false, providesModuleNodeModules: [], }, moduleDirectories: ['node_modules'], diff --git a/packages/jest-config/src/ValidConfig.js b/packages/jest-config/src/ValidConfig.js index 2d2d4128bc48..c3da446f08a5 100644 --- a/packages/jest-config/src/ValidConfig.js +++ b/packages/jest-config/src/ValidConfig.js @@ -51,6 +51,7 @@ export default ({ globalTeardown: 'teardown.js', globals: {__DEV__: true}, haste: { + computeSha1: true, defaultPlatform: 'ios', hasteImplModulePath: '/haste_impl.js', platforms: ['ios', 'android'], diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index f60b33b0dae6..f91e481a2925 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -236,6 +236,7 @@ class Runtime { return new HasteMap({ cacheDirectory: config.cacheDirectory, + computeSha1: config.haste.computeSha1, console: options && options.console, dependencyExtractor: config.dependencyExtractor, extensions: [Snapshot.EXTENSION].concat(config.moduleFileExtensions), diff --git a/types/Config.js b/types/Config.js index 957cb3afeaab..39eac782b764 100644 --- a/types/Config.js +++ b/types/Config.js @@ -11,6 +11,7 @@ export type Path = string; export type Glob = string; export type HasteConfig = {| + computeSha1?: boolean, defaultPlatform?: ?string, hasteImplModulePath?: string, platforms?: Array, From 213d8e5c22497a5b8730fbeec1d02b807956626e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 9 Nov 2018 16:08:13 +0000 Subject: [PATCH 38/45] Use namespace for dependency extractor (#7349) --- CHANGELOG.md | 2 +- docs/Configuration.md | 2 +- e2e/__tests__/find_related_files.test.js | 18 ++++++++++-------- .../src/__tests__/dependencyExtractor.js | 7 ++----- ...Requires.test.js => dependencyExtractor.js} | 2 +- ...tractRequires.js => dependencyExtractor.js} | 2 +- packages/jest-haste-map/src/worker.js | 9 ++++++--- 7 files changed, 22 insertions(+), 20 deletions(-) rename packages/jest-haste-map/src/lib/__tests__/{extractRequires.test.js => dependencyExtractor.js} (97%) rename packages/jest-haste-map/src/lib/{extractRequires.js => dependencyExtractor.js} (95%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e5e2d08c8fb..bdfa4d189221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ - `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203)) - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) -- `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313)) +- `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313), [#7349](https://github.com/facebook/jest/pull/7349)). - `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321)) - `[jest-config]` Add `haste.computeSha1` option to compute the sha-1 of the files in the haste map ([#7345](https://github.com/facebook/jest/pull/7345)) diff --git a/docs/Configuration.md b/docs/Configuration.md index 8035bb5c8278..a74e757b5281 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -261,7 +261,7 @@ Jest will fail if: Default: `undefined` -This option allows the use of a custom dependency extractor. It must be a node module that exports a function expecting a string as the first argument for the code to analyze and Jest's dependency extractor as the second argument (in case you only want to extend it). +This option allows the use of a custom dependency extractor. It must be a node module that exports an object with an `extract` function expecting a string as the first argument for the code to analyze and Jest's dependency extractor as the second argument (in case you only want to extend it). The function should return an iterable (`Array`, `Set`, etc.) with the dependencies found in the code. diff --git a/e2e/__tests__/find_related_files.test.js b/e2e/__tests__/find_related_files.test.js index f7ba19cf16bf..a9ddf9f2c3c7 100644 --- a/e2e/__tests__/find_related_files.test.js +++ b/e2e/__tests__/find_related_files.test.js @@ -53,14 +53,16 @@ describe('--findRelatedTests flag', () => { 'a.js': 'module.exports = {foo: 5};', 'dependencyExtractor.js': ` const DYNAMIC_IMPORT_RE = /(?:^|[^.]\\s*)(\\bdynamicImport\\s*?\\(\\s*?)([\`'"])([^\`'"]+)(\\2\\s*?\\))/g; - module.exports = function dependencyExtractor(code) { - const dependencies = new Set(); - const addDependency = (match, pre, quot, dep, post) => { - dependencies.add(dep); - return match; - }; - code.replace(DYNAMIC_IMPORT_RE, addDependency); - return dependencies; + module.exports = { + extract(code) { + const dependencies = new Set(); + const addDependency = (match, pre, quot, dep, post) => { + dependencies.add(dep); + return match; + }; + code.replace(DYNAMIC_IMPORT_RE, addDependency); + return dependencies; + }, }; `, 'package.json': JSON.stringify({ diff --git a/packages/jest-haste-map/src/__tests__/dependencyExtractor.js b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js index 3e872ae3227e..d8241394a89f 100644 --- a/packages/jest-haste-map/src/__tests__/dependencyExtractor.js +++ b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js @@ -11,10 +11,7 @@ const blockCommentRe = /\/\*[^]*?\*\//g; const lineCommentRe = /\/\/.*/g; const LOAD_MODULE_RE = /(?:^|[^.]\s*)(\bloadModule\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g; -module.exports = function dependencyExtractor( - code, - defaultDependencyExtractor, -) { +export function extract(code, defaultDependencyExtractor) { const dependencies = defaultDependencyExtractor(code); const addDependency = (match, pre, quot, dep, post) => { @@ -28,4 +25,4 @@ module.exports = function dependencyExtractor( .replace(LOAD_MODULE_RE, addDependency); return dependencies; -}; +} diff --git a/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js similarity index 97% rename from packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js rename to packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js index a349d083735e..085b0f6f4c21 100644 --- a/packages/jest-haste-map/src/lib/__tests__/extractRequires.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js @@ -9,7 +9,7 @@ */ 'use strict'; -import extractRequires from '../extractRequires'; +import {extract as extractRequires} from '../dependencyExtractor'; it('extracts both requires and imports from code', () => { const code = ` diff --git a/packages/jest-haste-map/src/lib/extractRequires.js b/packages/jest-haste-map/src/lib/dependencyExtractor.js similarity index 95% rename from packages/jest-haste-map/src/lib/extractRequires.js rename to packages/jest-haste-map/src/lib/dependencyExtractor.js index dfdcece33a29..c41393b2bb85 100644 --- a/packages/jest-haste-map/src/lib/extractRequires.js +++ b/packages/jest-haste-map/src/lib/dependencyExtractor.js @@ -18,7 +18,7 @@ const replacePatterns = { REQUIRE_RE: /(?:^|[^.]\s*)(\brequire\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g, }; -export default function extractRequires(code: string): Set { +export function extract(code: string): Set { const dependencies = new Set(); const addDependency = (match, pre, quot, dep, post) => { dependencies.add(dep); diff --git a/packages/jest-haste-map/src/worker.js b/packages/jest-haste-map/src/worker.js index 6096372a6aa2..51388240e377 100644 --- a/packages/jest-haste-map/src/worker.js +++ b/packages/jest-haste-map/src/worker.js @@ -14,7 +14,7 @@ import path from 'path'; import fs from 'graceful-fs'; import blacklist from './blacklist'; import H from './constants'; -import extractRequires from './lib/extractRequires'; +import * as dependencyExtractor from './lib/dependencyExtractor'; const PACKAGE_JSON = path.sep + 'package.json'; @@ -81,8 +81,11 @@ export async function worker(data: WorkerMessage): Promise { dependencies = Array.from( data.dependencyExtractor ? // $FlowFixMe - require(data.dependencyExtractor)(content, extractRequires) - : extractRequires(content), + require(data.dependencyExtractor).extract( + content, + dependencyExtractor.extract, + ) + : dependencyExtractor.extract(content), ); } From 49d08403a941e596eda1279c07a1eaf4d4a73dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 9 Nov 2018 16:31:29 +0000 Subject: [PATCH 39/45] Accept getCacheKey for dependencyExtractor and hasteImplModulePath (#7350) --- CHANGELOG.md | 3 ++- docs/Configuration.md | 2 ++ .../src/__tests__/dependencyExtractor.js | 10 ++++++++ .../src/__tests__/haste_impl.js | 9 +++++++ .../src/__tests__/index.test.js | 25 +++++++++++++++++++ packages/jest-haste-map/src/index.js | 22 ++++++++++++++++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdfa4d189221..452deb95efe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,9 @@ - `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203)) - `[expect]` Check constructor equality in .toStrictEqual() ([#7005](https://github.com/facebook/jest/pull/7005)) - `[jest-util]` Add `jest.getTimerCount()` to get the count of scheduled fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) -- `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313), [#7349](https://github.com/facebook/jest/pull/7349)). +- `[jest-config]` Add `dependencyExtractor` option to use a custom module to extract dependencies from files ([#7313](https://github.com/facebook/jest/pull/7313), [#7349](https://github.com/facebook/jest/pull/7349), [#7350](https://github.com/facebook/jest/pull/7350)) - `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321)) +- `[jest-haste-map]` Accept a `getCacheKey` method in `hasteImplModulePath` modules to reset the cache when the logic changes ([#7350](https://github.com/facebook/jest/pull/7350)) - `[jest-config]` Add `haste.computeSha1` option to compute the sha-1 of the files in the haste map ([#7345](https://github.com/facebook/jest/pull/7345)) ### Fixes diff --git a/docs/Configuration.md b/docs/Configuration.md index a74e757b5281..8cc5493f7864 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -265,6 +265,8 @@ This option allows the use of a custom dependency extractor. It must be a node m The function should return an iterable (`Array`, `Set`, etc.) with the dependencies found in the code. +That module can also contain a `getCacheKey` function to generate a cache key to determine if the logic has changed and any cached artifacts relying on it should be discarded. + ### `errorOnDeprecated` [boolean] Default: `false` diff --git a/packages/jest-haste-map/src/__tests__/dependencyExtractor.js b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js index d8241394a89f..a1d8e5bbc6db 100644 --- a/packages/jest-haste-map/src/__tests__/dependencyExtractor.js +++ b/packages/jest-haste-map/src/__tests__/dependencyExtractor.js @@ -26,3 +26,13 @@ export function extract(code, defaultDependencyExtractor) { return dependencies; } + +let cacheKey; + +export function getCacheKey() { + return cacheKey; +} + +export function setCacheKey(key) { + cacheKey = key; +} diff --git a/packages/jest-haste-map/src/__tests__/haste_impl.js b/packages/jest-haste-map/src/__tests__/haste_impl.js index 368879354ac2..ce58fef46fee 100644 --- a/packages/jest-haste-map/src/__tests__/haste_impl.js +++ b/packages/jest-haste-map/src/__tests__/haste_impl.js @@ -7,8 +7,13 @@ 'use strict'; const path = require('path'); +let cacheKey; module.exports = { + getCacheKey() { + return cacheKey; + }, + getHasteName(filename) { if ( filename.includes('__mocks__') || @@ -23,4 +28,8 @@ module.exports = { .substr(filename.lastIndexOf(path.sep) + 1) .replace(/(\.(android|ios|native))?\.js$/, ''); }, + + setCacheKey(key) { + cacheKey = key; + }, }; diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index 0429634bdf42..79383443fff5 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -232,6 +232,31 @@ describe('HasteMap', () => { expect(hasteMap1.getCacheFilePath()).not.toBe(hasteMap2.getCacheFilePath()); }); + it('creates different cache file paths for different dependency extractor cache keys', () => { + jest.resetModuleRegistry(); + const HasteMap = require('../'); + const dependencyExtractor = require('./dependencyExtractor'); + const config = Object.assign({}, defaultConfig, { + dependencyExtractor: require.resolve('./dependencyExtractor'), + }); + dependencyExtractor.setCacheKey('foo'); + const hasteMap1 = new HasteMap(config); + dependencyExtractor.setCacheKey('bar'); + const hasteMap2 = new HasteMap(config); + expect(hasteMap1.getCacheFilePath()).not.toBe(hasteMap2.getCacheFilePath()); + }); + + it('creates different cache file paths for different hasteImplModulePath cache keys', () => { + jest.resetModuleRegistry(); + const HasteMap = require('../'); + const hasteImpl = require('./haste_impl'); + hasteImpl.setCacheKey('foo'); + const hasteMap1 = new HasteMap(defaultConfig); + hasteImpl.setCacheKey('bar'); + const hasteMap2 = new HasteMap(defaultConfig); + expect(hasteMap1.getCacheFilePath()).not.toBe(hasteMap2.getCacheFilePath()); + }); + it('creates different cache file paths for different projects', () => { jest.resetModuleRegistry(); const HasteMap = require('../'); diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index d31d8f2188ff..ef5392efd5fe 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -261,10 +261,30 @@ class HasteMap extends EventEmitter { 'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.', ); } + const rootDirHash = crypto .createHash('md5') .update(options.rootDir) .digest('hex'); + let hasteImplHash = ''; + let dependencyExtractorHash = ''; + + if (options.hasteImplModulePath) { + // $FlowFixMe: dynamic require + const hasteImpl = require(options.hasteImplModulePath); + if (hasteImpl.getCacheKey) { + hasteImplHash = String(hasteImpl.getCacheKey()); + } + } + + if (options.dependencyExtractor) { + // $FlowFixMe: dynamic require + const dependencyExtractor = require(options.dependencyExtractor); + if (dependencyExtractor.getCacheKey) { + dependencyExtractorHash = String(dependencyExtractor.getCacheKey()); + } + } + this._cachePath = HasteMap.getCacheFilePath( this._options.cacheDirectory, `haste-map-${this._options.name}-${rootDirHash}`, @@ -278,6 +298,8 @@ class HasteMap extends EventEmitter { this._options.computeSha1.toString(), options.mocksPattern || '', (options.ignorePattern || '').toString(), + hasteImplHash, + dependencyExtractorHash, ); this._whitelist = getWhiteList(options.providesModuleNodeModules); this._buildPromise = null; From 5b7c75d4c36f60578ef29175cac09901eefb613d Mon Sep 17 00:00:00 2001 From: Terrence Wong Date: Fri, 9 Nov 2018 19:48:40 +0100 Subject: [PATCH 40/45] Add react testing library example (#7346) * docs: add react-testing-library example * chore: rename test files to match comments in docs * docs: show react-testing-library example first then enzyme --- docs/TutorialReact.md | 36 +++++++++++++++++-- ...abel.test.js => CheckboxWithLabel-test.js} | 0 examples/react-testing-library/.babelrc | 3 ++ .../CheckboxWithLabel.js | 31 ++++++++++++++++ .../__tests__/CheckboxWithLabel-test.js | 20 +++++++++++ examples/react-testing-library/package.json | 19 ++++++++++ ...abel.test.js => CheckboxWithLabel-test.js} | 0 ...el.test.tsx => CheckboxWithLabel-test.tsx} | 0 yarn.lock | 26 ++++++++++++++ 9 files changed, 132 insertions(+), 3 deletions(-) rename examples/enzyme/__tests__/{checkbox_with_label.test.js => CheckboxWithLabel-test.js} (100%) create mode 100644 examples/react-testing-library/.babelrc create mode 100644 examples/react-testing-library/CheckboxWithLabel.js create mode 100644 examples/react-testing-library/__tests__/CheckboxWithLabel-test.js create mode 100644 examples/react-testing-library/package.json rename examples/react/__tests__/{checkbox_with_label.test.js => CheckboxWithLabel-test.js} (100%) rename examples/typescript/__tests__/{checkbox_with_label.test.tsx => CheckboxWithLabel-test.tsx} (100%) diff --git a/docs/TutorialReact.md b/docs/TutorialReact.md index bd143617a019..039fcb10ab34 100644 --- a/docs/TutorialReact.md +++ b/docs/TutorialReact.md @@ -208,9 +208,11 @@ React 16 triggers these warnings due to how it checks element types, and the moc ### DOM Testing -If you'd like to assert, and manipulate your rendered components you can use [Enzyme](http://airbnb.io/enzyme/) or React's [TestUtils](http://facebook.github.io/react/docs/test-utils.html). We use Enzyme for this example. +If you'd like to assert, and manipulate your rendered components you can use [react-testing-library](https://github.com/kentcdodds/react-testing-library), [Enzyme](http://airbnb.io/enzyme/), or React's [TestUtils](http://facebook.github.io/react/docs/test-utils.html). The following two examples use react-testing-library and Enzyme. -You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React version below 15.5.0, you will also need to install `react-addons-test-utils`. +#### react-testing-library + +You have to run `yarn add --dev react-testing-library` to use react-testing-library. Let's implement a simple checkbox which swaps between two labels: @@ -248,7 +250,35 @@ export default class CheckboxWithLabel extends React.Component { } ``` -We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. +```javascript +// __tests__/CheckboxWithLabel-test.js +import React from 'react'; +import {render, fireEvent, cleanup} from 'react-testing-library'; +import CheckboxWithLabel from '../CheckboxWithLabel'; + +// automatically unmount and cleanup DOM after the test is finished. +afterEach(cleanup); + +it('CheckboxWithLabel changes the text after click', () => { + const {queryByLabelText, getByLabelText} = render( + , + ); + + expect(queryByLabelText(/off/i)).toBeTruthy(); + + fireEvent.click(getByLabelText(/off/i)); + + expect(queryByLabelText(/on/i)).toBeTruthy(); +}); +``` + +The code for this example is available at [examples/react-testing-library](https://github.com/facebook/jest/tree/master/examples/react-testing-library). + +#### Enzyme + +You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React version below 15.5.0, you will also need to install `react-addons-test-utils`. + +Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. ```javascript // __tests__/CheckboxWithLabel-test.js diff --git a/examples/enzyme/__tests__/checkbox_with_label.test.js b/examples/enzyme/__tests__/CheckboxWithLabel-test.js similarity index 100% rename from examples/enzyme/__tests__/checkbox_with_label.test.js rename to examples/enzyme/__tests__/CheckboxWithLabel-test.js diff --git a/examples/react-testing-library/.babelrc b/examples/react-testing-library/.babelrc new file mode 100644 index 000000000000..4ffef06dbfb5 --- /dev/null +++ b/examples/react-testing-library/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env", "react"] +} diff --git a/examples/react-testing-library/CheckboxWithLabel.js b/examples/react-testing-library/CheckboxWithLabel.js new file mode 100644 index 000000000000..ccad8995d978 --- /dev/null +++ b/examples/react-testing-library/CheckboxWithLabel.js @@ -0,0 +1,31 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +import React from 'react'; + +export default class CheckboxWithLabel extends React.Component { + constructor(props) { + super(props); + this.state = {isChecked: false}; + + // bind manually because React class components don't auto-bind + // http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding + this.onChange = this.onChange.bind(this); + } + + onChange() { + this.setState({isChecked: !this.state.isChecked}); + } + + render() { + return ( + + ); + } +} diff --git a/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js b/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js new file mode 100644 index 000000000000..cd3cf4832b94 --- /dev/null +++ b/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js @@ -0,0 +1,20 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +import React from 'react'; +import {render, fireEvent, cleanup} from 'react-testing-library'; +import CheckboxWithLabel from '../CheckboxWithLabel'; + +// automatically unmount and cleanup DOM after the test is finished. +afterEach(cleanup); + +it('CheckboxWithLabel changes the text after click', () => { + const {queryByLabelText, getByLabelText} = render( + + ); + + expect(queryByLabelText(/off/i)).toBeTruthy(); + + fireEvent.click(getByLabelText(/off/i)); + + expect(queryByLabelText(/on/i)).toBeTruthy(); +}); diff --git a/examples/react-testing-library/package.json b/examples/react-testing-library/package.json new file mode 100644 index 000000000000..7d634962515f --- /dev/null +++ b/examples/react-testing-library/package.json @@ -0,0 +1,19 @@ +{ + "private": true, + "version": "0.0.0", + "name": "example-react-testing-library", + "dependencies": { + "react": "16.4.1", + "react-dom": "16.4.1" + }, + "devDependencies": { + "babel-jest": "*", + "babel-preset-env": "*", + "babel-preset-react": "*", + "react-testing-library": "*", + "jest": "*" + }, + "scripts": { + "test": "jest" + } +} diff --git a/examples/react/__tests__/checkbox_with_label.test.js b/examples/react/__tests__/CheckboxWithLabel-test.js similarity index 100% rename from examples/react/__tests__/checkbox_with_label.test.js rename to examples/react/__tests__/CheckboxWithLabel-test.js diff --git a/examples/typescript/__tests__/checkbox_with_label.test.tsx b/examples/typescript/__tests__/CheckboxWithLabel-test.tsx similarity index 100% rename from examples/typescript/__tests__/checkbox_with_label.test.tsx rename to examples/typescript/__tests__/CheckboxWithLabel-test.tsx diff --git a/yarn.lock b/yarn.lock index d6dccc600b98..6e6fb15d740c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1386,6 +1386,11 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz#54c5a964462be3d4d78af631363c18d6fa91ac26" integrity sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw== +"@sheerun/mutationobserver-shim@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" + integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q== + "@types/cheerio@^0.22.8": version "0.22.9" resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.9.tgz#b5990152604c2ada749b7f88cab3476f21f39d7b" @@ -4899,6 +4904,15 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype "~1.1.1" entities "~1.1.1" +dom-testing-library@^3.12.0: + version "3.12.3" + resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.12.3.tgz#16c2fbd5198e175cb5499dabf9c64a893724015e" + integrity sha512-HvoxiKm8s4Gf+T52MX+gYHKXkGBM4ZiKYElIZxt8zPZtbT3wokrjKHskzryRqRD3oAKeg6chtUe3gchrurhmvA== + dependencies: + "@sheerun/mutationobserver-shim" "^0.3.2" + pretty-format "^23.6.0" + wait-for-expect "^1.0.0" + dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" @@ -11304,6 +11318,13 @@ react-test-renderer@*, react-test-renderer@^16.0.0-0: react-is "^16.5.2" schedule "^0.5.0" +react-testing-library@*: + version "5.2.3" + resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-5.2.3.tgz#c3be44bfa5eb1ba2acc1fb218785c40ebbdfe8ed" + integrity sha512-Bw52++7uORuIQnL55lK/WQfppqAc9+8yFG4lWUp/kmSOvYDnt8J9oI5fNCfAGSQi9iIhAv9aNsI2G5rtid0nrA== + dependencies: + dom-testing-library "^3.12.0" + react-timer-mixin@^0.13.2: version "0.13.4" resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz#75a00c3c94c13abe29b43d63b4c65a88fc8264d3" @@ -13844,6 +13865,11 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +wait-for-expect@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.0.1.tgz#73ab346ed56ed2ef66c380a59fd623755ceac0ce" + integrity sha512-TPZMSxGWUl2DWmqdspLDEy97/S1Mqq0pzbh2A7jTq0WbJurUb5GKli+bai6ayeYdeWTF0rQNWZmUvCVZ9gkrfA== + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" From 06bf664843fdf39007f432d85a5a0b22e438188a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Ma=C5=82kowski?= Date: Wed, 14 Nov 2018 16:28:36 +0700 Subject: [PATCH 41/45] chore: Standardize file names in packages/jest-worker and packages/pretty-format (#7316) * Rename jest-worker woker * rename in pretty-format/src/plugins/lib/escape_html.js * Update CHANGELOG * Rename with git mv * Code review fixes * Rename plugins and clean up exports * Fix formatting issue * Remove exports from AsymmetricMatcher * Revert remove exports for test/serialize * Change getPrettyPrint to default export * Fix require default --- CHANGELOG.md | 2 ++ jest.config.js | 4 ++-- packages/jest-worker/README.md | 6 +++--- packages/jest-worker/src/{worker.js => Worker.js} | 0 .../__tests__/{worker.test.js => Worker.test.js} | 2 +- packages/jest-worker/src/__tests__/index.test.js | 4 ++-- packages/jest-worker/src/index.js | 2 +- packages/jest-worker/src/types.js | 2 +- packages/pretty-format/perf/test.js | 2 +- ...c_matcher.test.js => AsymmetricMatcher.test.js} | 0 .../{convert_ansi.test.js => ConvertAnsi.test.js} | 0 ...om_collection.test.js => DOMCollection.test.js} | 2 +- .../{dom_element.test.js => DOMElement.test.js} | 2 +- .../{immutable.test.js => Immutable.test.js} | 2 +- .../{expect_util.js => getPrettyPrint.js} | 4 +++- ...{pretty_format.test.js => prettyFormat.test.js} | 0 packages/pretty-format/src/index.js | 14 +++++++------- ...{asymmetric_matcher.js => AsymmetricMatcher.js} | 0 .../plugins/{convert_ansi.js => ConvertAnsi.js} | 0 .../{dom_collection.js => DOMCollection.js} | 0 .../src/plugins/{dom_element.js => DOMElement.js} | 0 .../src/plugins/{immutable.js => Immutable.js} | 0 .../plugins/{react_element.js => ReactElement.js} | 0 ...act_test_component.js => ReactTestComponent.js} | 0 .../plugins/lib/{escape_html.js => escapeHTML.js} | 0 packages/pretty-format/src/plugins/lib/markup.js | 2 +- 26 files changed, 27 insertions(+), 23 deletions(-) rename packages/jest-worker/src/{worker.js => Worker.js} (100%) rename packages/jest-worker/src/__tests__/{worker.test.js => Worker.test.js} (99%) rename packages/pretty-format/src/__tests__/{asymmetric_matcher.test.js => AsymmetricMatcher.test.js} (100%) rename packages/pretty-format/src/__tests__/{convert_ansi.test.js => ConvertAnsi.test.js} (100%) rename packages/pretty-format/src/__tests__/{dom_collection.test.js => DOMCollection.test.js} (98%) rename packages/pretty-format/src/__tests__/{dom_element.test.js => DOMElement.test.js} (99%) rename packages/pretty-format/src/__tests__/{immutable.test.js => Immutable.test.js} (99%) rename packages/pretty-format/src/__tests__/{expect_util.js => getPrettyPrint.js} (95%) rename packages/pretty-format/src/__tests__/{pretty_format.test.js => prettyFormat.test.js} (100%) rename packages/pretty-format/src/plugins/{asymmetric_matcher.js => AsymmetricMatcher.js} (100%) rename packages/pretty-format/src/plugins/{convert_ansi.js => ConvertAnsi.js} (100%) rename packages/pretty-format/src/plugins/{dom_collection.js => DOMCollection.js} (100%) rename packages/pretty-format/src/plugins/{dom_element.js => DOMElement.js} (100%) rename packages/pretty-format/src/plugins/{immutable.js => Immutable.js} (100%) rename packages/pretty-format/src/plugins/{react_element.js => ReactElement.js} (100%) rename packages/pretty-format/src/plugins/{react_test_component.js => ReactTestComponent.js} (100%) rename packages/pretty-format/src/plugins/lib/{escape_html.js => escapeHTML.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 452deb95efe1..257e66b24706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,8 @@ - `[docs]` Add correct default value for `testUrl` config option ([#7277](https://github.com/facebook/jest/pull/7277)) - `[jest-util]` [**BREAKING**] Remove long-deprecated globals for fake timers ([#7285](https://github.com/facebook/jest/pull/7285)) - `[docs]` Remove duplicate code in `MockFunctions` ([#7297](https://github.com/facebook/jest/pull/7297)) +- `[jest-worker]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) +- `[pretty-format]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) ### Performance diff --git a/jest.config.js b/jest.config.js index 9c16175c878b..9a7e9b0808ce 100644 --- a/jest.config.js +++ b/jest.config.js @@ -25,7 +25,7 @@ module.exports = { projects: ['', '/examples/*/'], setupFilesAfterEnv: ['/testSetupFile.js'], snapshotSerializers: [ - '/packages/pretty-format/build/plugins/convert_ansi.js', + '/packages/pretty-format/build/plugins/ConvertAnsi.js', ], testEnvironment: './packages/jest-environment-node', testPathIgnorePatterns: [ @@ -35,7 +35,7 @@ module.exports = { '\\.snap$', '/packages/.*/build', '/packages/.*/build-es5', - '/packages/.*/src/__tests__/expect_util.js', + '/packages/.*/src/__tests__/getPrettyPrint.js', '/packages/jest-cli/src/__tests__/test_root', '/packages/jest-cli/src/__tests__/__fixtures__/', '/packages/jest-cli/src/lib/__tests__/fixtures/', diff --git a/packages/jest-worker/README.md b/packages/jest-worker/README.md index 5087287be92a..3c98dfdb2b5e 100644 --- a/packages/jest-worker/README.md +++ b/packages/jest-worker/README.md @@ -24,7 +24,7 @@ This example covers the minimal usage: import Worker from 'jest-worker'; async function main() { - const worker = new Worker(require.resolve('./worker')); + const worker = new Worker(require.resolve('./Worker')); const result = await worker.hello('Alice'); // "Hello, Alice" } @@ -114,7 +114,7 @@ This example covers the standard usage: import Worker from 'jest-worker'; async function main() { - const myWorker = new Worker(require.resolve('./worker'), { + const myWorker = new Worker(require.resolve('./Worker'), { exposedMethods: ['foo', 'bar', 'getWorkerId'], numWorkers: 4, }); @@ -155,7 +155,7 @@ This example covers the usage with a `computeWorkerKey` method: import Worker from 'jest-worker'; async function main() { - const myWorker = new Worker(require.resolve('./worker'), { + const myWorker = new Worker(require.resolve('./Worker'), { computeWorkerKey: (method, filename) => filename, }); diff --git a/packages/jest-worker/src/worker.js b/packages/jest-worker/src/Worker.js similarity index 100% rename from packages/jest-worker/src/worker.js rename to packages/jest-worker/src/Worker.js diff --git a/packages/jest-worker/src/__tests__/worker.test.js b/packages/jest-worker/src/__tests__/Worker.test.js similarity index 99% rename from packages/jest-worker/src/__tests__/worker.test.js rename to packages/jest-worker/src/__tests__/Worker.test.js index 4fd91d9e3de6..cad8347df5b9 100644 --- a/packages/jest-worker/src/__tests__/worker.test.js +++ b/packages/jest-worker/src/__tests__/Worker.test.js @@ -38,7 +38,7 @@ beforeEach(() => { return forkInterface; }); - Worker = require('../worker').default; + Worker = require('../Worker').default; }); afterEach(() => { diff --git a/packages/jest-worker/src/__tests__/index.test.js b/packages/jest-worker/src/__tests__/index.test.js index 349a91797b5f..ba49151b6ec2 100644 --- a/packages/jest-worker/src/__tests__/index.test.js +++ b/packages/jest-worker/src/__tests__/index.test.js @@ -30,7 +30,7 @@ beforeEach(() => { // The worker mock returns a worker with custom methods, plus it stores them // in a global list, so that they can be accessed later. This list is reset in // every test. - jest.mock('../worker', () => { + jest.mock('../Worker', () => { const fakeClass = jest.fn(() => { const fakeWorker = { getStderr: () => ({once() {}, pipe() {}}), @@ -63,7 +63,7 @@ beforeEach(() => { virtual: true, }); - Worker = require('../worker').default; + Worker = require('../Worker').default; Farm = require('../index').default; }); diff --git a/packages/jest-worker/src/index.js b/packages/jest-worker/src/index.js index 0cb636c2fc6c..be634f2fecbd 100644 --- a/packages/jest-worker/src/index.js +++ b/packages/jest-worker/src/index.js @@ -17,7 +17,7 @@ import type {FarmOptions} from './types'; import type {Readable} from 'stream'; import {CHILD_MESSAGE_CALL, CHILD_MESSAGE_END} from './types'; -import Worker from './worker'; +import Worker from './Worker'; /* istanbul ignore next */ const emptyMethod = () => {}; diff --git a/packages/jest-worker/src/types.js b/packages/jest-worker/src/types.js index a8afc71f9f58..5d7108f9fb30 100644 --- a/packages/jest-worker/src/types.js +++ b/packages/jest-worker/src/types.js @@ -29,7 +29,7 @@ export type PARENT_MESSAGE_ERROR = // Option objects. -import type Worker from './worker'; +import type Worker from './Worker'; export type ForkOptions = { cwd?: string, diff --git a/packages/pretty-format/perf/test.js b/packages/pretty-format/perf/test.js index 9bc97b44099f..e8ac99df480c 100644 --- a/packages/pretty-format/perf/test.js +++ b/packages/pretty-format/perf/test.js @@ -12,7 +12,7 @@ const React = require('react'); const ReactTestRenderer = require('react-test-renderer'); const leftPad = require('left-pad'); const prettyFormat = require('../build'); -const ReactTestComponent = require('../build/plugins/react_test_component'); +const ReactTestComponent = require('../build/plugins/ReactTestComponent'); const worldGeoJson = require('./world.geo.json'); const NANOSECONDS = 1000000000; diff --git a/packages/pretty-format/src/__tests__/asymmetric_matcher.test.js b/packages/pretty-format/src/__tests__/AsymmetricMatcher.test.js similarity index 100% rename from packages/pretty-format/src/__tests__/asymmetric_matcher.test.js rename to packages/pretty-format/src/__tests__/AsymmetricMatcher.test.js diff --git a/packages/pretty-format/src/__tests__/convert_ansi.test.js b/packages/pretty-format/src/__tests__/ConvertAnsi.test.js similarity index 100% rename from packages/pretty-format/src/__tests__/convert_ansi.test.js rename to packages/pretty-format/src/__tests__/ConvertAnsi.test.js diff --git a/packages/pretty-format/src/__tests__/dom_collection.test.js b/packages/pretty-format/src/__tests__/DOMCollection.test.js similarity index 98% rename from packages/pretty-format/src/__tests__/dom_collection.test.js rename to packages/pretty-format/src/__tests__/DOMCollection.test.js index cf0d498f8b18..204068c2561c 100644 --- a/packages/pretty-format/src/__tests__/dom_collection.test.js +++ b/packages/pretty-format/src/__tests__/DOMCollection.test.js @@ -13,7 +13,7 @@ const prettyFormat = require('../'); const {DOMCollection, DOMElement} = prettyFormat.plugins; -const toPrettyPrintTo = require('./expect_util').getPrettyPrint([ +const toPrettyPrintTo = require('./getPrettyPrint').default([ DOMCollection, DOMElement, ]); diff --git a/packages/pretty-format/src/__tests__/dom_element.test.js b/packages/pretty-format/src/__tests__/DOMElement.test.js similarity index 99% rename from packages/pretty-format/src/__tests__/dom_element.test.js rename to packages/pretty-format/src/__tests__/DOMElement.test.js index 9b06b105766c..e211b33665d9 100644 --- a/packages/pretty-format/src/__tests__/dom_element.test.js +++ b/packages/pretty-format/src/__tests__/DOMElement.test.js @@ -13,7 +13,7 @@ const prettyFormat = require('../'); const {DOMElement} = prettyFormat.plugins; -const toPrettyPrintTo = require('./expect_util').getPrettyPrint([DOMElement]); +const toPrettyPrintTo = require('./getPrettyPrint').default([DOMElement]); const expect: any = global.expect; expect.extend({toPrettyPrintTo}); diff --git a/packages/pretty-format/src/__tests__/immutable.test.js b/packages/pretty-format/src/__tests__/Immutable.test.js similarity index 99% rename from packages/pretty-format/src/__tests__/immutable.test.js rename to packages/pretty-format/src/__tests__/Immutable.test.js index b402605cf85c..4e0e40cf91e7 100644 --- a/packages/pretty-format/src/__tests__/immutable.test.js +++ b/packages/pretty-format/src/__tests__/Immutable.test.js @@ -11,7 +11,7 @@ import React from 'react'; import Immutable from 'immutable'; -import {getPrettyPrint} from './expect_util'; +import getPrettyPrint from './getPrettyPrint'; const {plugins: prettyPlugins} = require('..'); const {Immutable: ImmutablePlugin, ReactElement} = prettyPlugins; diff --git a/packages/pretty-format/src/__tests__/expect_util.js b/packages/pretty-format/src/__tests__/getPrettyPrint.js similarity index 95% rename from packages/pretty-format/src/__tests__/expect_util.js rename to packages/pretty-format/src/__tests__/getPrettyPrint.js index 1fb9a1dc0d8b..5ee5ee04929b 100644 --- a/packages/pretty-format/src/__tests__/expect_util.js +++ b/packages/pretty-format/src/__tests__/getPrettyPrint.js @@ -14,7 +14,7 @@ import type {OptionsReceived, Plugins} from 'types/PrettyFormat'; const diff = require('jest-diff'); const prettyFormat = require('../'); -export const getPrettyPrint = (plugins: Plugins) => +const getPrettyPrint = (plugins: Plugins) => function(received: any, expected: any, options?: OptionsReceived) { const prettyFormatted = prettyFormat( received, @@ -52,3 +52,5 @@ export const getPrettyPrint = (plugins: Plugins) => return {actual: prettyFormatted, message, pass}; }; + +export default getPrettyPrint; diff --git a/packages/pretty-format/src/__tests__/pretty_format.test.js b/packages/pretty-format/src/__tests__/prettyFormat.test.js similarity index 100% rename from packages/pretty-format/src/__tests__/pretty_format.test.js rename to packages/pretty-format/src/__tests__/prettyFormat.test.js diff --git a/packages/pretty-format/src/index.js b/packages/pretty-format/src/index.js index 3c193f1a17d3..618a6fc62971 100644 --- a/packages/pretty-format/src/index.js +++ b/packages/pretty-format/src/index.js @@ -28,13 +28,13 @@ import { printObjectProperties, } from './collections'; -import AsymmetricMatcher from './plugins/asymmetric_matcher'; -import ConvertAnsi from './plugins/convert_ansi'; -import DOMCollection from './plugins/dom_collection'; -import DOMElement from './plugins/dom_element'; -import Immutable from './plugins/immutable'; -import ReactElement from './plugins/react_element'; -import ReactTestComponent from './plugins/react_test_component'; +import AsymmetricMatcher from './plugins/AsymmetricMatcher'; +import ConvertAnsi from './plugins/ConvertAnsi'; +import DOMCollection from './plugins/DOMCollection'; +import DOMElement from './plugins/DOMElement'; +import Immutable from './plugins/Immutable'; +import ReactElement from './plugins/ReactElement'; +import ReactTestComponent from './plugins/ReactTestComponent'; const toString = Object.prototype.toString; const toISOString = Date.prototype.toISOString; diff --git a/packages/pretty-format/src/plugins/asymmetric_matcher.js b/packages/pretty-format/src/plugins/AsymmetricMatcher.js similarity index 100% rename from packages/pretty-format/src/plugins/asymmetric_matcher.js rename to packages/pretty-format/src/plugins/AsymmetricMatcher.js diff --git a/packages/pretty-format/src/plugins/convert_ansi.js b/packages/pretty-format/src/plugins/ConvertAnsi.js similarity index 100% rename from packages/pretty-format/src/plugins/convert_ansi.js rename to packages/pretty-format/src/plugins/ConvertAnsi.js diff --git a/packages/pretty-format/src/plugins/dom_collection.js b/packages/pretty-format/src/plugins/DOMCollection.js similarity index 100% rename from packages/pretty-format/src/plugins/dom_collection.js rename to packages/pretty-format/src/plugins/DOMCollection.js diff --git a/packages/pretty-format/src/plugins/dom_element.js b/packages/pretty-format/src/plugins/DOMElement.js similarity index 100% rename from packages/pretty-format/src/plugins/dom_element.js rename to packages/pretty-format/src/plugins/DOMElement.js diff --git a/packages/pretty-format/src/plugins/immutable.js b/packages/pretty-format/src/plugins/Immutable.js similarity index 100% rename from packages/pretty-format/src/plugins/immutable.js rename to packages/pretty-format/src/plugins/Immutable.js diff --git a/packages/pretty-format/src/plugins/react_element.js b/packages/pretty-format/src/plugins/ReactElement.js similarity index 100% rename from packages/pretty-format/src/plugins/react_element.js rename to packages/pretty-format/src/plugins/ReactElement.js diff --git a/packages/pretty-format/src/plugins/react_test_component.js b/packages/pretty-format/src/plugins/ReactTestComponent.js similarity index 100% rename from packages/pretty-format/src/plugins/react_test_component.js rename to packages/pretty-format/src/plugins/ReactTestComponent.js diff --git a/packages/pretty-format/src/plugins/lib/escape_html.js b/packages/pretty-format/src/plugins/lib/escapeHTML.js similarity index 100% rename from packages/pretty-format/src/plugins/lib/escape_html.js rename to packages/pretty-format/src/plugins/lib/escapeHTML.js diff --git a/packages/pretty-format/src/plugins/lib/markup.js b/packages/pretty-format/src/plugins/lib/markup.js index eb45835588a0..70ebceebc806 100644 --- a/packages/pretty-format/src/plugins/lib/markup.js +++ b/packages/pretty-format/src/plugins/lib/markup.js @@ -9,7 +9,7 @@ import type {Config, Printer, Refs} from 'types/PrettyFormat'; -import escapeHTML from './escape_html'; +import escapeHTML from './escapeHTML'; // Return empty string if keys is empty. export const printProps = ( From b7ee7bd324ea7aee5a7998a86e533304384150a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 15 Nov 2018 09:53:22 -0500 Subject: [PATCH 42/45] Add check for copyright headers (#7370) --- .circleci/config.yml | 2 +- CHANGELOG.md | 1 + package.json | 2 + scripts/checkCopyrightHeaders.js | 148 +++++++++++++++++++++++++++++++ yarn.lock | 2 +- 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100755 scripts/checkCopyrightHeaders.js diff --git a/.circleci/config.yml b/.circleci/config.yml index e3cadb0b6788..f7051b683e40 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: - restore-cache: *restore-cache - run: yarn --no-progress - save-cache: *save-cache - - run: yarn lint --format junit -o reports/junit/js-lint-results.xml && yarn typecheck && yarn lint-es5-build --format junit -o reports/junit/js-es5-lint-results.xml && yarn lint:md:ci + - run: yarn lint --format junit -o reports/junit/js-lint-results.xml && yarn typecheck && yarn lint-es5-build --format junit -o reports/junit/js-es5-lint-results.xml && yarn lint:md:ci && yarn check-copyright-headers - store_test_results: path: reports/junit diff --git a/CHANGELOG.md b/CHANGELOG.md index 257e66b24706..ccfa03859ae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,6 +109,7 @@ - `[docs]` Remove duplicate code in `MockFunctions` ([#7297](https://github.com/facebook/jest/pull/7297)) - `[jest-worker]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) - `[pretty-format]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) +- `[*]` Add check for Facebook copyright headers on CI ([#7370](https://github.com/facebook/jest/pull/7370)) ### Performance diff --git a/package.json b/package.json index 238af5ff7b8a..987d4eb37f73 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "flow-bin": "^0.85.0", "glob": "^7.1.1", "graceful-fs": "^4.1.11", + "isbinaryfile": "^3.0.3", "istanbul-api": "^1.3.1", "istanbul-lib-coverage": "^1.0.0", "jasmine-reporters": "^2.2.0", @@ -81,6 +82,7 @@ "scripts": { "build-clean": "rm -rf ./packages/*/build ./packages/*/build-es5", "build": "node ./scripts/build.js", + "check-copyright-headers": "node ./scripts/checkCopyrightHeaders.js", "clean-all": "rm -rf ./node_modules && rm -rf ./packages/*/node_modules && yarn clean-e2e && yarn build-clean", "clean-e2e": "find ./e2e -not \\( -path ./e2e/presets/js -prune \\) -not \\( -path ./e2e/presets/json -prune \\) -mindepth 2 -type d \\( -name node_modules -prune \\) -exec rm -r '{}' +", "jest": "node ./packages/jest-cli/bin/jest.js", diff --git a/scripts/checkCopyrightHeaders.js b/scripts/checkCopyrightHeaders.js new file mode 100755 index 000000000000..43ecbc7c7388 --- /dev/null +++ b/scripts/checkCopyrightHeaders.js @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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 fs = require('fs'); +const {execSync} = require('child_process'); +const isbinaryfile = require('isbinaryfile'); + +const getFileContents = path => fs.readFileSync(path, {encoding: 'utf-8'}); +const isDirectory = path => fs.lstatSync(path).isDirectory(); +const createRegExp = pattern => new RegExp(pattern); + +// Important: this patterns must be in sync with internal Facebook tools + +const GENERIC_IGNORED_EXTENSIONS = [ + 'lock', + 'patch', + 'exe', + 'bin', + 'cfg', + 'config', + 'conf', + 'html', + 'md', + 'markdown', + 'opam', + 'osm', + 'descr', + 'rst', + 'json', + 'key', + 'ini', + 'plist', + 'snap', + 'svg', + 'txt', + 'xcodeproj', + 'xcscheme', + 'xml', + 'yaml', + 'yml', + 'textile', + 'tsv', + 'csv', + 'pem', + 'csr', + 'der', + 'crt', + 'cert', + 'cer', + 'p7b', + 'iml', + 'org', + 'podspec', + 'modulemap', + 'pch', + 'lproj', + 'xcworkspace', + 'storyboard', + 'tvml', + 'xib', + 'pbxproj', + 'xcworkspacedata', + 'xccheckout', + 'xcsettings', + 'strings', + 'ipynb', + 'htm', + 'toml', +].map(extension => createRegExp(`\.${extension}$`)); + +const GENERIC_IGNORED_PATTERNS = [ + '(^|/)\\.[^/]+(/|$)', + + 'third[_\\-. ]party/', + '^node[_\\-. ]modules/', + 'gradlew\\.bat$', + 'gradlew$', + 'gradle/wrapper/', + '.idea/', + '__init__\\.py$', + '^Setup.hs$', + '^(readme|README|Readme)\\..*$', + 'Cargo\\.toml$', + '^Cartfile.*$', + '^.*\\.xcodeproj/$', + '^.*\\.xcworkspace/$', + '^.*\\.lproj/$', + '^.*\\.bundle/$', + '^MANIFEST\\.in$', +].map(createRegExp); + +const CUSTOM_IGNORED_PATTERNS = [ + '\\.(example|map)$', + '^examples/.*', + '^flow-typed/.*', + '^packages/expect/src/jasmineUtils\\.js$', + '^packages/jest-config/src/vendor/jsonlint\\.js$', +].map(createRegExp); + +const IGNORED_PATTERNS = [ + ...GENERIC_IGNORED_EXTENSIONS, + ...GENERIC_IGNORED_PATTERNS, + ...CUSTOM_IGNORED_PATTERNS, +]; + +const INCLUDED_PATTERNS = [ + // Any file with an extension + /\.[^/]+$/, +]; + +const COPYRIGHT_HEADER_RE = /(Facebook, Inc(.|,)? and its affiliates)|([0-9]{4}-present(.|,)? Facebook)|([0-9]{4}(.|,)? Facebook)/; + +function needsCopyrightHeader(file) { + const contents = getFileContents(file); + return contents.trim().length > 0 && !COPYRIGHT_HEADER_RE.test(contents); +} + +function check() { + const allFiles = execSync('git ls-files', {encoding: 'utf-8'}) + .trim() + .split('\n'); + + const invalidFiles = allFiles.filter( + file => + INCLUDED_PATTERNS.some(pattern => pattern.test(file)) && + !IGNORED_PATTERNS.some(pattern => pattern.test(file)) && + !isDirectory(file) && + !isbinaryfile.sync(file) && + needsCopyrightHeader(file) + ); + + if (invalidFiles.length > 0) { + console.log(`Facebook copyright header check failed for the following files: + + ${invalidFiles.join('\n ')} + +Please include the header or blacklist the files in \`scripts/checkCopyrightHeaders.js\``); + process.exit(1); + } +} + +check(); diff --git a/yarn.lock b/yarn.lock index 6e6fb15d740c..cfe08495395d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7819,7 +7819,7 @@ isarray@^2.0.4: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7" integrity sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA== -isbinaryfile@^3.0.0: +isbinaryfile@^3.0.0, isbinaryfile@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== From 7b62b080ba304128a058281d7c3a3165f3fd283d Mon Sep 17 00:00:00 2001 From: Simon Sarris Date: Fri, 16 Nov 2018 12:44:35 -0500 Subject: [PATCH 43/45] include npm command in addition to yarn command (#7371) * include npm command in addition to yarn command The page starts out with both `yarn` and `npm` language for install, so it should contain both commands when it comes time to run. Unsure about further commands in the page though. * Give yarn and npm equal mention * add newline for linter * jest-cli to jest in command Co-Authored-By: simonsarris * Note about jest documentation using yarn but either is OK * Update docs/GettingStarted.md Co-Authored-By: simonsarris --- docs/GettingStarted.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 86a42a5a9fa7..71c021b555a8 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -15,6 +15,8 @@ Or [`npm`](https://www.npmjs.com/): npm install --save-dev jest ``` +Note: Jest documentation uses `yarn` commands, but `npm` will also work. You can compare `yarn` and `npm` commands in the [yarn docs, here](https://yarnpkg.com/en/docs/migrating-from-npm#toc-cli-commands-comparison). + Let's get started by writing a test for a hypothetical function that adds two numbers. First, create a `sum.js` file: ```javascript @@ -44,7 +46,7 @@ Add the following section to your `package.json`: } ``` -Finally, run `yarn test` and Jest will print this message: +Finally, run `yarn test` or `npm run test` and Jest will print this message: ```bash PASS ./sum.test.js @@ -57,7 +59,7 @@ This test used `expect` and `toBe` to test that two values were exactly identica ## Running from command line -You can run Jest directly from the CLI (if it's globally available in your `PATH`, e.g. by `yarn global add jest`) with a variety of useful options. +You can run Jest directly from the CLI (if it's globally available in your `PATH`, e.g. by `yarn global add jest` or `npm install jest --global`) with a variety of useful options. Here's how to run Jest on files matching `my-test`, using `config.json` as a configuration file and display a native OS notification after the run: @@ -79,13 +81,19 @@ jest --init ### Using Babel -To use [Babel](http://babeljs.io/), install the `babel-jest` and `regenerator-runtime` packages: +To use [Babel](http://babeljs.io/), install the `babel-jest` and `regenerator-runtime` packages via `yarn`: ```bash yarn add --dev babel-jest babel-core regenerator-runtime ``` -> Note: If you are using Babel version 7 then you need to install `babel-jest`, `babel-core@^7.0.0-bridge.0` and `@babel/core` with the following command: +Or `npm`: + +```bash +npm install --save-dev babel-jest babel-core regenerator-runtime +``` + +> Note: If you are using Babel version 7 then you need to install `babel-jest`, `babel-core@^7.0.0-bridge.0` and `@babel/core` with the following command or its `npm` equivalent: > > ```bash > yarn add --dev babel-jest babel-core@^7.0.0-bridge.0 @babel/core regenerator-runtime From 819cae5f18b6dc99c16ee2fc4e2df4a93b782290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Mon, 19 Nov 2018 07:28:30 -0500 Subject: [PATCH 44/45] Improve dependency extractor (#7385) * Refactored dependency extractor * Refactored dependency extractor test * Update changelog * Fix headers and naming * Disable tests failing in Node <9 * Add feature detection to tests --- CHANGELOG.md | 2 + .../src/lib/__tests__/dependencyExtractor.js | 127 --------- .../lib/__tests__/dependencyExtractor.test.js | 267 ++++++++++++++++++ .../lib/__tests__/isRegExpSupported.test.js | 20 ++ .../src/lib/dependencyExtractor.js | 90 ++++-- .../src/lib/isRegExpSupported.js | 18 ++ 6 files changed, 380 insertions(+), 144 deletions(-) delete mode 100644 packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js create mode 100644 packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js create mode 100644 packages/jest-haste-map/src/lib/__tests__/isRegExpSupported.test.js create mode 100644 packages/jest-haste-map/src/lib/isRegExpSupported.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ccfa03859ae9..b4b9f192770a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ - `[expect]` Fix toMatchObject matcher when used with `Object.create(null)` ([#7334](https://github.com/facebook/jest/pull/7334)) - `[jest-haste-map]` [**BREAKING**] Recover files correctly after haste name collisions are fixed ([#7329](https://github.com/facebook/jest/pull/7329)) - `[jest-haste-map]` Remove legacy condition for duplicate module detection ([#7333](https://github.com/facebook/jest/pull/7333)) +- `[jest-haste-map]` Fix `require` detection with trailing commas and ignore `import typeof` modules ([#7385](https://github.com/facebook/jest/pull/7385)) ### Chore & Maintenance @@ -110,6 +111,7 @@ - `[jest-worker]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) - `[pretty-format]` Standardize filenames ([#7316](https://github.com/facebook/jest/pull/7316)) - `[*]` Add check for Facebook copyright headers on CI ([#7370](https://github.com/facebook/jest/pull/7370)) +- `[jest-haste-map]` Refactor `dependencyExtractor` and tests ([#7385](https://github.com/facebook/jest/pull/7385)) ### Performance diff --git a/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js deleted file mode 100644 index 085b0f6f4c21..000000000000 --- a/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * 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. - * - * @flow - */ -'use strict'; - -import {extract as extractRequires} from '../dependencyExtractor'; - -it('extracts both requires and imports from code', () => { - const code = ` - import module1 from 'module1'; - const module2 = require('module2'); - import('module3').then(module3 => {})'; - `; - - expect(extractRequires(code)).toEqual( - new Set(['module1', 'module2', 'module3']), - ); -}); - -it('extracts requires in order', () => { - const code = ` - const module1 = require('module1'); - const module2 = require('module2'); - const module3 = require('module3'); - `; - - expect(extractRequires(code)).toEqual( - new Set(['module1', 'module2', 'module3']), - ); -}); - -it('strips out comments from code', () => { - const code = `// comment const module2 = require('module2');`; - - expect(extractRequires(code)).toEqual(new Set([])); -}); - -it('ignores requires in comments', () => { - const code = [ - '// const module1 = require("module1");', - '/**', - ' * const module2 = require("module2");', - ' */', - ].join('\n'); - - expect(extractRequires(code)).toEqual(new Set([])); -}); - -it('ignores requires in comments with Windows line endings', () => { - const code = [ - '// const module1 = require("module1");', - '/**', - ' * const module2 = require("module2");', - ' */', - ].join('\r\n'); - - expect(extractRequires(code)).toEqual(new Set([])); -}); - -it('ignores requires in comments with unicode line endings', () => { - const code = [ - '// const module1 = require("module1");\u2028', - '// const module1 = require("module2");\u2029', - '/*\u2028', - 'const module2 = require("module3");\u2029', - ' */', - ].join(''); - - expect(extractRequires(code)).toEqual(new Set([])); -}); - -it('does not contain duplicates', () => { - const code = ` - const module1 = require('module1'); - const module1Dup = require('module1'); - `; - - expect(extractRequires(code)).toEqual(new Set(['module1'])); -}); - -it('ignores type imports', () => { - const code = [ - "import type foo from 'bar';", - 'import type {', - ' bar,', - ' baz,', - "} from 'wham'", - ].join('\r\n'); - - expect(extractRequires(code)).toEqual(new Set([])); -}); - -it('ignores type exports', () => { - const code = [ - 'export type Foo = number;', - 'export default {}', - "export * from 'module1'", - ].join('\r\n'); - - expect(extractRequires(code)).toEqual(new Set(['module1'])); -}); - -it('understands require.requireActual', () => { - const code = `require.requireActual('pizza');`; - expect(extractRequires(code)).toEqual(new Set(['pizza'])); -}); - -it('understands jest.requireActual', () => { - const code = `jest.requireActual('whiskey');`; - expect(extractRequires(code)).toEqual(new Set(['whiskey'])); -}); - -it('understands require.requireMock', () => { - const code = `require.requireMock('cheeseburger');`; - expect(extractRequires(code)).toEqual(new Set(['cheeseburger'])); -}); - -it('understands jest.requireMock', () => { - const code = `jest.requireMock('scotch');`; - expect(extractRequires(code)).toEqual(new Set(['scotch'])); -}); diff --git a/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js new file mode 100644 index 000000000000..7d10e43b2ea7 --- /dev/null +++ b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js @@ -0,0 +1,267 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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. + * + * @flow + */ + +import {extract} from '../dependencyExtractor'; +import isRegExpSupported from '../isRegExpSupported'; + +const COMMENT_NO_NEG_LB = isRegExpSupported('(? { + it('should not extract dependencies inside comments', () => { + const code = ` + // import a from 'ignore-line-comment'; + // require('ignore-line-comment'); + /* + * import a from 'ignore-block-comment'; + * require('ignore-block-comment'); + */ + `; + expect(extract(code)).toEqual(new Set()); + }); + + it('should not extract dependencies inside comments (windows line endings)', () => { + const code = [ + '// const module1 = require("module1");', + '/**', + ' * const module2 = require("module2");', + ' */', + ].join('\r\n'); + + expect(extract(code)).toEqual(new Set([])); + }); + + it('should not extract dependencies inside comments (unicode line endings)', () => { + const code = [ + '// const module1 = require("module1");\u2028', + '// const module1 = require("module2");\u2029', + '/*\u2028', + 'const module2 = require("module3");\u2029', + ' */', + ].join(''); + + expect(extract(code)).toEqual(new Set([])); + }); + + it('should extract dependencies from `import` statements', () => { + const code = ` + // Good + import * as depNS from 'dep1'; + import { + a as aliased_a, + b, + } from 'dep2'; + import depDefault from 'dep3'; + import * as depNS, { + a as aliased_a, + b, + }, depDefault from 'dep4'; + + // Bad + ${COMMENT_NO_NEG_LB} foo . import ('inv1'); + ${COMMENT_NO_NEG_LB} foo . export ('inv2'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should not extract dependencies from `import type/typeof` statements', () => { + const code = ` + // Bad + import typeof {foo} from 'inv1'; + import type {foo} from 'inv2'; + `; + expect(extract(code)).toEqual(new Set([])); + }); + + it('should extract dependencies from `export` statements', () => { + const code = ` + // Good + export * as depNS from 'dep1'; + export { + a as aliased_a, + b, + } from 'dep2'; + export depDefault from 'dep3'; + export * as depNS, { + a as aliased_a, + b, + }, depDefault from 'dep4'; + + // Bad + ${COMMENT_NO_NEG_LB} foo . export ('inv1'); + ${COMMENT_NO_NEG_LB} foo . export ('inv2'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should extract dependencies from `export-from` statements', () => { + const code = ` + // Good + export * as depNS from 'dep1'; + export { + a as aliased_a, + b, + } from 'dep2'; + export depDefault from 'dep3'; + export * as depNS, { + a as aliased_a, + b, + }, depDefault from 'dep4'; + + // Bad + ${COMMENT_NO_NEG_LB} foo . export ('inv1'); + ${COMMENT_NO_NEG_LB} foo . export ('inv2'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should not extract dependencies from `export type/typeof` statements', () => { + const code = ` + // Bad + export typeof {foo} from 'inv1'; + export type {foo} from 'inv2'; + `; + expect(extract(code)).toEqual(new Set([])); + }); + + it('should extract dependencies from dynamic `import` calls', () => { + const code = ` + // Good + import('dep1').then(); + const dep2 = await import( + "dep2", + ); + if (await import(\`dep3\`)) {} + + // Bad + ${COMMENT_NO_NEG_LB} await foo . import('inv1') + await ximport('inv2'); + importx('inv3'); + import('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3'])); + }); + + it('should extract dependencies from `require` calls', () => { + const code = ` + // Good + require('dep1'); + const dep2 = require( + "dep2", + ); + if (require(\`dep3\`).cond) {} + + // Bad + ${COMMENT_NO_NEG_LB} foo . require('inv1') + xrequire('inv2'); + requirex('inv3'); + require('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3'])); + }); + + it('should extract dependencies from `require.requireActual` calls', () => { + const code = ` + // Good + require.requireActual('dep1'); + const dep2 = require.requireActual( + "dep2", + ); + if (require.requireActual(\`dep3\`).cond) {} + require + .requireActual('dep4'); + + // Bad + ${COMMENT_NO_NEG_LB} foo . require.requireActual('inv1') + xrequire.requireActual('inv2'); + require.requireActualx('inv3'); + require.requireActual('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should extract dependencies from `require.requireMock` calls', () => { + const code = ` + // Good + require.requireMock('dep1'); + const dep2 = require.requireMock( + "dep2", + ); + if (require.requireMock(\`dep3\`).cond) {} + require + .requireMock('dep4'); + + // Bad + ${COMMENT_NO_NEG_LB} foo . require.requireMock('inv1') + xrequire.requireMock('inv2'); + require.requireMockx('inv3'); + require.requireMock('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should extract dependencies from `jest.requireActual` calls', () => { + const code = ` + // Good + jest.requireActual('dep1'); + const dep2 = jest.requireActual( + "dep2", + ); + if (jest.requireActual(\`dep3\`).cond) {} + require + .requireActual('dep4'); + + // Bad + ${COMMENT_NO_NEG_LB} foo . jest.requireActual('inv1') + xjest.requireActual('inv2'); + jest.requireActualx('inv3'); + jest.requireActual('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should extract dependencies from `jest.requireMock` calls', () => { + const code = ` + // Good + jest.requireMock('dep1'); + const dep2 = jest.requireMock( + "dep2", + ); + if (jest.requireMock(\`dep3\`).cond) {} + require + .requireMock('dep4'); + + // Bad + ${COMMENT_NO_NEG_LB} foo . jest.requireMock('inv1') + xjest.requireMock('inv2'); + jest.requireMockx('inv3'); + jest.requireMock('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); + + it('should extract dependencies from `jest.genMockFromModule` calls', () => { + const code = ` + // Good + jest.genMockFromModule('dep1'); + const dep2 = jest.genMockFromModule( + "dep2", + ); + if (jest.genMockFromModule(\`dep3\`).cond) {} + require + .requireMock('dep4'); + + // Bad + ${COMMENT_NO_NEG_LB} foo . jest.genMockFromModule('inv1') + xjest.genMockFromModule('inv2'); + jest.genMockFromModulex('inv3'); + jest.genMockFromModule('inv4', 'inv5'); + `; + expect(extract(code)).toEqual(new Set(['dep1', 'dep2', 'dep3', 'dep4'])); + }); +}); diff --git a/packages/jest-haste-map/src/lib/__tests__/isRegExpSupported.test.js b/packages/jest-haste-map/src/lib/__tests__/isRegExpSupported.test.js new file mode 100644 index 000000000000..5408244073c9 --- /dev/null +++ b/packages/jest-haste-map/src/lib/__tests__/isRegExpSupported.test.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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. + * + * @flow + */ + +import isRegExpSupported from '../isRegExpSupported'; + +describe('isRegExpSupported', () => { + it('should return true when passing valid regular expression', () => { + expect(isRegExpSupported('(?:foo|bar)')).toBe(true); + }); + + it('should return false when passing an invalid regular expression', () => { + expect(isRegExpSupported('(?_foo|bar)')).toBe(false); + }); +}); diff --git a/packages/jest-haste-map/src/lib/dependencyExtractor.js b/packages/jest-haste-map/src/lib/dependencyExtractor.js index c41393b2bb85..038e6084c2ce 100644 --- a/packages/jest-haste-map/src/lib/dependencyExtractor.js +++ b/packages/jest-haste-map/src/lib/dependencyExtractor.js @@ -7,32 +7,88 @@ * @flow */ -const blockCommentRe = /\/\*[^]*?\*\//g; -const lineCommentRe = /\/\/.*/g; +import isRegExpSupported from './isRegExpSupported'; -const replacePatterns = { - DYNAMIC_IMPORT_RE: /(?:^|[^.]\s*)(\bimport\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g, - EXPORT_RE: /(\bexport\s+(?!type )(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g, - IMPORT_RE: /(\bimport\s+(?!type )(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g, - REQUIRE_EXTENSIONS_PATTERN: /(?:^|[^.]\s*)(\b(?:require\s*?\.\s*?(?:requireActual|requireMock)|jest\s*?\.\s*?(?:requireActual|requireMock|genMockFromModule))\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g, - REQUIRE_RE: /(?:^|[^.]\s*)(\brequire\s*?\(\s*?)([`'"])([^`'"]+)(\2\s*?\))/g, -}; +// Negative look behind is only supported in Node 9+ +const NOT_A_DOT = isRegExpSupported('(? `([\`'"])([^'"\`]*?)(?:\\${pos})`; +const WORD_SEPARATOR = '\\b'; +const LEFT_PARENTHESIS = '\\('; +const RIGHT_PARENTHESIS = '\\)'; +const WHITESPACE = '\\s*'; +const OPTIONAL_COMMA = '(:?,\\s*)?'; + +function createRegExp(parts, flags) { + return new RegExp(parts.join(''), flags); +} + +function alternatives(...parts) { + return `(?:${parts.join('|')})`; +} + +function functionCallStart(...names) { + return [ + NOT_A_DOT, + WORD_SEPARATOR, + alternatives(...names), + WHITESPACE, + LEFT_PARENTHESIS, + WHITESPACE, + ]; +} + +const BLOCK_COMMENT_RE = /\/\*[^]*?\*\//g; +const LINE_COMMENT_RE = /\/\/.*/g; + +const REQUIRE_OR_DYNAMIC_IMPORT_RE = createRegExp( + [ + ...functionCallStart('require', 'import'), + CAPTURE_STRING_LITERAL(1), + WHITESPACE, + OPTIONAL_COMMA, + RIGHT_PARENTHESIS, + ], + 'g', +); + +const IMPORT_OR_EXPORT_RE = createRegExp( + [ + '\\b(?:import|export)\\s+(?!type(?:of)?\\s+)[^\'"]+\\s+from\\s+', + CAPTURE_STRING_LITERAL(1), + ], + 'g', +); + +const JEST_EXTENSIONS_RE = createRegExp( + [ + ...functionCallStart( + 'require\\s*\\.\\s*(?:requireActual|requireMock)', + 'jest\\s*\\.\\s*(?:requireActual|requireMock|genMockFromModule)', + ), + CAPTURE_STRING_LITERAL(1), + WHITESPACE, + OPTIONAL_COMMA, + RIGHT_PARENTHESIS, + ], + 'g', +); export function extract(code: string): Set { const dependencies = new Set(); - const addDependency = (match, pre, quot, dep, post) => { + + const addDependency = (match: string, q: string, dep: string) => { dependencies.add(dep); return match; }; code - .replace(blockCommentRe, '') - .replace(lineCommentRe, '') - .replace(replacePatterns.EXPORT_RE, addDependency) - .replace(replacePatterns.IMPORT_RE, addDependency) - .replace(replacePatterns.REQUIRE_EXTENSIONS_PATTERN, addDependency) - .replace(replacePatterns.REQUIRE_RE, addDependency) - .replace(replacePatterns.DYNAMIC_IMPORT_RE, addDependency); + .replace(BLOCK_COMMENT_RE, '') + .replace(LINE_COMMENT_RE, '') + .replace(IMPORT_OR_EXPORT_RE, addDependency) + .replace(REQUIRE_OR_DYNAMIC_IMPORT_RE, addDependency) + .replace(JEST_EXTENSIONS_RE, addDependency); return dependencies; } diff --git a/packages/jest-haste-map/src/lib/isRegExpSupported.js b/packages/jest-haste-map/src/lib/isRegExpSupported.js new file mode 100644 index 000000000000..d20cb1a6e21e --- /dev/null +++ b/packages/jest-haste-map/src/lib/isRegExpSupported.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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. + * + * @flow + */ + +export default function isRegExpSupported(value: string): boolean { + try { + // eslint-disable-next-line no-new + new RegExp(value); + return true; + } catch (e) { + return false; + } +} From 993bc5c5f2cf8e3bb65c810b1f729a32d6874b75 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 19 Nov 2018 15:46:34 +0100 Subject: [PATCH 45/45] chore: upgrade prettier (#7336) --- .prettierignore | 3 + docs/JestObjectAPI.md | 6 +- docs/TutorialAsync.md | 13 +- .../coverage_remapping.test.js.snap | 196 +++++++++--------- .../__snapshots__/failures.test.js.snap | 12 +- e2e/coverage-remapping/covered.ts | 14 +- .../package.json | 8 +- e2e/custom-reporters/package.json | 13 +- e2e/failures/__tests__/async_failures.test.js | 10 +- .../__tests__/promise_before_all.test.js | 3 +- .../__tests__/promise_before_each.test.js | 3 +- e2e/json-reporter/package.json | 4 +- e2e/multi-project-config-root/package.json | 24 +-- e2e/resolve-node-module/package.json | 6 +- e2e/resolve/test1.json | 2 +- e2e/resolve/test2.json | 2 +- e2e/resolve/test3.json | 2 +- e2e/resolve/test4.json | 2 +- e2e/stack-trace-source-maps/package.json | 5 +- e2e/transform/babel-jest/package.json | 4 +- .../ecmascript-modules-support/package.json | 12 +- e2e/transform/no-babel-jest/package.json | 4 +- e2e/typescript-coverage/package.json | 4 +- examples/async/__mocks__/request.js | 13 +- .../AppIcon.appiconset/Contents.json | 44 ++-- examples/typescript/CheckboxWithLabel.tsx | 11 +- .../__tests__/CheckboxWithLabel-test.tsx | 4 +- examples/typescript/__tests__/sum-test.ts | 4 +- package.json | 6 +- packages/expect/src/matchers.js | 8 +- packages/expect/src/spyMatchers.js | 34 ++- .../src/__tests__/test_sequencer.test.js | 19 +- .../src/__tests__/normalize.test.js | 19 +- packages/jest-config/src/normalize.js | 13 +- .../jest-haste-map/src/crawlers/watchman.js | 6 +- packages/jest-haste-map/src/index.js | 4 +- packages/jest-resolve/src/index.js | 4 +- packages/jest-resolve/src/nodeModulesPaths.js | 13 +- packages/jest-runner/src/run_test.js | 5 +- .../2018-06-27-supporting-jest-open-source.md | 4 +- website/pages/en/index.js | 84 ++++---- website/static/css/custom.css | 8 +- website/static/img/favicon/manifest.json | 32 +-- .../version-22.0/JestObjectAPI.md | 6 +- .../version-22.0/TutorialAsync.md | 13 +- .../version-22.1/JestObjectAPI.md | 6 +- .../version-22.2/JestObjectAPI.md | 6 +- .../version-22.2/TutorialAsync.md | 13 +- .../version-22.3/JestObjectAPI.md | 6 +- .../version-22.3/TutorialAsync.md | 13 +- .../version-22.4/JestObjectAPI.md | 6 +- .../version-23.0/JestObjectAPI.md | 6 +- .../version-23.1/JestObjectAPI.md | 6 +- .../version-23.2/JestObjectAPI.md | 6 +- .../version-23.3/JestObjectAPI.md | 6 +- .../version-23.5/TutorialAsync.md | 13 +- yarn.lock | 24 +-- 57 files changed, 421 insertions(+), 396 deletions(-) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000000..1019f4c475e3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +fixtures/failing-jsons/ +packages/jest-config/src/__tests__/jest-preset.json +packages/pretty-format/perf/world.geo.json diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 58c86823eb64..7d42bb08235e 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -154,9 +154,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/docs/TutorialAsync.md b/docs/TutorialAsync.md index 4d0b69d6e7c8..760c6d323a8f 100644 --- a/docs/TutorialAsync.md +++ b/docs/TutorialAsync.md @@ -50,13 +50,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }), + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }), ); }); } diff --git a/e2e/__tests__/__snapshots__/coverage_remapping.test.js.snap b/e2e/__tests__/__snapshots__/coverage_remapping.test.js.snap index 00cebd87ecb8..7285790c0bbf 100644 --- a/e2e/__tests__/__snapshots__/coverage_remapping.test.js.snap +++ b/e2e/__tests__/__snapshots__/coverage_remapping.test.js.snap @@ -26,33 +26,33 @@ Object { "0": Object { "loc": Object { "end": Object { - "column": 9, - "line": 5, + "column": 35, + "line": 4, }, "start": Object { - "column": 8, - "line": 5, + "column": 34, + "line": 4, }, }, "locations": Array [ Object { "end": Object { - "column": 9, - "line": 5, + "column": 35, + "line": 4, }, "start": Object { - "column": 8, - "line": 5, + "column": 34, + "line": 4, }, }, Object { "end": Object { - "column": 9, - "line": 6, + "column": 39, + "line": 4, }, "start": Object { - "column": 8, - "line": 6, + "column": 38, + "line": 4, }, }, ], @@ -61,33 +61,33 @@ Object { "1": Object { "loc": Object { "end": Object { - "column": 37, - "line": 7, + "column": 35, + "line": 5, }, "start": Object { - "column": 36, - "line": 7, + "column": 34, + "line": 5, }, }, "locations": Array [ Object { "end": Object { - "column": 37, - "line": 7, + "column": 35, + "line": 5, }, "start": Object { - "column": 36, - "line": 7, + "column": 34, + "line": 5, }, }, Object { "end": Object { - "column": 41, - "line": 7, + "column": 39, + "line": 5, }, "start": Object { - "column": 40, - "line": 7, + "column": 38, + "line": 5, }, }, ], @@ -96,43 +96,43 @@ Object { "2": Object { "loc": Object { "end": Object { - "column": 33, - "line": 8, + "column": 31, + "line": 6, }, "start": Object { - "column": 29, - "line": 8, + "column": 27, + "line": 6, }, }, "locations": Array [ Object { "end": Object { - "column": 33, - "line": 8, + "column": 31, + "line": 6, }, "start": Object { - "column": 29, - "line": 8, + "column": 27, + "line": 6, }, }, Object { "end": Object { - "column": 41, - "line": 8, + "column": 39, + "line": 6, }, "start": Object { - "column": 37, - "line": 8, + "column": 35, + "line": 6, }, }, Object { "end": Object { - "column": 50, - "line": 8, + "column": 48, + "line": 6, }, "start": Object { - "column": 45, - "line": 8, + "column": 43, + "line": 6, }, }, ], @@ -141,33 +141,33 @@ Object { "3": Object { "loc": Object { "end": Object { - "column": 42, - "line": 9, + "column": 40, + "line": 7, }, "start": Object { - "column": 32, - "line": 9, + "column": 30, + "line": 7, }, }, "locations": Array [ Object { "end": Object { - "column": 42, - "line": 9, + "column": 40, + "line": 7, }, "start": Object { - "column": 32, - "line": 9, + "column": 30, + "line": 7, }, }, Object { "end": Object { - "column": 55, - "line": 9, + "column": 53, + "line": 7, }, "start": Object { - "column": 45, - "line": 9, + "column": 43, + "line": 7, }, }, ], @@ -194,7 +194,7 @@ Object { "loc": Object { "end": Object { "column": 1, - "line": 12, + "line": 10, }, "start": Object { "column": 49, @@ -206,22 +206,22 @@ Object { "1": Object { "decl": Object { "end": Object { - "column": 37, - "line": 9, + "column": 35, + "line": 7, }, "start": Object { - "column": 32, - "line": 9, + "column": 30, + "line": 7, }, }, "loc": Object { "end": Object { - "column": 42, - "line": 9, + "column": 40, + "line": 7, }, "start": Object { - "column": 32, - "line": 9, + "column": 30, + "line": 7, }, }, "name": "(anonymous_1)", @@ -229,22 +229,22 @@ Object { "2": Object { "decl": Object { "end": Object { - "column": 50, - "line": 9, + "column": 48, + "line": 7, }, "start": Object { - "column": 45, - "line": 9, + "column": 43, + "line": 7, }, }, "loc": Object { "end": Object { - "column": 55, - "line": 9, + "column": 53, + "line": 7, }, "start": Object { - "column": 45, - "line": 9, + "column": 43, + "line": 7, }, }, "name": "(anonymous_2)", @@ -264,8 +264,8 @@ Object { "statementMap": Object { "0": Object { "end": Object { - "column": 1, - "line": 12, + "column": 2, + "line": 10, }, "start": Object { "column": 0, @@ -274,72 +274,72 @@ Object { }, "1": Object { "end": Object { - "column": 9, - "line": 6, + "column": 39, + "line": 4, }, "start": Object { - "column": 29, + "column": 27, "line": 4, }, }, "2": Object { "end": Object { - "column": 41, - "line": 7, + "column": 39, + "line": 5, }, "start": Object { - "column": 29, - "line": 7, + "column": 27, + "line": 5, }, }, "3": Object { "end": Object { - "column": 50, - "line": 8, + "column": 48, + "line": 6, }, "start": Object { - "column": 29, - "line": 8, + "column": 27, + "line": 6, }, }, "4": Object { "end": Object { - "column": 55, - "line": 9, + "column": 53, + "line": 7, }, "start": Object { - "column": 25, - "line": 9, + "column": 23, + "line": 7, }, }, "5": Object { "end": Object { - "column": 42, - "line": 9, + "column": 40, + "line": 7, }, "start": Object { - "column": 38, - "line": 9, + "column": 36, + "line": 7, }, }, "6": Object { "end": Object { - "column": 55, - "line": 9, + "column": 53, + "line": 7, }, "start": Object { - "column": 51, - "line": 9, + "column": 49, + "line": 7, }, }, "7": Object { "end": Object { - "column": 17, - "line": 11, + "column": 15, + "line": 9, }, "start": Object { - "column": 4, - "line": 11, + "column": 2, + "line": 9, }, }, }, diff --git a/e2e/__tests__/__snapshots__/failures.test.js.snap b/e2e/__tests__/__snapshots__/failures.test.js.snap index ab3f4c76b947..f52248988187 100644 --- a/e2e/__tests__/__snapshots__/failures.test.js.snap +++ b/e2e/__tests__/__snapshots__/failures.test.js.snap @@ -385,8 +385,8 @@ exports[`works with async failures 1`] = ` > 21 | expect(Promise.reject({foo: 'bar'})).resolves.toEqual({foo: 'bar'})); | ^ 22 | - 23 | test( - 24 | 'timeout', + 23 | test('timeout', done => { + 24 | setTimeout(done, 50); at __tests__/async_failures.test.js:21:3 @@ -396,11 +396,11 @@ exports[`works with async failures 1`] = ` 21 | expect(Promise.reject({foo: 'bar'})).resolves.toEqual({foo: 'bar'})); 22 | - > 23 | test( + > 23 | test('timeout', done => { | ^ - 24 | 'timeout', - 25 | done => { - 26 | setTimeout(done, 50); + 24 | setTimeout(done, 50); + 25 | }, 5); + 26 | at __tests__/async_failures.test.js:23:1 diff --git a/e2e/coverage-remapping/covered.ts b/e2e/coverage-remapping/covered.ts index df5496159f87..28b8d10b0668 100644 --- a/e2e/coverage-remapping/covered.ts +++ b/e2e/coverage-remapping/covered.ts @@ -1,12 +1,10 @@ // Copyright 2004-present Facebook. All Rights Reserved. export = function difference(a: number, b: number): number { - const branch1: boolean = true - ? 1 - : 0; - const branch2: boolean = true ? 1 : 0; - const branch3: boolean = true || true || false; - const fn: Function = true ? () => null : () => null; + const branch1: boolean = true ? 1 : 0; + const branch2: boolean = true ? 1 : 0; + const branch3: boolean = true || true || false; + const fn: Function = true ? () => null : () => null; - return a - b; -} + return a - b; +}; diff --git a/e2e/coverage-transform-instrumented/package.json b/e2e/coverage-transform-instrumented/package.json index b5263f057316..cc34abce6686 100644 --- a/e2e/coverage-transform-instrumented/package.json +++ b/e2e/coverage-transform-instrumented/package.json @@ -6,10 +6,14 @@ }, "testRegex": "/__tests__/.*\\.(js)$", "testEnvironment": "node", - "moduleFileExtensions": ["js"] + "moduleFileExtensions": [ + "js" + ] }, "babel": { - "presets": ["env"] + "presets": [ + "env" + ] }, "dependencies": { "babel-core": "6.26.0", diff --git a/e2e/custom-reporters/package.json b/e2e/custom-reporters/package.json index 590f11ffe692..c08385980ac4 100644 --- a/e2e/custom-reporters/package.json +++ b/e2e/custom-reporters/package.json @@ -1,11 +1,14 @@ { "jest": { "reporters": [ - ["/reporters/TestReporter.js", { - "hello": "world", - "dmitrii": "abramov", - "christoph": "pojer" - }] + [ + "/reporters/TestReporter.js", + { + "hello": "world", + "dmitrii": "abramov", + "christoph": "pojer" + } + ] ] } } diff --git a/e2e/failures/__tests__/async_failures.test.js b/e2e/failures/__tests__/async_failures.test.js index 9eaafa3a8878..b78eecd6f4bd 100644 --- a/e2e/failures/__tests__/async_failures.test.js +++ b/e2e/failures/__tests__/async_failures.test.js @@ -20,10 +20,6 @@ test('expect reject', () => test('expect resolve', () => expect(Promise.reject({foo: 'bar'})).resolves.toEqual({foo: 'bar'})); -test( - 'timeout', - done => { - setTimeout(done, 50); - }, - 5 -); +test('timeout', done => { + setTimeout(done, 50); +}, 5); diff --git a/e2e/jasmine-async/__tests__/promise_before_all.test.js b/e2e/jasmine-async/__tests__/promise_before_all.test.js index 1907239d42f5..b4f1df734707 100644 --- a/e2e/jasmine-async/__tests__/promise_before_all.test.js +++ b/e2e/jasmine-async/__tests__/promise_before_all.test.js @@ -15,7 +15,8 @@ describe('promise beforeAll', () => { process.nextTick(resolve); }).then(() => { flag = 1; - })); + }) + ); beforeAll(() => new Promise(resolve => setTimeout(resolve, 10)), 500); diff --git a/e2e/jasmine-async/__tests__/promise_before_each.test.js b/e2e/jasmine-async/__tests__/promise_before_each.test.js index 53570b9126f0..dbb7fdbc206a 100644 --- a/e2e/jasmine-async/__tests__/promise_before_each.test.js +++ b/e2e/jasmine-async/__tests__/promise_before_each.test.js @@ -13,7 +13,8 @@ describe('promise beforeEach', () => { process.nextTick(resolve); }).then(() => { this.flag = 1; - })); + }) + ); // passing tests it('runs tests after beforeEach asynchronously completes', () => { diff --git a/e2e/json-reporter/package.json b/e2e/json-reporter/package.json index d59562604cad..781ddcb77c5a 100644 --- a/e2e/json-reporter/package.json +++ b/e2e/json-reporter/package.json @@ -1,6 +1,8 @@ { "jest": { "testEnvironment": "node", - "coverageReporters": ["json"] + "coverageReporters": [ + "json" + ] } } diff --git a/e2e/multi-project-config-root/package.json b/e2e/multi-project-config-root/package.json index 58e129a79e90..897e521d1dc8 100644 --- a/e2e/multi-project-config-root/package.json +++ b/e2e/multi-project-config-root/package.json @@ -1,18 +1,18 @@ { "jest": { "projects": [ - { - "rootDir": "/foo", - "testPathIgnorePatterns": [ - "/__tests__/boggus-foo.test.js" - ] - }, - { - "rootDir": "/bar", - "testPathIgnorePatterns": [ - "/__tests__/boggus-bar.test.js" - ] - } + { + "rootDir": "/foo", + "testPathIgnorePatterns": [ + "/__tests__/boggus-foo.test.js" + ] + }, + { + "rootDir": "/bar", + "testPathIgnorePatterns": [ + "/__tests__/boggus-bar.test.js" + ] + } ] } } diff --git a/e2e/resolve-node-module/package.json b/e2e/resolve-node-module/package.json index 0a586922137e..7c329bea6ee6 100644 --- a/e2e/resolve-node-module/package.json +++ b/e2e/resolve-node-module/package.json @@ -1,6 +1,10 @@ { "jest": { - "moduleFileExtensions": ["js", "json", "jsx"], + "moduleFileExtensions": [ + "js", + "json", + "jsx" + ], "testEnvironment": "node" } } diff --git a/e2e/resolve/test1.json b/e2e/resolve/test1.json index 13827d9bbdc0..001968d98e1b 100644 --- a/e2e/resolve/test1.json +++ b/e2e/resolve/test1.json @@ -1,3 +1,3 @@ { - "extension": "json" + "extension": "json" } diff --git a/e2e/resolve/test2.json b/e2e/resolve/test2.json index 13827d9bbdc0..001968d98e1b 100644 --- a/e2e/resolve/test2.json +++ b/e2e/resolve/test2.json @@ -1,3 +1,3 @@ { - "extension": "json" + "extension": "json" } diff --git a/e2e/resolve/test3.json b/e2e/resolve/test3.json index 13827d9bbdc0..001968d98e1b 100644 --- a/e2e/resolve/test3.json +++ b/e2e/resolve/test3.json @@ -1,3 +1,3 @@ { - "extension": "json" + "extension": "json" } diff --git a/e2e/resolve/test4.json b/e2e/resolve/test4.json index 13827d9bbdc0..001968d98e1b 100644 --- a/e2e/resolve/test4.json +++ b/e2e/resolve/test4.json @@ -1,3 +1,3 @@ { - "extension": "json" + "extension": "json" } diff --git a/e2e/stack-trace-source-maps/package.json b/e2e/stack-trace-source-maps/package.json index cb29f0b9a69a..8941387eb502 100644 --- a/e2e/stack-trace-source-maps/package.json +++ b/e2e/stack-trace-source-maps/package.json @@ -5,7 +5,10 @@ "^.+\\.(ts)$": "/Preprocessor.js" }, "testEnvironment": "node", - "moduleFileExtensions": ["ts", "js"], + "moduleFileExtensions": [ + "ts", + "js" + ], "testRegex": "fails" }, "dependencies": { diff --git a/e2e/transform/babel-jest/package.json b/e2e/transform/babel-jest/package.json index 31b6b0becd61..dbf4430811f5 100644 --- a/e2e/transform/babel-jest/package.json +++ b/e2e/transform/babel-jest/package.json @@ -7,7 +7,9 @@ "/this-directory-is-covered/Covered.js": true, "/this-directory-is-covered/ExcludedFromCoverage.js": true }, - "coveragePathIgnorePatterns": ["ExcludedFromCoverage"], + "coveragePathIgnorePatterns": [ + "ExcludedFromCoverage" + ], "testEnvironment": "node" } } diff --git a/e2e/transform/ecmascript-modules-support/package.json b/e2e/transform/ecmascript-modules-support/package.json index b3145fb854df..d37c7ca66af6 100644 --- a/e2e/transform/ecmascript-modules-support/package.json +++ b/e2e/transform/ecmascript-modules-support/package.json @@ -1,8 +1,16 @@ { "jest": { "testEnvironment": "node", - "moduleFileExtensions": ["js", "json", "jsx", "node", "mjs"], - "testMatch": [ "**/__tests__/**/*.mjs"], + "moduleFileExtensions": [ + "js", + "json", + "jsx", + "node", + "mjs" + ], + "testMatch": [ + "**/__tests__/**/*.mjs" + ], "transform": { "^.+\\.mjs?$": "../../../packages/babel-jest" } diff --git a/e2e/transform/no-babel-jest/package.json b/e2e/transform/no-babel-jest/package.json index 86982fa93b05..9fb09b127a3b 100644 --- a/e2e/transform/no-babel-jest/package.json +++ b/e2e/transform/no-babel-jest/package.json @@ -4,7 +4,9 @@ "/this-directory-is-covered/Covered.js": true, "/this-directory-is-covered/ExcludedFromCoverage.js": true }, - "coveragePathIgnorePatterns": ["ExcludedFromCoverage"], + "coveragePathIgnorePatterns": [ + "ExcludedFromCoverage" + ], "testEnvironment": "node" } } diff --git a/e2e/typescript-coverage/package.json b/e2e/typescript-coverage/package.json index 4c274920cbe4..9b6cf144b886 100644 --- a/e2e/typescript-coverage/package.json +++ b/e2e/typescript-coverage/package.json @@ -4,7 +4,9 @@ "transform": { "^.+\\.(ts|js)$": "/TypescriptPreprocessor.js" }, - "testMatch": ["**/__tests__/*.+(ts|tsx|js)"], + "testMatch": [ + "**/__tests__/*.+(ts|tsx|js)" + ], "testEnvironment": "node", "moduleFileExtensions": [ "ts", diff --git a/examples/async/__mocks__/request.js b/examples/async/__mocks__/request.js index 3dc3d9451003..51784974d8fa 100644 --- a/examples/async/__mocks__/request.js +++ b/examples/async/__mocks__/request.js @@ -10,13 +10,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }) + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }) ); }); } diff --git a/examples/react-native/ios/jestrn/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/react-native/ios/jestrn/Images.xcassets/AppIcon.appiconset/Contents.json index d3942e941ae8..48e64ae8a3ef 100644 --- a/examples/react-native/ios/jestrn/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/examples/react-native/ios/jestrn/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,38 +1,38 @@ { - "images" : [ + "images": [ { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" + "idiom": "iphone", + "size": "29x29", + "scale": "2x" }, { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" + "idiom": "iphone", + "size": "29x29", + "scale": "3x" }, { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" + "idiom": "iphone", + "size": "40x40", + "scale": "2x" }, { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" + "idiom": "iphone", + "size": "40x40", + "scale": "3x" }, { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" + "idiom": "iphone", + "size": "60x60", + "scale": "2x" }, { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" + "idiom": "iphone", + "size": "60x60", + "scale": "3x" } ], - "info" : { - "version" : 1, - "author" : "xcode" + "info": { + "version": 1, + "author": "xcode" } } diff --git a/examples/typescript/CheckboxWithLabel.tsx b/examples/typescript/CheckboxWithLabel.tsx index 744ea4f75fc5..86456eac73d3 100644 --- a/examples/typescript/CheckboxWithLabel.tsx +++ b/examples/typescript/CheckboxWithLabel.tsx @@ -2,7 +2,7 @@ /// -import * as React from 'react' +import * as React from 'react'; interface CheckboxWithLabelProps { labelOff: string; @@ -13,7 +13,10 @@ interface CheckboxWithLabelState { isChecked: boolean; } -class CheckboxWithLabel extends React.Component { +class CheckboxWithLabel extends React.Component< + CheckboxWithLabelProps, + CheckboxWithLabelState +> { constructor(props: CheckboxWithLabelProps) { super(props); this.state = {isChecked: false}; @@ -25,7 +28,9 @@ class CheckboxWithLabel extends React.Component this.setState(current => ({isChecked: !current.isChecked}))} + onChange={() => + this.setState(current => ({isChecked: !current.isChecked})) + } /> {this.state.isChecked ? this.props.labelOn : this.props.labelOff} diff --git a/examples/typescript/__tests__/CheckboxWithLabel-test.tsx b/examples/typescript/__tests__/CheckboxWithLabel-test.tsx index ddfd65d7c397..4321ceaf88a5 100644 --- a/examples/typescript/__tests__/CheckboxWithLabel-test.tsx +++ b/examples/typescript/__tests__/CheckboxWithLabel-test.tsx @@ -9,7 +9,7 @@ const CheckboxWithLabel = require('../CheckboxWithLabel'); it('CheckboxWithLabel changes the text after click', () => { // Render a checkbox with label in the document const checkbox = TestUtils.renderIntoDocument( - + , ); const checkboxNode = ReactDOM.findDOMNode(checkbox); @@ -19,7 +19,7 @@ it('CheckboxWithLabel changes the text after click', () => { // Simulate a click and verify that it is now On TestUtils.Simulate.change( - TestUtils.findRenderedDOMComponentWithTag(checkbox, 'input') + TestUtils.findRenderedDOMComponentWithTag(checkbox, 'input'), ); expect(checkboxNode.textContent).toEqual('On'); }); diff --git a/examples/typescript/__tests__/sum-test.ts b/examples/typescript/__tests__/sum-test.ts index 4555790104d3..47ecf4167fc4 100644 --- a/examples/typescript/__tests__/sum-test.ts +++ b/examples/typescript/__tests__/sum-test.ts @@ -1,11 +1,11 @@ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. -it('adds 1 + 2 to equal 3 in TScript', ()=> { +it('adds 1 + 2 to equal 3 in TScript', () => { const sum = require('../sum.ts'); expect(sum(1, 2)).toBe(3); }); -it('adds 1 + 2 to equal 3 in JavaScript', ()=> { +it('adds 1 + 2 to equal 3 in JavaScript', () => { const sum = require('../sum.js'); expect(sum(1, 2)).toBe(3); }); diff --git a/package.json b/package.json index 987d4eb37f73..36336e0d27a9 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,14 @@ "codecov": "^3.0.0", "debug": "^4.0.1", "eslint": "^5.6.0", - "eslint-config-prettier": "^3.0.1", + "eslint-config-prettier": "^3.1.0", "eslint-plugin-babel": "^5.1.0", "eslint-plugin-flowtype": "^2.35.0", "eslint-plugin-import": "^2.6.0", "eslint-plugin-jest": "^22.0.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-markdown": "^1.0.0-beta.6", - "eslint-plugin-prettier": "^2.3.1", + "eslint-plugin-prettier": "^2.7.0", "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "~0.0.19", "execa": "^1.0.0", @@ -57,7 +57,7 @@ "mkdirp": "^0.5.1", "mocha": "^5.0.1", "mock-fs": "^4.4.1", - "prettier": "^1.13.3", + "prettier": "^1.15.2", "prettylint": "^1.0.0", "progress": "^2.0.0", "promise": "^8.0.2", diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 4e9575213513..13e516e48267 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -511,10 +511,10 @@ const matchers: MatchersObject = { ` ${printReceived(result.value)}` + (diffString ? `\n\nDifference:\n\n${diffString}` : '') : traversedPath - ? `Received:\n ${RECEIVED_COLOR( - 'object', - )}.${traversedPath}: ${printReceived(lastTraversedObject)}` - : '') + ? `Received:\n ${RECEIVED_COLOR( + 'object', + )}.${traversedPath}: ${printReceived(lastTraversedObject)}` + : '') ); }; if (pass === undefined) { diff --git a/packages/expect/src/spyMatchers.js b/packages/expect/src/spyMatchers.js index a494cc8b2368..39c5abb36dea 100644 --- a/packages/expect/src/spyMatchers.js +++ b/packages/expect/src/spyMatchers.js @@ -313,12 +313,12 @@ const createLastReturnedMatcher = matcherName => ( (!lastResult ? `But it was ${RECEIVED_COLOR('not called')}` : lastResult.type === 'incomplete' - ? `But the last call ${RECEIVED_COLOR('has not returned yet')}` - : lastResult.type === 'throw' - ? `But the last call ${RECEIVED_COLOR('threw an error')}` - : `But the last call returned:\n ${printReceived( - lastResult.value, - )}`); + ? `But the last call ${RECEIVED_COLOR('has not returned yet')}` + : lastResult.type === 'throw' + ? `But the last call ${RECEIVED_COLOR('threw an error')}` + : `But the last call returned:\n ${printReceived( + lastResult.value, + )}`); return {message, pass}; }; @@ -420,18 +420,16 @@ const createNthReturnedWithMatcher = (matcherName: string) => ( (results.length === 0 ? `But it was ${RECEIVED_COLOR('not called')}` : nth > results.length - ? `But it was only called ${printReceived(results.length)} times` - : nthResult.type === 'incomplete' - ? `But the ${nthString} call ${RECEIVED_COLOR( - 'has not returned yet', - )}` - : nthResult.type === 'throw' - ? `But the ${nthString} call ${RECEIVED_COLOR( - 'threw an error', - )}` - : `But the ${nthString} call returned with:\n ${printReceived( - nthResult.value, - )}`); + ? `But it was only called ${printReceived(results.length)} times` + : nthResult.type === 'incomplete' + ? `But the ${nthString} call ${RECEIVED_COLOR( + 'has not returned yet', + )}` + : nthResult.type === 'throw' + ? `But the ${nthString} call ${RECEIVED_COLOR('threw an error')}` + : `But the ${nthString} call returned with:\n ${printReceived( + nthResult.value, + )}`); return {message, pass}; }; diff --git a/packages/jest-cli/src/__tests__/test_sequencer.test.js b/packages/jest-cli/src/__tests__/test_sequencer.test.js index ae3b3a6f10fb..47cd3131e984 100644 --- a/packages/jest-cli/src/__tests__/test_sequencer.test.js +++ b/packages/jest-cli/src/__tests__/test_sequencer.test.js @@ -203,16 +203,15 @@ test('writes the cache based on the results', () => { }); test('works with multiple contexts', () => { - fs.readFileSync = jest.fn( - cacheName => - cacheName.startsWith(path.sep + 'cache' + path.sep) - ? JSON.stringify({ - '/test-a.js': [SUCCESS, 5], - '/test-b.js': [FAIL, 1], - }) - : JSON.stringify({ - '/test-c.js': [FAIL], - }), + fs.readFileSync = jest.fn(cacheName => + cacheName.startsWith(path.sep + 'cache' + path.sep) + ? JSON.stringify({ + '/test-a.js': [SUCCESS, 5], + '/test-b.js': [FAIL, 1], + }) + : JSON.stringify({ + '/test-c.js': [FAIL], + }), ); const testPaths = [ diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index e801b998b797..28c2aea79422 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -334,9 +334,8 @@ describe('setupFilesAfterEnv', () => { let Resolver; beforeEach(() => { Resolver = require('jest-resolve'); - Resolver.findNodeModule = jest.fn( - name => - name.startsWith('/') ? name : '/root/path/foo' + path.sep + name, + Resolver.findNodeModule = jest.fn(name => + name.startsWith('/') ? name : '/root/path/foo' + path.sep + name, ); }); @@ -385,9 +384,8 @@ describe('setupTestFrameworkScriptFile', () => { console.warn = jest.fn(); consoleWarn = console.warn; Resolver = require('jest-resolve'); - Resolver.findNodeModule = jest.fn( - name => - name.startsWith('/') ? name : '/root/path/foo' + path.sep + name, + Resolver.findNodeModule = jest.fn(name => + name.startsWith('/') ? name : '/root/path/foo' + path.sep + name, ); }); @@ -724,11 +722,10 @@ describe('babel-jest', () => { let Resolver; beforeEach(() => { Resolver = require('jest-resolve'); - Resolver.findNodeModule = jest.fn( - name => - name.indexOf('babel-jest') === -1 - ? path.sep + 'node_modules' + path.sep + name - : name, + Resolver.findNodeModule = jest.fn(name => + name.indexOf('babel-jest') === -1 + ? path.sep + 'node_modules' + path.sep + name + : name, ); }); diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index ef6886ce2a3b..b29e3e690091 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -565,11 +565,10 @@ export default function normalize(options: InitialOptions, argv: Argv) { break; case 'projects': value = (options[key] || []) - .map( - project => - typeof project === 'string' - ? _replaceRootDirTags(options.rootDir, project) - : project, + .map(project => + typeof project === 'string' + ? _replaceRootDirTags(options.rootDir, project) + : project, ) .reduce((projects, project) => { // Project can be specified as globs. If a glob matches any files, @@ -727,8 +726,8 @@ export default function normalize(options: InitialOptions, argv: Argv) { argv.ci && !argv.updateSnapshot ? 'none' : argv.updateSnapshot - ? 'all' - : 'new'; + ? 'all' + : 'new'; newOptions.maxWorkers = getMaxWorkers(argv); diff --git a/packages/jest-haste-map/src/crawlers/watchman.js b/packages/jest-haste-map/src/crawlers/watchman.js index e0d0dce9ee73..2b8b903899dd 100644 --- a/packages/jest-haste-map/src/crawlers/watchman.js +++ b/packages/jest-haste-map/src/crawlers/watchman.js @@ -44,10 +44,8 @@ module.exports = async function watchmanCrawl( const cmd = (...args) => new Promise((resolve, reject) => - client.command( - args, - (error, result) => - error ? reject(WatchmanError(error)) : resolve(result), + client.command(args, (error, result) => + error ? reject(WatchmanError(error)) : resolve(result), ), ); diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index ef5392efd5fe..50fe4eee43ee 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -755,8 +755,8 @@ class HasteMap extends EventEmitter { canUseWatchman && this._options.useWatchman ? WatchmanWatcher : os.platform() === 'darwin' - ? sane.FSEventsWatcher - : sane.NodeWatcher; + ? sane.FSEventsWatcher + : sane.NodeWatcher; const extensions = this._options.extensions; const ignorePattern = this._options.ignorePattern; const rootDir = this._options.rootDir; diff --git a/packages/jest-resolve/src/index.js b/packages/jest-resolve/src/index.js index cf3ba0d85093..55562ac8b7f7 100644 --- a/packages/jest-resolve/src/index.js +++ b/packages/jest-resolve/src/index.js @@ -328,8 +328,8 @@ class Resolver { return virtualMocks[virtualMockPath] ? virtualMockPath : moduleName - ? this.resolveModule(from, moduleName) - : from; + ? this.resolveModule(from, moduleName) + : from; } _isModuleResolved(from: Path, moduleName: string): boolean { diff --git a/packages/jest-resolve/src/nodeModulesPaths.js b/packages/jest-resolve/src/nodeModulesPaths.js index 84cb68a2c3fb..32d447aa90d0 100644 --- a/packages/jest-resolve/src/nodeModulesPaths.js +++ b/packages/jest-resolve/src/nodeModulesPaths.js @@ -59,13 +59,12 @@ export default function nodeModulesPaths( .reduce( (dirs, aPath) => dirs.concat( - modules.map( - moduleDir => - path.isAbsolute(moduleDir) - ? aPath === basedirAbs - ? moduleDir - : '' - : path.join(prefix, aPath, moduleDir), + modules.map(moduleDir => + path.isAbsolute(moduleDir) + ? aPath === basedirAbs + ? moduleDir + : '' + : path.join(prefix, aPath, moduleDir), ), ), [], diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index 4292349ec8e3..8908a54b58ec 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -71,9 +71,8 @@ async function runTestInternal( : /* $FlowFixMe */ require(config.testRunner)): TestFramework); /* $FlowFixMe */ - const Runtime = (require(config.moduleLoader || 'jest-runtime'): Class< - RuntimeClass, - >); + const Runtime = (require(config.moduleLoader || + 'jest-runtime'): Class); let runtime = undefined; diff --git a/website/blog/2018-06-27-supporting-jest-open-source.md b/website/blog/2018-06-27-supporting-jest-open-source.md index b8c541695bd3..efb7b4bb4128 100644 --- a/website/blog/2018-06-27-supporting-jest-open-source.md +++ b/website/blog/2018-06-27-supporting-jest-open-source.md @@ -43,11 +43,11 @@ There are two levels of support for the collective: Backer and Sponsor. ### Backers -Backers of the collective are individuals contributing at least $2/month. We'll include a list of backers on the Jest homepage, README on github/yarn/npm, and Contributors page. +Backers of the collective are individuals contributing at least \$2/month. We'll include a list of backers on the Jest homepage, README on github/yarn/npm, and Contributors page. ### Sponsors -Sponsors of the collective are individuals and organizations contributing at least $100/month. We'll place sponsor logos with a link to their site on the Jest homepage, README on github/yarn/npm, and Contributors page. +Sponsors of the collective are individuals and organizations contributing at least \$100/month. We'll place sponsor logos with a link to their site on the Jest homepage, README on github/yarn/npm, and Contributors page. ## What is the goal of the collective diff --git a/website/pages/en/index.js b/website/pages/en/index.js index fe1f7c3ca8b1..f66efc3201f7 100755 --- a/website/pages/en/index.js +++ b/website/pages/en/index.js @@ -49,25 +49,29 @@ class Contributors extends React.Component {

- {backers.filter(b => b.tier === 'sponsor').map(b => ( - - { - { - } - - ))} + {backers + .filter(b => b.tier === 'sponsor') + .map(b => ( + + { + { + } + + ))}

- {backers.filter(b => b.tier === 'backer').map(b => ( - - { - { - } - - ))} + {backers + .filter(b => b.tier === 'backer') + .map(b => ( + + { + { + } + + ))}
{ /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-22.0/TutorialAsync.md b/website/versioned_docs/version-22.0/TutorialAsync.md index 63e56c14cc19..49c559a21b1e 100644 --- a/website/versioned_docs/version-22.0/TutorialAsync.md +++ b/website/versioned_docs/version-22.0/TutorialAsync.md @@ -51,13 +51,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }), + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }), ); }); } diff --git a/website/versioned_docs/version-22.1/JestObjectAPI.md b/website/versioned_docs/version-22.1/JestObjectAPI.md index 0bccfffd50f5..1ba24bd06849 100644 --- a/website/versioned_docs/version-22.1/JestObjectAPI.md +++ b/website/versioned_docs/version-22.1/JestObjectAPI.md @@ -125,9 +125,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-22.2/JestObjectAPI.md b/website/versioned_docs/version-22.2/JestObjectAPI.md index 8991484ca9b2..e2c69594f6b7 100644 --- a/website/versioned_docs/version-22.2/JestObjectAPI.md +++ b/website/versioned_docs/version-22.2/JestObjectAPI.md @@ -126,9 +126,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-22.2/TutorialAsync.md b/website/versioned_docs/version-22.2/TutorialAsync.md index 2c19a5bc4949..4ab1d6c0b749 100644 --- a/website/versioned_docs/version-22.2/TutorialAsync.md +++ b/website/versioned_docs/version-22.2/TutorialAsync.md @@ -51,13 +51,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }), + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }), ); }); } diff --git a/website/versioned_docs/version-22.3/JestObjectAPI.md b/website/versioned_docs/version-22.3/JestObjectAPI.md index 8705bac90005..f3b80dd34935 100644 --- a/website/versioned_docs/version-22.3/JestObjectAPI.md +++ b/website/versioned_docs/version-22.3/JestObjectAPI.md @@ -126,9 +126,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-22.3/TutorialAsync.md b/website/versioned_docs/version-22.3/TutorialAsync.md index b683f8cf552d..4b8ddce1e516 100644 --- a/website/versioned_docs/version-22.3/TutorialAsync.md +++ b/website/versioned_docs/version-22.3/TutorialAsync.md @@ -51,13 +51,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }), + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }), ); }); } diff --git a/website/versioned_docs/version-22.4/JestObjectAPI.md b/website/versioned_docs/version-22.4/JestObjectAPI.md index 383c5faab39d..f0f9b8c0fb74 100644 --- a/website/versioned_docs/version-22.4/JestObjectAPI.md +++ b/website/versioned_docs/version-22.4/JestObjectAPI.md @@ -208,9 +208,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-23.0/JestObjectAPI.md b/website/versioned_docs/version-23.0/JestObjectAPI.md index b962638c922c..91305ed295e4 100644 --- a/website/versioned_docs/version-23.0/JestObjectAPI.md +++ b/website/versioned_docs/version-23.0/JestObjectAPI.md @@ -208,9 +208,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-23.1/JestObjectAPI.md b/website/versioned_docs/version-23.1/JestObjectAPI.md index 700bf9bc85a0..843f45835d31 100644 --- a/website/versioned_docs/version-23.1/JestObjectAPI.md +++ b/website/versioned_docs/version-23.1/JestObjectAPI.md @@ -208,9 +208,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-23.2/JestObjectAPI.md b/website/versioned_docs/version-23.2/JestObjectAPI.md index dce067532b37..7607b1aebb9b 100644 --- a/website/versioned_docs/version-23.2/JestObjectAPI.md +++ b/website/versioned_docs/version-23.2/JestObjectAPI.md @@ -208,9 +208,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-23.3/JestObjectAPI.md b/website/versioned_docs/version-23.3/JestObjectAPI.md index f11e24388bb7..f3a8f4be3d9f 100644 --- a/website/versioned_docs/version-23.3/JestObjectAPI.md +++ b/website/versioned_docs/version-23.3/JestObjectAPI.md @@ -209,9 +209,9 @@ jest.mock( '../moduleName', () => { /* - * Custom implementation of a module that doesn't exist in JS, - * like a generated module or a native module in react-native. - */ + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ }, {virtual: true}, ); diff --git a/website/versioned_docs/version-23.5/TutorialAsync.md b/website/versioned_docs/version-23.5/TutorialAsync.md index 82ca5daa10c4..b8847230d31e 100644 --- a/website/versioned_docs/version-23.5/TutorialAsync.md +++ b/website/versioned_docs/version-23.5/TutorialAsync.md @@ -51,13 +51,12 @@ const users = { export default function request(url) { return new Promise((resolve, reject) => { const userID = parseInt(url.substr('/users/'.length), 10); - process.nextTick( - () => - users[userID] - ? resolve(users[userID]) - : reject({ - error: 'User with ' + userID + ' not found.', - }), + process.nextTick(() => + users[userID] + ? resolve(users[userID]) + : reject({ + error: 'User with ' + userID + ' not found.', + }), ); }); } diff --git a/yarn.lock b/yarn.lock index cfe08495395d..53ba7277f0c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5286,10 +5286,10 @@ eslint-config-fbjs@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-config-fbjs/-/eslint-config-fbjs-2.1.0.tgz#bfe4f8c2d2282bfe515359553905d830e3a5d12f" integrity sha512-wh7Lveo51V3/SUydWtR2VEU8wNfSHt5V7YzIUKTRkHF3kvkCwFtM6Jgsn+xBNkjxZGpfWgNJN/drk1LLx64Dww== -eslint-config-prettier@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.0.1.tgz#479214f64c1a4b344040924bfb97543db334b7b1" - integrity sha512-vA0TB8HCx/idHXfKHYcg9J98p0Q8nkfNwNAoP7e+ywUidn6ScaFS5iqncZAHPz+/a0A/tp657ulFHFx/2JDP4Q== +eslint-config-prettier@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz#2c26d2cdcfa3a05f0642cd7e6e4ef3316cdabfa2" + integrity sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w== dependencies: get-stdin "^6.0.0" @@ -5378,10 +5378,10 @@ eslint-plugin-markdown@^1.0.0-beta.6: remark-parse "^3.0.0" unified "^6.1.2" -eslint-plugin-prettier@^2.2.0, eslint-plugin-prettier@^2.3.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz#71998c60aedfa2141f7bfcbf9d1c459bf98b4fad" - integrity sha512-tGek5clmW5swrAx1mdPYM8oThrBE83ePh7LeseZHBWfHVGrHPhKn7Y5zgRMbU/9D5Td9K4CEmUPjGxA7iw98Og== +eslint-plugin-prettier@^2.2.0, eslint-plugin-prettier@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" + integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== dependencies: fast-diff "^1.1.1" jest-docblock "^21.0.0" @@ -10839,10 +10839,10 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= -prettier@^1.13.3, prettier@^1.13.4: - version "1.14.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9" - integrity sha512-McHPg0n1pIke+A/4VcaS2en+pTNjy4xF+Uuq86u/5dyDO59/TtFZtQ708QIRkEZ3qwKz3GVkVa6mpxK/CpB8Rg== +prettier@^1.13.4, prettier@^1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" + integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== pretty-format@^4.2.1: version "4.3.1"