diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c3b57e67af0..15029d0dfaf5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,8 @@
- `[expect]` Match symbols and bigints in `any()` ([#10223](https://github.com/facebook/jest/pull/10223))
- `[jest-changed-files]` Use `git diff` instead of `git log` for `--changedSince` ([#10155](https://github.com/facebook/jest/pull/10155))
-- `[jest-console]` Add missing console.timeLog for compatability with Node ([#10209](https://github.com/facebook/jest/pull/10209))
+- `[jest-console]` Add missing `console.timeLog` for compatibility with Node ([#10209](https://github.com/facebook/jest/pull/10209))
+- `[jest-haste-map]` Check `find` binary supports the `-iname` parameter ([#10308](https://github.com/facebook/jest/pull/10308))
- `[jest-snapshot]` Strip added indentation for inline error snapshots ([#10217](https://github.com/facebook/jest/pull/10217))
### Chore & Maintenance
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e475ec2bc54f..971973cefc70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -232,7 +232,9 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
## Credits
-This project exists thanks to all the people who [contribute](CONTRIBUTING.md).
+This project exists thanks to all the people who [contribute](CONTRIBUTING.md).
+
+
### [Backers](https://opencollective.com/jest#backer)
diff --git a/README.md b/README.md
index 0315111d0642..ca5936aeb337 100644
--- a/README.md
+++ b/README.md
@@ -236,7 +236,9 @@ To help you get your feet wet and get you familiar with our contribution process
## Credits
-This project exists thanks to all the people who [contribute](CONTRIBUTING.md).
+This project exists thanks to all the people who [contribute](CONTRIBUTING.md).
+
+
### [Backers](https://opencollective.com/jest#backer)
diff --git a/docs/CLI.md b/docs/CLI.md
index 9aee643a4102..dd9c00c56006 100644
--- a/docs/CLI.md
+++ b/docs/CLI.md
@@ -138,7 +138,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-A glob pattern relative to matching the files that coverage info needs to be collected from.
+A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -146,7 +146,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage[=]`
diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md
index 3f99779ed3fa..52e6dedb28db 100644
--- a/docs/WatchPlugins.md
+++ b/docs/WatchPlugins.md
@@ -224,8 +224,8 @@ Any key not used by built-in functionality can be claimed, as you would expect.
Should your plugin attempt to overwrite a reserved key, Jest will error out with a descriptive message, something like:
-> Watch plugin YourFaultyPlugin attempted to register key , that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
+> Watch plugin YourFaultyPlugin attempted to register key `q`, that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
Third-party plugins are also forbidden to overwrite a key reserved already by another third-party plugin present earlier in the configured plugins list (`watchPlugins` array setting). When this happens, you’ll also get an error message that tries to help you fix that:
-> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key . Please change the key configuration for one of the conflicting plugins to avoid overlap.
+> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key `x`. Please change the key configuration for one of the conflicting plugins to avoid overlap.
diff --git a/e2e/async-regenerator/yarn.lock b/e2e/async-regenerator/yarn.lock
index 236d2fa2ed51..f980026cd0d8 100644
--- a/e2e/async-regenerator/yarn.lock
+++ b/e2e/async-regenerator/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/babel-plugin-jest-hoist/yarn.lock b/e2e/babel-plugin-jest-hoist/yarn.lock
index 4889de3d0508..03581ee192fc 100644
--- a/e2e/babel-plugin-jest-hoist/yarn.lock
+++ b/e2e/babel-plugin-jest-hoist/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/chai-assertion-library-errors/yarn.lock b/e2e/chai-assertion-library-errors/yarn.lock
index 4080194c353c..7fb782725f06 100644
--- a/e2e/chai-assertion-library-errors/yarn.lock
+++ b/e2e/chai-assertion-library-errors/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"assertion-error@npm:^1.1.0":
version: 1.1.0
diff --git a/e2e/console-winston/yarn.lock b/e2e/console-winston/yarn.lock
index c3f0cef31f7b..a812d12623c9 100644
--- a/e2e/console-winston/yarn.lock
+++ b/e2e/console-winston/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"async@npm:^2.6.1":
version: 2.6.3
diff --git a/e2e/coverage-handlebars/yarn.lock b/e2e/coverage-handlebars/yarn.lock
index 58ffd42c552d..72e6260d30b5 100644
--- a/e2e/coverage-handlebars/yarn.lock
+++ b/e2e/coverage-handlebars/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"commander@npm:~2.20.3":
version: 2.20.3
diff --git a/e2e/coverage-remapping/yarn.lock b/e2e/coverage-remapping/yarn.lock
index a81055e41cba..4d6b494151c8 100644
--- a/e2e/coverage-remapping/yarn.lock
+++ b/e2e/coverage-remapping/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
@@ -25,7 +25,7 @@ typescript@^3.7.4:
"typescript@patch:typescript@^3.7.4#builtin":
version: 3.8.3
- resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=64df9d"
+ resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=5b02a2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
diff --git a/e2e/coverage-report/yarn.lock b/e2e/coverage-report/yarn.lock
index 98d14aaac0ad..68e8b9d238ef 100644
--- a/e2e/coverage-report/yarn.lock
+++ b/e2e/coverage-report/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/coverage-transform-instrumented/yarn.lock b/e2e/coverage-transform-instrumented/yarn.lock
index cdcd34252ff7..08e0b5c4bf16 100644
--- a/e2e/coverage-transform-instrumented/yarn.lock
+++ b/e2e/coverage-transform-instrumented/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/expect-async-matcher/yarn.lock b/e2e/expect-async-matcher/yarn.lock
index 98d14aaac0ad..68e8b9d238ef 100644
--- a/e2e/expect-async-matcher/yarn.lock
+++ b/e2e/expect-async-matcher/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/failures/yarn.lock b/e2e/failures/yarn.lock
index 98d14aaac0ad..68e8b9d238ef 100644
--- a/e2e/failures/yarn.lock
+++ b/e2e/failures/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/global-setup/yarn.lock b/e2e/global-setup/yarn.lock
index 0a5f76b9dc1f..d8771ec6bbdc 100644
--- a/e2e/global-setup/yarn.lock
+++ b/e2e/global-setup/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/global-teardown/yarn.lock b/e2e/global-teardown/yarn.lock
index 0a5f76b9dc1f..d8771ec6bbdc 100644
--- a/e2e/global-teardown/yarn.lock
+++ b/e2e/global-teardown/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/stack-trace-source-maps-with-coverage/yarn.lock b/e2e/stack-trace-source-maps-with-coverage/yarn.lock
index a81055e41cba..4d6b494151c8 100644
--- a/e2e/stack-trace-source-maps-with-coverage/yarn.lock
+++ b/e2e/stack-trace-source-maps-with-coverage/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
@@ -25,7 +25,7 @@ typescript@^3.7.4:
"typescript@patch:typescript@^3.7.4#builtin":
version: 3.8.3
- resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=64df9d"
+ resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=5b02a2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
diff --git a/e2e/stack-trace-source-maps/yarn.lock b/e2e/stack-trace-source-maps/yarn.lock
index a81055e41cba..4d6b494151c8 100644
--- a/e2e/stack-trace-source-maps/yarn.lock
+++ b/e2e/stack-trace-source-maps/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
@@ -25,7 +25,7 @@ typescript@^3.7.4:
"typescript@patch:typescript@^3.7.4#builtin":
version: 3.8.3
- resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=64df9d"
+ resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=5b02a2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
diff --git a/e2e/transform/babel-jest-manual/yarn.lock b/e2e/transform/babel-jest-manual/yarn.lock
index 98d14aaac0ad..68e8b9d238ef 100644
--- a/e2e/transform/babel-jest-manual/yarn.lock
+++ b/e2e/transform/babel-jest-manual/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/transform/babel-jest/yarn.lock b/e2e/transform/babel-jest/yarn.lock
index 98d14aaac0ad..68e8b9d238ef 100644
--- a/e2e/transform/babel-jest/yarn.lock
+++ b/e2e/transform/babel-jest/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/transform/multiple-transformers/yarn.lock b/e2e/transform/multiple-transformers/yarn.lock
index 4d43e9f5bb86..c94e93cfc1d9 100644
--- a/e2e/transform/multiple-transformers/yarn.lock
+++ b/e2e/transform/multiple-transformers/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/code-frame@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/transform/transformer-config/yarn.lock b/e2e/transform/transformer-config/yarn.lock
index 6ee10e7837ca..dd41475c1994 100644
--- a/e2e/transform/transformer-config/yarn.lock
+++ b/e2e/transform/transformer-config/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.8.3":
version: 7.8.3
diff --git a/e2e/typescript-coverage/yarn.lock b/e2e/typescript-coverage/yarn.lock
index b1e167d2dcf2..29c836d1eb1b 100644
--- a/e2e/typescript-coverage/yarn.lock
+++ b/e2e/typescript-coverage/yarn.lock
@@ -3,7 +3,7 @@
__metadata:
version: 4
- cacheKey: 4
+ cacheKey: 6
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
@@ -25,7 +25,7 @@ typescript@^3.3.1:
"typescript@patch:typescript@^3.3.1#builtin":
version: 3.8.3
- resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=64df9d"
+ resolution: "typescript@patch:typescript@npm%3A3.8.3#builtin::version=3.8.3&hash=5b02a2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
diff --git a/packages/jest-config/src/color.ts b/packages/jest-config/src/color.ts
index 78f15a5398ce..dcb0534805cb 100644
--- a/packages/jest-config/src/color.ts
+++ b/packages/jest-config/src/color.ts
@@ -6,9 +6,11 @@
*/
import {createHash} from 'crypto';
-import chalk = require('chalk');
+import type {ForegroundColor} from 'chalk';
-const colors: Array = [
+type Color = typeof ForegroundColor;
+
+const colors: Array = [
'red',
'green',
'yellow',
@@ -18,7 +20,7 @@ const colors: Array = [
'white',
];
-export const getDisplayNameColor = (seed?: string): typeof colors[number] => {
+export const getDisplayNameColor = (seed?: string): Color => {
if (seed === undefined) {
return 'white';
}
diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json
index 22df1b8907ca..084e4a07e6db 100644
--- a/packages/jest-haste-map/package.json
+++ b/packages/jest-haste-map/package.json
@@ -22,8 +22,7 @@
"jest-worker": "^26.1.0",
"micromatch": "^4.0.2",
"sane": "^4.0.3",
- "walker": "^1.0.7",
- "which": "^2.0.2"
+ "walker": "^1.0.7"
},
"devDependencies": {
"@jest/test-utils": "^26.0.0",
@@ -31,7 +30,7 @@
"@types/fb-watchman": "^2.0.0",
"@types/micromatch": "^4.0.0",
"@types/sane": "^2.0.0",
- "@types/which": "^1.3.2"
+ "slash": "^3.0.0"
},
"optionalDependencies": {
"fsevents": "^2.1.2"
diff --git a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js
index c972f0da6dd1..467c0acb9195 100644
--- a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js
+++ b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js
@@ -8,12 +8,15 @@
'use strict';
-import {skipSuiteOnWindows} from '@jest/test-utils';
-
jest.mock('child_process', () => ({
spawn: jest.fn((cmd, args) => {
let closeCallback;
return {
+ on: jest.fn().mockImplementation((event, callback) => {
+ if (event === 'exit') {
+ callback(mockSpawnExit, null);
+ }
+ }),
stdout: {
on: jest.fn().mockImplementation((event, callback) => {
if (event === 'data') {
@@ -34,6 +37,7 @@ jest.mock('child_process', () => ({
let mockHasReaddirWithFileTypesSupport = false;
jest.mock('graceful-fs', () => {
+ const slash = require('slash');
let mtime = 32;
const size = 42;
const stat = (path, callback) => {
@@ -41,10 +45,10 @@ jest.mock('graceful-fs', () => {
() =>
callback(null, {
isDirectory() {
- return path.endsWith('/directory');
+ return slash(path).endsWith('/directory');
},
isSymbolicLink() {
- return path.endsWith('symlink');
+ return slash(path).endsWith('symlink');
},
mtime: {
getTime() {
@@ -70,7 +74,7 @@ jest.mock('graceful-fs', () => {
}
if (mockHasReaddirWithFileTypesSupport) {
- if (dir === '/project/fruits') {
+ if (slash(dir) === '/project/fruits') {
setTimeout(
() =>
callback(null, [
@@ -92,7 +96,7 @@ jest.mock('graceful-fs', () => {
]),
0,
);
- } else if (dir === '/project/fruits/directory') {
+ } else if (slash(dir) === '/project/fruits/directory') {
setTimeout(
() =>
callback(null, [
@@ -104,18 +108,18 @@ jest.mock('graceful-fs', () => {
]),
0,
);
- } else if (dir == '/error') {
+ } else if (slash(dir) == '/error') {
setTimeout(() => callback({code: 'ENOTDIR'}, undefined), 0);
}
} else {
- if (dir === '/project/fruits') {
+ if (slash(dir) === '/project/fruits') {
setTimeout(
() => callback(null, ['directory', 'tomato.js', 'symlink']),
0,
);
- } else if (dir === '/project/fruits/directory') {
+ } else if (slash(dir) === '/project/fruits/directory') {
setTimeout(() => callback(null, ['strawberry.js']), 0);
- } else if (dir == '/error') {
+ } else if (slash(dir) == '/error') {
setTimeout(() => callback({code: 'ENOTDIR'}, undefined), 0);
}
}
@@ -124,35 +128,32 @@ jest.mock('graceful-fs', () => {
};
});
-jest.mock('which', () => jest.fn().mockResolvedValue());
-
const pearMatcher = path => /pear/.test(path);
-const createMap = obj => new Map(Object.keys(obj).map(key => [key, obj[key]]));
+const normalize = path =>
+ process.platform === 'win32' ? path.replace(/\//g, '\\') : path;
+const createMap = obj =>
+ new Map(Object.keys(obj).map(key => [normalize(key), obj[key]]));
const rootDir = '/project';
let mockResponse;
+let mockSpawnExit;
let nodeCrawl;
let childProcess;
describe('node crawler', () => {
- skipSuiteOnWindows();
-
beforeEach(() => {
jest.resetModules();
- // Remove the "process.platform" property descriptor so it can be writable.
- delete process.platform;
-
mockResponse = [
'/project/fruits/pear.js',
'/project/fruits/strawberry.js',
'/project/fruits/tomato.js',
].join('\n');
+
+ mockSpawnExit = 0;
});
it('crawls for files based on patterns', () => {
- process.platform = 'linux';
-
childProcess = require('child_process');
nodeCrawl = require('../node');
@@ -203,8 +204,6 @@ describe('node crawler', () => {
});
it('updates only changed files', () => {
- process.platform = 'linux';
-
nodeCrawl = require('../node');
// In this test sample, strawberry is changed and tomato is unchanged
@@ -229,15 +228,13 @@ describe('node crawler', () => {
);
// Make sure it is the *same* unchanged object.
- expect(hasteMap.files.get('fruits/tomato.js')).toBe(tomato);
+ expect(hasteMap.files.get(normalize('fruits/tomato.js'))).toBe(tomato);
expect(removedFiles).toEqual(new Map());
});
});
it('returns removed files', () => {
- process.platform = 'linux';
-
nodeCrawl = require('../node');
// In this test sample, previouslyExisted was present before and will not be
@@ -269,8 +266,10 @@ describe('node crawler', () => {
});
});
- it('uses node fs APIs on windows', () => {
- process.platform = 'win32';
+ it('uses node fs APIs with incompatible find binary', () => {
+ mockResponse = '';
+ mockSpawnExit = 1;
+ childProcess = require('child_process');
nodeCrawl = require('../node');
@@ -283,6 +282,7 @@ describe('node crawler', () => {
rootDir,
roots: ['/project/fruits'],
}).then(({hasteMap, removedFiles}) => {
+ expect(childProcess.spawn).lastCalledWith('find', ['.', '-iname', "''"]);
expect(hasteMap.files).toEqual(
createMap({
'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null],
@@ -293,11 +293,11 @@ describe('node crawler', () => {
});
});
- it('uses node fs APIs on Unix based OS without find binary', () => {
- process.platform = 'linux';
- const which = require('which');
- which.mockReturnValueOnce(Promise.reject());
-
+ it('uses node fs APIs without find binary', () => {
+ childProcess = require('child_process');
+ childProcess.spawn.mockImplementationOnce(() => {
+ throw new Error();
+ });
nodeCrawl = require('../node');
return nodeCrawl({
@@ -316,13 +316,11 @@ describe('node crawler', () => {
}),
);
expect(removedFiles).toEqual(new Map());
- expect(which).toBeCalledWith('find');
});
});
it('uses node fs APIs if "forceNodeFilesystemAPI" is set to true, regardless of platform', () => {
- process.platform = 'linux';
-
+ childProcess = require('child_process');
nodeCrawl = require('../node');
const files = new Map();
@@ -334,6 +332,7 @@ describe('node crawler', () => {
rootDir,
roots: ['/project/fruits'],
}).then(({hasteMap, removedFiles}) => {
+ expect(childProcess.spawn).toHaveBeenCalledTimes(0);
expect(hasteMap.files).toEqual(
createMap({
'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null],
@@ -345,8 +344,6 @@ describe('node crawler', () => {
});
it('completes with empty roots', () => {
- process.platform = 'win32';
-
nodeCrawl = require('../node');
const files = new Map();
@@ -364,14 +361,13 @@ describe('node crawler', () => {
});
it('completes with fs.readdir throwing an error', () => {
- process.platform = 'win32';
-
nodeCrawl = require('../node');
const files = new Map();
return nodeCrawl({
data: {files},
extensions: ['js'],
+ forceNodeFilesystemAPI: true,
ignore: pearMatcher,
rootDir,
roots: ['/error'],
diff --git a/packages/jest-haste-map/src/crawlers/node.ts b/packages/jest-haste-map/src/crawlers/node.ts
index 0266816d91fb..be6bcae43b05 100644
--- a/packages/jest-haste-map/src/crawlers/node.ts
+++ b/packages/jest-haste-map/src/crawlers/node.ts
@@ -8,7 +8,6 @@
import * as path from 'path';
import {spawn} from 'child_process';
import * as fs from 'graceful-fs';
-import which = require('which');
import H from '../constants';
import * as fastPath from '../lib/fast_path';
import type {
@@ -25,13 +24,22 @@ type Callback = (result: Result) => void;
async function hasNativeFindSupport(
forceNodeFilesystemAPI: boolean,
): Promise {
- if (forceNodeFilesystemAPI || process.platform === 'win32') {
+ if (forceNodeFilesystemAPI) {
return false;
}
try {
- await which('find');
- return true;
+ return await new Promise(resolve => {
+ // Check the find binary supports the non-POSIX -iname parameter.
+ const args = ['.', '-iname', "''"];
+ const child = spawn('find', args);
+ child.on('error', () => {
+ resolve(false);
+ });
+ child.on('exit', code => {
+ resolve(code === 0);
+ });
+ });
} catch {
return false;
}
diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts
index d2725ead5917..1b13136f055b 100644
--- a/packages/jest-reporters/src/types.ts
+++ b/packages/jest-reporters/src/types.ts
@@ -12,7 +12,7 @@ import type {
TestResult,
} from '@jest/test-result';
import type {FS as HasteFS, ModuleMap} from 'jest-haste-map';
-import HasteResolver = require('jest-resolve');
+import type {ResolverType} from 'jest-resolve';
import type {worker} from './coverage_worker';
export type ReporterOnStartOptions = {
@@ -24,7 +24,7 @@ export type Context = {
config: Config.ProjectConfig;
hasteFS: HasteFS;
moduleMap: ModuleMap;
- resolver: HasteResolver;
+ resolver: ResolverType;
};
export type Test = {
diff --git a/packages/jest-resolve-dependencies/src/index.ts b/packages/jest-resolve-dependencies/src/index.ts
index a16092ab73de..d016fadaabcf 100644
--- a/packages/jest-resolve-dependencies/src/index.ts
+++ b/packages/jest-resolve-dependencies/src/index.ts
@@ -7,7 +7,7 @@
import type {Config} from '@jest/types';
import type {FS as HasteFS} from 'jest-haste-map';
-import Resolver = require('jest-resolve');
+import type {ResolveModuleConfig, ResolverType} from 'jest-resolve';
import {SnapshotResolver, isSnapshotPath} from 'jest-snapshot';
namespace DependencyResolver {
@@ -24,11 +24,11 @@ namespace DependencyResolver {
/* eslint-disable-next-line no-redeclare */
class DependencyResolver {
private _hasteFS: HasteFS;
- private _resolver: Resolver;
+ private _resolver: ResolverType;
private _snapshotResolver: SnapshotResolver;
constructor(
- resolver: Resolver,
+ resolver: ResolverType,
hasteFS: HasteFS,
snapshotResolver: SnapshotResolver,
) {
@@ -39,7 +39,7 @@ class DependencyResolver {
resolve(
file: Config.Path,
- options?: Resolver.ResolveModuleConfig,
+ options?: ResolveModuleConfig,
): Array {
const dependencies = this._hasteFS.getDependencies(file);
if (!dependencies) {
@@ -76,7 +76,7 @@ class DependencyResolver {
resolveInverseModuleMap(
paths: Set,
filter: (file: Config.Path) => boolean,
- options?: Resolver.ResolveModuleConfig,
+ options?: ResolveModuleConfig,
): Array {
if (!paths.size) {
return [];
@@ -141,7 +141,7 @@ class DependencyResolver {
resolveInverse(
paths: Set,
filter: (file: Config.Path) => boolean,
- options?: Resolver.ResolveModuleConfig,
+ options?: ResolveModuleConfig,
): Array {
return this.resolveInverseModuleMap(paths, filter, options).map(
module => module.file,
diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts
index 7588ded4b93c..b52786716917 100644
--- a/packages/jest-resolve/src/index.ts
+++ b/packages/jest-resolve/src/index.ts
@@ -37,6 +37,7 @@ namespace Resolver {
skipNodeResolution?: boolean;
paths?: Array;
};
+ export type ResolverType = Resolver;
}
const NATIVE_PLATFORM = 'native';
diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts
index bc73db185c42..13e574b40436 100644
--- a/packages/jest-runner/src/runTest.ts
+++ b/packages/jest-runner/src/runTest.ts
@@ -21,7 +21,7 @@ import RuntimeClass = require('jest-runtime');
import * as fs from 'graceful-fs';
import {ErrorWithStack, interopRequireDefault, setGlobal} from 'jest-util';
import LeakDetector from 'jest-leak-detector';
-import Resolver = require('jest-resolve');
+import type {ResolverType} from 'jest-resolve';
import {getTestEnvironment} from 'jest-config';
import * as docblock from 'jest-docblock';
import {formatExecError} from 'jest-message-util';
@@ -79,7 +79,7 @@ async function runTestInternal(
path: Config.Path,
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
- resolver: Resolver,
+ resolver: ResolverType,
context?: TestRunnerContext,
): Promise {
const testSource = fs.readFileSync(path, 'utf8');
@@ -311,7 +311,7 @@ export default async function runTest(
path: Config.Path,
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
- resolver: Resolver,
+ resolver: ResolverType,
context?: TestRunnerContext,
): Promise {
const {leakDetector, result} = await runTestInternal(
diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts
index 70d45328a4ab..8e91bc12c2ce 100644
--- a/packages/jest-runner/src/testWorker.ts
+++ b/packages/jest-runner/src/testWorker.ts
@@ -12,7 +12,7 @@ import HasteMap = require('jest-haste-map');
import exit = require('exit');
import {separateMessageFromStack} from 'jest-message-util';
import Runtime = require('jest-runtime');
-import Resolver = require('jest-resolve');
+import type {ResolverType} from 'jest-resolve';
import type {ErrorWithCode, TestRunnerSerializedContext} from './types';
import runTest from './runTest';
@@ -52,7 +52,7 @@ const formatError = (error: string | ErrorWithCode): SerializableError => {
};
};
-const resolvers = new Map();
+const resolvers = new Map();
const getResolver = (config: Config.ProjectConfig) => {
const resolver = resolvers.get(config.name);
if (!resolver) {
diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts
index c4fc43117ff0..69d9525ff73c 100644
--- a/packages/jest-runner/src/types.ts
+++ b/packages/jest-runner/src/types.ts
@@ -10,8 +10,8 @@ import type {Config} from '@jest/types';
import type {SerializableError, TestResult} from '@jest/test-result';
import type {JestEnvironment} from '@jest/environment';
import type {FS as HasteFS, ModuleMap} from 'jest-haste-map';
-import HasteResolver = require('jest-resolve');
-import Runtime = require('jest-runtime');
+import type {ResolverType} from 'jest-resolve';
+import type {RuntimeType} from 'jest-runtime';
export type ErrorWithCode = Error & {code?: string};
export type Test = {
@@ -24,7 +24,7 @@ export type Context = {
config: Config.ProjectConfig;
hasteFS: HasteFS;
moduleMap: ModuleMap;
- resolver: HasteResolver;
+ resolver: ResolverType;
};
export type OnTestStart = (test: Test) => Promise;
@@ -41,7 +41,7 @@ export type TestFramework = (
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
environment: JestEnvironment,
- runtime: Runtime,
+ runtime: RuntimeType,
testPath: string,
) => Promise;
diff --git a/packages/jest-runtime/src/types.ts b/packages/jest-runtime/src/types.ts
index 51e98aad130c..7ef3887ec060 100644
--- a/packages/jest-runtime/src/types.ts
+++ b/packages/jest-runtime/src/types.ts
@@ -6,12 +6,12 @@
*/
import type {Config} from '@jest/types';
-import HasteResolver = require('jest-resolve');
+import type {ResolverType} from 'jest-resolve';
import type {FS as HasteFS, ModuleMap} from 'jest-haste-map';
export type Context = {
config: Config.ProjectConfig;
hasteFS: HasteFS;
moduleMap: ModuleMap;
- resolver: HasteResolver;
+ resolver: ResolverType;
};
diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts
index 76a7b33a8f77..079061013c83 100644
--- a/packages/jest-types/src/Config.ts
+++ b/packages/jest-types/src/Config.ts
@@ -7,7 +7,7 @@
import type {Arguments} from 'yargs';
import type {ReportOptions} from 'istanbul-reports';
-import chalk = require('chalk');
+import type {ForegroundColor} from 'chalk';
type CoverageProvider = 'babel' | 'v8';
@@ -86,7 +86,7 @@ export type DefaultOptions = {
export type DisplayName = {
name: string;
- color: typeof chalk.Color;
+ color: typeof ForegroundColor;
};
export type InitialOptionsWithRootDir = InitialOptions &
diff --git a/website/blog/2017-05-06-jest-20-delightful-testing-multi-project-runner.md b/website/blog/2017-05-06-jest-20-delightful-testing-multi-project-runner.md
index 834d1ad7e6a6..f7e321142409 100644
--- a/website/blog/2017-05-06-jest-20-delightful-testing-multi-project-runner.md
+++ b/website/blog/2017-05-06-jest-20-delightful-testing-multi-project-runner.md
@@ -37,7 +37,7 @@ Finally, we are now properly mapping code coverage when using TypeScript and we
We made a number of additions and improvements to the testing APIs which will help write more effective tests. We'd like to point out that all of these improvements were made entirely by community members!
- **Better async testing:** Added new async/Promise support through resolves/rejects modifiers on expect: `expect(Promise(…)).resolves.toEqual(…)`. [See documentation](https://jestjs.io/docs/en/expect.html#resolves).
-- **Expect assertions:** Along with the existing `expect.assertions(n)`, the new `expect.hasAssertions()` can be used to ensure a test has at least one assertion.
+- **Expect `n` assertions:** Along with the existing `expect.assertions(n)`, the new `expect.hasAssertions()` can be used to ensure a test has at least one assertion.
- **Lint Plugin:** A `valid-expect` rule was added to `eslint-plugin-jest` to ensure that an assertion is called after invoking `expect`. This will prevent mistakes like a stray `expect(banana);` with a missing assertion call.
- **Pretty-Format Plugins:** A number of new pretty-format plugins were added to Jest. We now pretty-print [Immutable.js](https://github.com/facebook/immutable-js/) data structures and HtmlElements in assertion failures and snapshots.
- **Custom Environment:** It is now possible to add a `@jest-environment node|jsdom` annotation to the doc-block comment of a test file to use a test environment different from the default for individual tests.
diff --git a/website/versioned_docs/version-22.x/CLI.md b/website/versioned_docs/version-22.x/CLI.md
index 89a0deb70a1d..fb8994023a37 100644
--- a/website/versioned_docs/version-22.x/CLI.md
+++ b/website/versioned_docs/version-22.x/CLI.md
@@ -124,7 +124,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-An array of glob patterns relative to matching the files that coverage info needs to be collected from.
+An array of glob patterns relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -132,7 +132,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage`
diff --git a/website/versioned_docs/version-22.x/Es6ClassMocks.md b/website/versioned_docs/version-22.x/Es6ClassMocks.md
new file mode 100644
index 000000000000..9c6400e39d2b
--- /dev/null
+++ b/website/versioned_docs/version-22.x/Es6ClassMocks.md
@@ -0,0 +1,333 @@
+---
+id: version-22.x-es6-class-mocks
+title: ES6 Class Mocks
+original_id: es6-class-mocks
+---
+
+Jest can be used to mock ES6 classes that are imported into files you want to test.
+
+ES6 classes are constructor functions with some syntactic sugar. Therefore, any mock for an ES6 class must be a function or an actual ES6 class (which is, again, another function). So you can mock them using [mock functions](MockFunctions.md).
+
+## An ES6 Class Example
+
+We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`.
+
+```javascript
+// sound-player.js
+export default class SoundPlayer {
+ constructor() {
+ this.foo = 'bar';
+ }
+
+ playSoundFile(fileName) {
+ console.log('Playing sound file ' + fileName);
+ }
+}
+```
+
+```javascript
+// sound-player-consumer.js
+import SoundPlayer from './sound-player';
+
+export default class SoundPlayerConsumer {
+ constructor() {
+ this.soundPlayer = new SoundPlayer();
+ }
+
+ playSomethingCool() {
+ const coolSoundFileName = 'song.mp3';
+ this.soundPlayer.playSoundFile(coolSoundFileName);
+ }
+}
+```
+
+## The 4 ways to create an ES6 class mock
+
+### Automatic mock
+
+Calling `jest.mock('./sound-player')` returns a useful "automatic mock" you can use to spy on calls to the class constructor and all of its methods. It replaces the ES6 class with a mock constructor, and replaces all of its methods with [mock functions](MockFunctions.md) that always return `undefined`. Method calls are saved in `theAutomaticMock.mock.instances[index].methodName.mock.calls`.
+
+If you don't need to replace the implementation of the class, this is the easiest option to set up. For example:
+
+```javascript
+import SoundPlayer from './sound-player';
+import SoundPlayerConsumer from './sound-player-consumer';
+jest.mock('./sound-player'); // SoundPlayer is now a mock constructor
+
+beforeEach(() => {
+ // Clear all instances and calls to constructor and all methods:
+ SoundPlayer.mockClear();
+});
+
+it('We can check if the consumer called the class constructor', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ expect(SoundPlayer).toHaveBeenCalledTimes(1);
+});
+
+it('We can check if the consumer called a method on the class instance', () => {
+ // Show that mockClear() is working:
+ expect(SoundPlayer).not.toHaveBeenCalled();
+
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ // Constructor should have been called again:
+ expect(SoundPlayer).toHaveBeenCalledTimes(1);
+
+ const coolSoundFileName = 'song.mp3';
+ soundPlayerConsumer.playSomethingCool();
+
+ // mock.instances is available with automatic mocks:
+ const mockSoundPlayerInstance = SoundPlayer.mock.instances[0];
+ const mockPlaySoundFile = mockSoundPlayerInstance.playSoundFile;
+ expect(mockPlaySoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
+ // Equivalent to above check:
+ expect(mockPlaySoundFile).toHaveBeenCalledWith(coolSoundFileName);
+ expect(mockPlaySoundFile).toHaveBeenCalledTimes(1);
+});
+```
+
+### Manual mock
+
+Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files.
+
+```javascript
+// __mocks__/sound-player.js
+
+// Import this named export into your test file:
+export const mockPlaySoundFile = jest.fn();
+const mock = jest.fn().mockImplementation(() => {
+ return {playSoundFile: mockPlaySoundFile};
+});
+
+export default mock;
+```
+
+Import the mock and the mock method shared by all instances:
+
+```javascript
+// sound-player-consumer.test.js
+import SoundPlayer, {mockPlaySoundFile} from './sound-player';
+import SoundPlayerConsumer from './sound-player-consumer';
+jest.mock('./sound-player'); // SoundPlayer is now a mock constructor
+
+beforeEach(() => {
+ // Clear all instances and calls to constructor and all methods:
+ SoundPlayer.mockClear();
+ mockPlaySoundFile.mockClear();
+});
+
+it('We can check if the consumer called the class constructor', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ expect(SoundPlayer).toHaveBeenCalledTimes(1);
+});
+
+it('We can check if the consumer called a method on the class instance', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ const coolSoundFileName = 'song.mp3';
+ soundPlayerConsumer.playSomethingCool();
+ expect(mockPlaySoundFile).toHaveBeenCalledWith(coolSoundFileName);
+});
+```
+
+### Calling [`jest.mock()`](JestObjectAPI.md#jestmockmodulename-factory-options) with the module factory parameter
+
+`jest.mock(path, moduleFactory)` takes a **module factory** argument. A module factory is a function that returns the mock.
+
+In order to mock a constructor function, the module factory must return a constructor function. In other words, the module factory must be a function that returns a function - a higher-order function (HOF).
+
+```javascript
+import SoundPlayer from './sound-player';
+const mockPlaySoundFile = jest.fn();
+jest.mock('./sound-player', () => {
+ return jest.fn().mockImplementation(() => {
+ return {playSoundFile: mockPlaySoundFile};
+ });
+});
+```
+
+A limitation with the factory parameter is that, since calls to `jest.mock()` are hoisted to the top of the file, it's not possible to first define a variable and then use it in the factory. An exception is made for variables that start with the word 'mock'. It's up to you to guarantee that they will be initialized on time!
+
+### Replacing the mock using [`mockImplementation()`](MockFunctionAPI.md#mockfnmockimplementationfn) or [`mockImplementationOnce()`](MockFunctionAPI.md#mockfnmockimplementationoncefn)
+
+You can replace all of the above mocks in order to change the implementation, for a single test or all tests, by calling `mockImplementation()` on the existing mock.
+
+Calls to jest.mock are hoisted to the top of the code. You can specify a mock later, e.g. in `beforeAll()`, by calling `mockImplementation()` (or `mockImplementationOnce()`) on the existing mock instead of using the factory parameter. This also allows you to change the mock between tests, if needed:
+
+```javascript
+import SoundPlayer from './sound-player';
+jest.mock('./sound-player');
+
+describe('When SoundPlayer throws an error', () => {
+ beforeAll(() => {
+ SoundPlayer.mockImplementation(() => {
+ return {
+ playSoundFile: () => {
+ throw new Error('Test error');
+ },
+ };
+ });
+ });
+
+ it('Should throw an error when calling playSomethingCool', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ expect(() => soundPlayerConsumer.playSomethingCool()).toThrow();
+ });
+});
+```
+
+## In depth: Understanding mock constructor functions
+
+Building your constructor function mock using `jest.fn().mockImplementation()` makes mocks appear more complicated than they really are. This section shows how you can create your own simple mocks to illustrate how mocking works.
+
+### Manual mock that is another ES6 class
+
+If you define an ES6 class using the same filename as the mocked class in the `__mocks__` folder, it will serve as the mock. This class will be used in place of the real class. This allows you to inject a test implementation for the class, but does not provide a way to spy on calls.
+
+For the contrived example, the mock might look like this:
+
+```javascript
+// __mocks/sound-player.js
+export default class SoundPlayer {
+ constructor() {
+ console.log('Mock SoundPlayer: constructor was called');
+ }
+
+ playSoundFile() {
+ console.log('Mock SoundPlayer: playSoundFile was called');
+ }
+}
+```
+
+### Simple mock using module factory parameter
+
+The module factory function passed to `jest.mock(path, moduleFactory)` can be a HOF that returns a function\*. This will allow calling `new` on the mock. Again, this allows you to inject different behavior for testing, but does not provide a way to spy on calls.
+
+#### \* Module factory function must return a function
+
+In order to mock a constructor function, the module factory must return a constructor function. In other words, the module factory must be a function that returns a function - a higher-order function (HOF).
+
+```javascript
+jest.mock('./sound-player', () => {
+ return function () {
+ return {playSoundFile: () => {}};
+ };
+});
+```
+
+**_Note: Arrow functions won't work_**
+
+Note that the mock can't be an arrow function because calling `new` on an arrow function is not allowed in Javascript. So this won't work:
+
+```javascript
+jest.mock('./sound-player', () => {
+ return () => {
+ // Does not work; arrow functions can't be called with new
+ return {playSoundFile: () => {}};
+ };
+});
+```
+
+This will throw **_TypeError: \_soundPlayer2.default is not a constructor_**, unless the code is transpiled to ES5, e.g. by babel-preset-env. (ES5 doesn't have arrow functions nor classes, so both will be transpiled to plain functions.)
+
+## Keeping track of usage (spying on the mock)
+
+Injecting a test implementation is helpful, but you will probably also want to test whether the class constructor and methods are called with the correct parameters.
+
+### Spying on the constructor
+
+In order to track calls to the constructor, replace the function returned by the HOF with a Jest mock function. Create it with [`jest.fn()`](JestObjectAPI.md#jestfnimplementation), and then specify its implementation with `mockImplementation()`.
+
+```javascript
+import SoundPlayer from './sound-player';
+jest.mock('./sound-player', () => {
+ // Works and lets you check for constructor calls:
+ return jest.fn().mockImplementation(() => {
+ return {playSoundFile: () => {}};
+ });
+});
+```
+
+This will let us inspect usage of our mocked class, using `SoundPlayer.mock.calls`: `expect(SoundPlayer).toHaveBeenCalled();` or near-equivalent: `expect(SoundPlayer.mock.calls.length).toEqual(1);`
+
+### Spying on methods of our class
+
+Our mocked class will need to provide any member functions (`playSoundFile` in the example) that will be called during our tests, or else we'll get an error for calling a function that doesn't exist. But we'll probably want to also spy on calls to those methods, to ensure that they were called with the expected parameters.
+
+A new object will be created each time the mock constructor function is called during tests. To spy on method calls in all of these objects, we populate `playSoundFile` with another mock function, and store a reference to that same mock function in our test file, so it's available during tests.
+
+```javascript
+import SoundPlayer from './sound-player';
+const mockPlaySoundFile = jest.fn();
+jest.mock('./sound-player', () => {
+ return jest.fn().mockImplementation(() => {
+ return {playSoundFile: mockPlaySoundFile};
+ // Now we can track calls to playSoundFile
+ });
+});
+```
+
+The manual mock equivalent of this would be:
+
+```javascript
+// __mocks__/sound-player.js
+
+// Import this named export into your test file
+export const mockPlaySoundFile = jest.fn();
+const mock = jest.fn().mockImplementation(() => {
+ return {playSoundFile: mockPlaySoundFile};
+});
+
+export default mock;
+```
+
+Usage is similar to the module factory function, except that you can omit the second argument from `jest.mock()`, and you must import the mocked method into your test file, since it is no longer defined there. Use the original module path for this; don't include `__mocks__`.
+
+### Cleaning up between tests
+
+To clear the record of calls to the mock constructor function and its methods, we call [`mockClear()`](MockFunctionAPI.md#mockfnmockclear) in the `beforeEach()` function:
+
+```javascript
+beforeEach(() => {
+ SoundPlayer.mockClear();
+ mockPlaySoundFile.mockClear();
+});
+```
+
+## Complete example
+
+Here's a complete test file which uses the module factory parameter to `jest.mock`:
+
+```javascript
+// sound-player-consumer.test.js
+import SoundPlayerConsumer from './sound-player-consumer';
+import SoundPlayer from './sound-player';
+
+const mockPlaySoundFile = jest.fn();
+jest.mock('./sound-player', () => {
+ return jest.fn().mockImplementation(() => {
+ return {playSoundFile: mockPlaySoundFile};
+ });
+});
+
+beforeEach(() => {
+ SoundPlayer.mockClear();
+ mockPlaySoundFile.mockClear();
+});
+
+it('The consumer should be able to call new() on SoundPlayer', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ // Ensure constructor created the object:
+ expect(soundPlayerConsumer).toBeTruthy();
+});
+
+it('We can check if the consumer called the class constructor', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ expect(SoundPlayer).toHaveBeenCalledTimes(1);
+});
+
+it('We can check if the consumer called a method on the class instance', () => {
+ const soundPlayerConsumer = new SoundPlayerConsumer();
+ const coolSoundFileName = 'song.mp3';
+ soundPlayerConsumer.playSomethingCool();
+ expect(mockPlaySoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
+});
+```
diff --git a/website/versioned_docs/version-23.x/CLI.md b/website/versioned_docs/version-23.x/CLI.md
index 71ab11e04ff8..b17d28bb2c88 100644
--- a/website/versioned_docs/version-23.x/CLI.md
+++ b/website/versioned_docs/version-23.x/CLI.md
@@ -124,7 +124,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-A glob pattern relative to matching the files that coverage info needs to be collected from.
+A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -132,7 +132,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage`
diff --git a/website/versioned_docs/version-23.x/WatchPlugins.md b/website/versioned_docs/version-23.x/WatchPlugins.md
index 5dc902fb48a8..a24d3191d903 100644
--- a/website/versioned_docs/version-23.x/WatchPlugins.md
+++ b/website/versioned_docs/version-23.x/WatchPlugins.md
@@ -226,8 +226,8 @@ Any key not used by built-in functionality can be claimed, as you would expect.
Should your plugin attempt to overwrite a reserved key, Jest will error out with a descriptive message, something like:
-> Watch plugin YourFaultyPlugin attempted to register key , that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
+> Watch plugin YourFaultyPlugin attempted to register key `q`, that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
Third-party plugins are also forbidden to overwrite a key reserved already by another third-party plugin present earlier in the configured plugins list (`watchPlugins` array setting). When this happens, you’ll also get an error message that tries to help you fix that:
-> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key . Please change the key configuration for one of the conflicting plugins to avoid overlap.
+> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key `x`. Please change the key configuration for one of the conflicting plugins to avoid overlap.
diff --git a/website/versioned_docs/version-24.x/CLI.md b/website/versioned_docs/version-24.x/CLI.md
index 6ebff30b3245..c88177adbfb9 100644
--- a/website/versioned_docs/version-24.x/CLI.md
+++ b/website/versioned_docs/version-24.x/CLI.md
@@ -139,7 +139,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-A glob pattern relative to matching the files that coverage info needs to be collected from.
+A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -147,7 +147,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage`
diff --git a/website/versioned_docs/version-24.x/WatchPlugins.md b/website/versioned_docs/version-24.x/WatchPlugins.md
index 8a23740ad169..5fbf79d38227 100644
--- a/website/versioned_docs/version-24.x/WatchPlugins.md
+++ b/website/versioned_docs/version-24.x/WatchPlugins.md
@@ -225,8 +225,8 @@ Any key not used by built-in functionality can be claimed, as you would expect.
Should your plugin attempt to overwrite a reserved key, Jest will error out with a descriptive message, something like:
-> Watch plugin YourFaultyPlugin attempted to register key , that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
+> Watch plugin YourFaultyPlugin attempted to register key `q`, that is reserved internally for quitting watch mode. Please change the configuration key for this plugin.
Third-party plugins are also forbidden to overwrite a key reserved already by another third-party plugin present earlier in the configured plugins list (`watchPlugins` array setting). When this happens, you’ll also get an error message that tries to help you fix that:
-> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key . Please change the key configuration for one of the conflicting plugins to avoid overlap.
+> Watch plugins YourFaultyPlugin and TheirFaultyPlugin both attempted to register key `x`. Please change the key configuration for one of the conflicting plugins to avoid overlap.
diff --git a/website/versioned_docs/version-25.x/CLI.md b/website/versioned_docs/version-25.x/CLI.md
index 3194db9e7236..2baea0f21bdb 100644
--- a/website/versioned_docs/version-25.x/CLI.md
+++ b/website/versioned_docs/version-25.x/CLI.md
@@ -139,7 +139,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-A glob pattern relative to matching the files that coverage info needs to be collected from.
+A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -147,7 +147,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage[=]`
diff --git a/website/versioned_docs/version-26.0/CLI.md b/website/versioned_docs/version-26.0/CLI.md
index 31c9ed47c40a..91ad9349e8ec 100644
--- a/website/versioned_docs/version-26.0/CLI.md
+++ b/website/versioned_docs/version-26.0/CLI.md
@@ -139,7 +139,7 @@ Deletes the Jest cache directory and then exits without running tests. Will dele
### `--collectCoverageFrom=`
-A glob pattern relative to matching the files that coverage info needs to be collected from.
+A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from.
### `--colors`
@@ -147,7 +147,7 @@ Forces test results output highlighting even if stdout is not a TTY.
### `--config=`
-Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the rootDir for the project. This can also be a JSON-encoded value which Jest will use as configuration.
+Alias: `-c`. The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.
### `--coverage[=]`
diff --git a/yarn.lock b/yarn.lock
index 0e2c65f6a462..03cc3ab26a01 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11208,7 +11208,6 @@ fsevents@^1.2.7:
"@types/micromatch": ^4.0.0
"@types/node": "*"
"@types/sane": ^2.0.0
- "@types/which": ^1.3.2
anymatch: ^3.0.3
fb-watchman: ^2.0.0
fsevents: ^2.1.2
@@ -11219,8 +11218,8 @@ fsevents@^1.2.7:
jest-worker: ^26.1.0
micromatch: ^4.0.2
sane: ^4.0.3
+ slash: ^3.0.0
walker: ^1.0.7
- which: ^2.0.2
dependenciesMeta:
fsevents:
optional: true