Skip to content

Commit

Permalink
merge main into branch
Browse files Browse the repository at this point in the history
  • Loading branch information
JVBorges committed Oct 3, 2022
1 parent 219ea90 commit 3d623a3
Show file tree
Hide file tree
Showing 194 changed files with 1,383 additions and 903 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,12 @@ module.exports = {
],
env: {'jest/globals': true},
excludedFiles: ['**/__typetests__/**'],
extends: ['plugin:jest/style'],
plugins: ['jest'],
rules: {
'jest/no-alias-methods': 'error',
'jest/no-focused-tests': 'error',
'jest/no-identical-title': 'error',
'jest/prefer-to-be': 'error',
'jest/valid-expect': 'error',
},
},
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ jobs:
run: yarn typecheck:examples
- name: typecheck tests
run: yarn typecheck:tests
- name: run ESLint with type info
run: yarn lint-ts-files

lint:
name: Lint
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Features

- `[jest-config]` Add `readInitialConfig` utility function ([#13356](https://github.com/facebook/jest/pull/13356))
- `[jest-core]` Enable testResultsProcessor to be async ([#13343](https://github.com/facebook/jest/pull/13343))
- `[expect, @jest/expect-utils]` Allow `isA` utility to take a type argument ([#13355](https://github.com/facebook/jest/pull/13355))

Expand Down
2 changes: 1 addition & 1 deletion docs/Es6ClassMocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ jest.mock('./sound-player', () => {
});
```

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).toBe(1);`
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).toBeGreaterThan(0);`

### Mocking non-default class exports

Expand Down
18 changes: 9 additions & 9 deletions docs/ExpectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ it('transitions as expected', () => {
test('map calls its argument with a non-null argument', () => {
const mock = jest.fn();
[1].map(x => mock(x));
expect(mock).toBeCalledWith(expect.anything());
expect(mock).toHaveBeenCalledWith(expect.anything());
});
```

Expand All @@ -520,7 +520,7 @@ function getCat(fn) {
test('randocall calls its callback with a class instance', () => {
const mock = jest.fn();
getCat(mock);
expect(mock).toBeCalledWith(expect.any(Cat));
expect(mock).toHaveBeenCalledWith(expect.any(Cat));
});

function randocall(fn) {
Expand All @@ -530,7 +530,7 @@ function randocall(fn) {
test('randocall calls its callback with a number', () => {
const mock = jest.fn();
randocall(mock);
expect(mock).toBeCalledWith(expect.any(Number));
expect(mock).toHaveBeenCalledWith(expect.any(Number));
});
```

Expand Down Expand Up @@ -709,7 +709,7 @@ For example, let's say that we expect an `onPress` function to be called with an
test('onPress gets called with the right thing', () => {
const onPress = jest.fn();
simulatePresses(onPress);
expect(onPress).toBeCalledWith(
expect(onPress).toHaveBeenCalledWith(
expect.objectContaining({
x: expect.any(Number),
y: expect.any(Number),
Expand Down Expand Up @@ -1548,15 +1548,15 @@ test('throws on octopus', () => {
}

// Test that the error message says "yuck" somewhere: these are equivalent
expect(drinkOctopus).toThrowError(/yuck/);
expect(drinkOctopus).toThrowError('yuck');
expect(drinkOctopus).toThrow(/yuck/);
expect(drinkOctopus).toThrow('yuck');

// Test the exact error message
expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/);
expect(drinkOctopus).toThrowError(new Error('yuck, octopus flavor'));
expect(drinkOctopus).toThrow(/^yuck, octopus flavor$/);
expect(drinkOctopus).toThrow(new Error('yuck, octopus flavor'));

// Test that we get a DisgustingFlavorError
expect(drinkOctopus).toThrowError(DisgustingFlavorError);
expect(drinkOctopus).toThrow(DisgustingFlavorError);
});
```

Expand Down
4 changes: 2 additions & 2 deletions docs/GlobalAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@ const binaryStringToNumber = binString => {
describe('binaryStringToNumber', () => {
describe('given an invalid binary string', () => {
test('composed of non-numbers throws CustomError', () => {
expect(() => binaryStringToNumber('abc')).toThrowError(CustomError);
expect(() => binaryStringToNumber('abc')).toThrow(CustomError);
});

test('with extra whitespace throws CustomError', () => {
expect(() => binaryStringToNumber(' 100')).toThrowError(CustomError);
expect(() => binaryStringToNumber(' 100')).toThrow(CustomError);
});
});

Expand Down
8 changes: 4 additions & 4 deletions docs/JestObjectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,16 @@ const example = jest.createMockFromModule('../example');
test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toBe('square');
expect(example.function.length).toBe(0);
expect(example.function).toHaveLength(0);

// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toBe('asyncSquare');
expect(example.asyncFunction.length).toBe(0);
expect(example.asyncFunction).toHaveLength(0);

// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toBe('Bar');
expect(example.class.foo.name).toBe('foo');
expect(example.class.array.length).toBe(0);
expect(example.class.array).toHaveLength(0);

// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
Expand All @@ -251,7 +251,7 @@ test('should run example code', () => {
});

// creates a new empty array, ignoring the original array.
expect(example.array.length).toBe(0);
expect(example.array).toHaveLength(0);

// creates a new property with the same primitive value as the original property.
expect(example.number).toBe(123);
Expand Down
4 changes: 2 additions & 2 deletions docs/MockFunctionAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,8 @@ test('calculate calls add', () => {
// requiring `add`.
calculate(mockAdd, 1, 2);

expect(mockAdd).toBeCalledTimes(1);
expect(mockAdd).toBeCalledWith(1, 2);
expect(mockAdd).toHaveBeenCalledTimes(1);
expect(mockAdd).toHaveBeenCalledWith(1, 2);
});
```

Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ exports[`moduleNameMapper wrong array configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:896:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:891:17)
at Object.require (index.js:10:1)
at Object.require (__tests__/index.js:10:20)"
`;
Expand Down Expand Up @@ -71,7 +71,7 @@ exports[`moduleNameMapper wrong configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:896:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:891:17)
at Object.require (index.js:10:1)
at Object.require (__tests__/index.js:10:20)"
`;
8 changes: 4 additions & 4 deletions e2e/__tests__/failureDetailsProperty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,19 @@ test('that the failureDetails property is set', () => {
Object {
"actual": "",
"error": Object {
"message": "expect(received).rejects.toThrowError()
"message": "expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: 1",
},
"expected": "",
"matcherName": "",
"message": "Error: expect(received).rejects.toThrowError()
"message": "Error: expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: 1",
"passed": false,
"stack": "Error: expect(received).rejects.toThrowError()
"stack": "Error: expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: 1
Expand Down Expand Up @@ -245,7 +245,7 @@ test('that the failureDetails property is set', () => {
],
Array [
Object {
"message": "expect(received).rejects.toThrowError()
"message": "expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: 1",
Expand Down
2 changes: 1 addition & 1 deletion e2e/__tests__/jasmineAsync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('async jasmine', () => {
expect(json.numPendingTests).toBe(0);
expect(json.testResults[0].message).toBe('');

expect((result.stderr.match(/unset flag/g) || []).length).toBe(1);
expect(result.stderr.match(/unset flag/g) || []).toHaveLength(1);
});

it('works with afterEach', () => {
Expand Down
148 changes: 148 additions & 0 deletions e2e/__tests__/readInitialOptions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import path = require('path');
import execa = require('execa');
import type {ReadJestConfigOptions, readInitialOptions} from 'jest-config';

function resolveFixture(...pathSegments: Array<string>) {
return path.resolve(__dirname, '..', 'read-initial-options', ...pathSegments);
}

interface ProxyReadJestConfigOptions extends ReadJestConfigOptions {
cwd?: string;
}

/**
* These e2e tests are running via a child process, because we're running in a VM and are not allowed to `import` directly
* It also represents a more real-world example of how to run.
*/
async function proxyReadInitialOptions(
configFile: string | undefined,
options: ProxyReadJestConfigOptions,
): ReturnType<typeof readInitialOptions> {
const {stdout} = await execa(
'node',
[
require.resolve('../read-initial-options/readOptions.js'),
configFile ?? '',
JSON.stringify(options),
],
{cwd: options?.cwd},
);
return JSON.parse(stdout);
}

describe('readInitialOptions', () => {
test('should read from the cwd by default', async () => {
const configFile = resolveFixture('js-config', 'jest.config.js');
const rootDir = resolveFixture('js-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.js file', async () => {
const configFile = resolveFixture('js-config', 'jest.config.js');
const rootDir = resolveFixture('js-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a package.json file', async () => {
const configFile = resolveFixture('pkg-config', 'package.json');
const rootDir = resolveFixture('pkg-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'package.json', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.ts file', async () => {
const configFile = resolveFixture('ts-config', 'jest.config.ts');
const rootDir = resolveFixture('ts-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.ts', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.mjs file', async () => {
const configFile = resolveFixture('mjs-config', 'jest.config.mjs');
const rootDir = resolveFixture('mjs-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.mjs', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.json file', async () => {
const configFile = resolveFixture('json-config', 'jest.config.json');
const rootDir = resolveFixture('json-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.json', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest config exporting an async function', async () => {
const configFile = resolveFixture('async-config', 'jest.config.js');
const rootDir = resolveFixture('async-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'async-config', rootDir});
expect(configPath).toEqual(configFile);
});

test('should be able to skip config reading, instead read from cwd', async () => {
const expectedConfigFile = resolveFixture(
'json-config',
'jest.config.json',
);
const {config, configPath} = await proxyReadInitialOptions(
resolveFixture('js-config', 'jest.config.js'),
{
cwd: resolveFixture('json-config'),
readFromCwd: true,
},
);

expect(config).toEqual({
jestConfig: 'jest.config.json',
rootDir: path.dirname(expectedConfigFile),
});
expect(configPath).toEqual(expectedConfigFile);
});

test('should give an error when there are multiple config files', async () => {
const cwd = resolveFixture('multiple-config-files');
const error: Error = await proxyReadInitialOptions(undefined, {cwd}).catch(
error => error,
);
expect(error.message).toContain('Multiple configurations found');
expect(error.message).toContain('multiple-config-files/jest.config.js');
expect(error.message).toContain('multiple-config-files/jest.config.json');
});

test('should be able to ignore multiple config files error', async () => {
const cwd = resolveFixture('multiple-config-files');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd,
skipMultipleConfigError: true,
});
expect(config).toEqual({
jestConfig: 'jest.config.js',
rootDir: resolveFixture('multiple-config-files'),
});
expect(configPath).toEqual(
resolveFixture('multiple-config-files', 'jest.config.js'),
);
});
});
4 changes: 2 additions & 2 deletions e2e/__tests__/setupFilesAfterEnvConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('setupFilesAfterEnv', () => {

expect(result.json.numTotalTests).toBe(2);
expect(result.json.numPassedTests).toBe(2);
expect(result.json.testResults.length).toBe(2);
expect(result.json.testResults).toHaveLength(2);
expect(result.exitCode).toBe(0);
});

Expand All @@ -61,7 +61,7 @@ describe('setupFilesAfterEnv', () => {

expect(result.json.numTotalTests).toBe(1);
expect(result.json.numPassedTests).toBe(1);
expect(result.json.testResults.length).toBe(1);
expect(result.json.testResults).toHaveLength(1);
expect(result.exitCode).toBe(0);
});
});
2 changes: 1 addition & 1 deletion e2e/__tests__/testInRoot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ it('runs tests in only test.js and spec.js', () => {
.map(name => path.basename(name))
.sort();

expect(testNames.length).toBe(2);
expect(testNames).toHaveLength(2);
expect(testNames[0]).toBe('spec.js');
expect(testNames[1]).toBe('test.js');
});
Loading

0 comments on commit 3d623a3

Please sign in to comment.