Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(expect): migrate to ESM #12344

Merged
merged 5 commits into from Feb 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions .eslintrc.js
Expand Up @@ -42,8 +42,6 @@ module.exports = {
'@typescript-eslint/prefer-ts-expect-error': 'error',
// TS verifies this
'consistent-return': 'off',
// Since we do `export =`. Remove for Jest 27
'import/default': 'off',
'no-dupe-class-members': 'off',
'no-unused-vars': 'off',
},
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

### Features

- `[expect]` [**BREAKING**] Migrate to ESM ([#12344](https://github.com/facebook/jest/pull/12344))
- `[jest-environment-jsdom]` [**BREAKING**] Add default `browser` condition to `exportConditions` for `jsdom` environment ([#11924](https://github.com/facebook/jest/pull/11924))
- `[jest-environment-jsdom]` [**BREAKING**] Migrate to ESM ([#12340](https://github.com/facebook/jest/pull/12340))
- `[jest-environment-node]` [**BREAKING**] Add default `node` and `node-addon` conditions to `exportConditions` for `node` environment ([#11924](https://github.com/facebook/jest/pull/11924))
Expand Down
1 change: 0 additions & 1 deletion babel.config.js
Expand Up @@ -17,7 +17,6 @@ module.exports = {
overrides: [
{
plugins: [
'babel-plugin-replace-ts-export-assignment',
require.resolve(
'./scripts/babel-plugin-jest-replace-ts-require-assignment.js',
),
Expand Down
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -25,7 +25,6 @@
"@typescript-eslint/parser": "^4.1.0",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
"chokidar": "^3.3.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/expect/src/__tests__/matchers.test.js
Expand Up @@ -9,7 +9,7 @@ const chalk = require('chalk');
const Immutable = require('immutable');
const {alignedAnsiStyleSerializer} = require('@jest/test-utils');
const {stringify} = require('jest-matcher-utils');
const jestExpect = require('../');
const {expect: jestExpect} = require('../');
const chalkEnabled = chalk.enabled;

expect.addSnapshotSerializer(alignedAnsiStyleSerializer);
Expand Down
34 changes: 14 additions & 20 deletions packages/expect/src/index.ts
Expand Up @@ -41,16 +41,17 @@ import type {
AsyncExpectationResult,
Expect,
ExpectationResult,
MatcherState as JestMatcherState,
Matchers as MatcherInterface,
MatcherState,
MatchersObject,
PromiseMatcherFn,
RawMatcherFn,
SyncExpectationResult,
ThrowingMatcherFn,
} from './types';

class JestAssertionError extends Error {
export type {Expect, MatcherState, Matchers} from './types';

export class JestAssertionError extends Error {
matcherResult?: Omit<SyncExpectationResult, 'message'> & {message: string};
}

Expand All @@ -63,7 +64,7 @@ const createToThrowErrorMatchingSnapshotMatcher = function (
matcher: RawMatcherFn,
) {
return function (
this: JestMatcherState,
this: MatcherState,
received: any,
testNameOrInlineSnapshot?: string,
) {
Expand All @@ -84,7 +85,7 @@ const getPromiseMatcher = (name: string, matcher: any) => {
return null;
};

const expect: any = (actual: any, ...rest: Array<any>) => {
export const expect: Expect = (actual: any, ...rest: Array<any>) => {
if (rest.length !== 0) {
throw new Error('Expect takes at most one argument.');
}
Expand Down Expand Up @@ -252,7 +253,7 @@ const makeThrowingMatcher = (
let throws = true;
const utils = {...matcherUtils, iterableEquality, subsetEquality};

const matcherContext: JestMatcherState = {
const matcherContext: MatcherState = {
// When throws is disabled, the matcher will not throw errors during test
// execution but instead add them to the global matcher state. If a
// matcher throws, test execution is normally stopped immediately. The
Expand Down Expand Up @@ -355,7 +356,7 @@ const makeThrowingMatcher = (
}
};

expect.extend = <T extends JestMatcherState = JestMatcherState>(
expect.extend = <T extends MatcherState = MatcherState>(
matchers: MatchersObject<T>,
): void => setMatchers(matchers, false, expect);

Expand Down Expand Up @@ -394,7 +395,7 @@ const _validateResult = (result: any) => {
}
};

function assertions(expected: number) {
function assertions(expected: number): void {
const error = new Error();
if (Error.captureStackTrace) {
Error.captureStackTrace(error, assertions);
Expand All @@ -405,7 +406,7 @@ function assertions(expected: number) {
expectedAssertionsNumberError: error,
});
}
function hasAssertions(...args: Array<any>) {
function hasAssertions(...args: Array<unknown>): void {
const error = new Error();
if (Error.captureStackTrace) {
Error.captureStackTrace(error, hasAssertions);
Expand All @@ -419,9 +420,9 @@ function hasAssertions(...args: Array<any>) {
}

// add default jest matchers
setMatchers(matchers, true, expect as Expect);
setMatchers(spyMatchers, true, expect as Expect);
setMatchers(toThrowMatchers, true, expect as Expect);
setMatchers(matchers, true, expect);
setMatchers(spyMatchers, true, expect);
setMatchers(toThrowMatchers, true, expect);

expect.addSnapshotSerializer = () => void 0;
expect.assertions = assertions;
Expand All @@ -430,11 +431,4 @@ expect.getState = getState;
expect.setState = setState;
expect.extractExpectedAssertionsErrors = extractExpectedAssertionsErrors;

const expectExport = expect as Expect;

declare namespace expectExport {
export type MatcherState = JestMatcherState;
export interface Matchers<R, T = unknown> extends MatcherInterface<R, T> {}
}

export = expectExport;
export default expect;
Expand Up @@ -15,7 +15,7 @@ import {
createEmptyTestResult,
} from '@jest/test-result';
import type {Circus, Config, Global} from '@jest/types';
import {extractExpectedAssertionsErrors, getState, setState} from 'expect';
import {Expect, expect} from 'expect';
import {bind} from 'jest-each';
import {formatExecError, formatResultsErrors} from 'jest-message-util';
import {
Expand All @@ -33,7 +33,7 @@ import {
} from '../state';
import testCaseReportHandler from '../testCaseReportHandler';
import {getTestID} from '../utils';
import createExpect, {Expect} from './jestExpect';
import createExpect from './jestExpect';

type Process = NodeJS.Process;

Expand Down Expand Up @@ -162,7 +162,7 @@ export const initialize = async ({
updateSnapshot,
});
// @ts-expect-error: snapshotState is a jest extension of `expect`
setState({snapshotState, testPath});
expect.setState({snapshotState, testPath});

addEventHandler(handleSnapshotStateAfterRetry(snapshotState));
if (sendMessageToJest) {
Expand Down Expand Up @@ -279,7 +279,7 @@ const handleSnapshotStateAfterRetry =
const eventHandler = async (event: Circus.Event) => {
switch (event.name) {
case 'test_start': {
setState({currentTestName: getTestID(event.test)});
expect.setState({currentTestName: getTestID(event.test)});
break;
}
case 'test_done': {
Expand All @@ -291,7 +291,7 @@ const eventHandler = async (event: Circus.Event) => {
};

const _addExpectedAssertionErrors = (test: Circus.TestEntry) => {
const failures = extractExpectedAssertionsErrors();
const failures = expect.extractExpectedAssertionsErrors();
const errors = failures.map(failure => failure.error);
test.errors = test.errors.concat(errors);
};
Expand All @@ -300,8 +300,8 @@ const _addExpectedAssertionErrors = (test: Circus.TestEntry) => {
// test execution and add them to the test result, potentially failing
// a passing test.
const _addSuppressedErrors = (test: Circus.TestEntry) => {
const {suppressedErrors} = getState();
setState({suppressedErrors: []});
const {suppressedErrors} = expect.getState();
expect.setState({suppressedErrors: []});
if (suppressedErrors.length) {
test.errors = test.errors.concat(suppressedErrors);
}
Expand Down
Expand Up @@ -6,7 +6,7 @@
*/

import type {Config} from '@jest/types';
import expect = require('expect');
import {Expect, expect} from 'expect';
import {
addSerializer,
toMatchInlineSnapshot,
Expand All @@ -15,8 +15,6 @@ import {
toThrowErrorMatchingSnapshot,
} from 'jest-snapshot';

export type Expect = typeof expect;

export default function jestExpect(
config: Pick<Config.GlobalConfig, 'expand'>,
): Expect {
Expand Down
5 changes: 2 additions & 3 deletions packages/jest-circus/src/types.ts
Expand Up @@ -5,9 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/

// Used as type
import type {Circus} from '@jest/types';
import type expect = require('expect');
import type {Expect} from 'expect';

export const STATE_SYM = Symbol(
'JEST_STATE_SYMBOL',
Expand All @@ -26,7 +25,7 @@ declare global {
STATE_SYM_SYMBOL: Circus.State;
RETRY_TIMES_SYMBOL: string;
TEST_TIMEOUT_SYMBOL: number;
expect: typeof expect;
expect: Expect;
}
}
}
4 changes: 2 additions & 2 deletions packages/jest-globals/src/index.ts
Expand Up @@ -7,11 +7,11 @@

import type {Jest} from '@jest/environment';
import type {Global} from '@jest/types';
import type importedExpect = require('expect');
import type {Expect} from 'expect';

export declare const jest: Jest;

export declare const expect: typeof importedExpect;
export declare const expect: Expect;

export declare const it: Global.GlobalAdditions['it'];
export declare const test: Global.GlobalAdditions['test'];
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-jasmine2/src/jestExpect.ts
Expand Up @@ -8,7 +8,7 @@
/* eslint-disable local/prefer-spread-eventually */

import type {Global} from '@jest/types';
import expect = require('expect');
import {MatcherState, expect} from 'expect';
import {
addSerializer,
toMatchInlineSnapshot,
Expand Down Expand Up @@ -42,7 +42,7 @@ export default function jestExpect(config: {expand: boolean}): void {
const jestMatchersObject = Object.create(null);
Object.keys(jasmineMatchersObject).forEach(name => {
jestMatchersObject[name] = function (
this: expect.MatcherState,
this: MatcherState,
...args: Array<unknown>
): RawMatcherFn {
// use "expect.extend" if you need to use equality testers (via this.equal)
Expand Down
12 changes: 6 additions & 6 deletions packages/jest-jasmine2/src/setup_jest_globals.ts
Expand Up @@ -6,7 +6,7 @@
*/

import type {Config, Global} from '@jest/types';
import {extractExpectedAssertionsErrors, getState, setState} from 'expect';
import {expect} from 'expect';
import {
SnapshotState,
addSerializer,
Expand All @@ -33,8 +33,8 @@ export type SetupOptions = {
// test execution and add them to the test result, potentially failing
// a passing test.
const addSuppressedErrors = (result: SpecResult) => {
const {suppressedErrors} = getState();
setState({suppressedErrors: []});
const {suppressedErrors} = expect.getState();
expect.setState({suppressedErrors: []});
if (suppressedErrors.length) {
result.status = 'failed';

Expand All @@ -52,7 +52,7 @@ const addSuppressedErrors = (result: SpecResult) => {
};

const addAssertionErrors = (result: SpecResult) => {
const assertionErrors = extractExpectedAssertionsErrors();
const assertionErrors = expect.extractExpectedAssertionsErrors();
if (assertionErrors.length) {
const jasmineErrors = assertionErrors.map(({actual, error, expected}) => ({
actual,
Expand All @@ -77,7 +77,7 @@ const patchJasmine = () => {
};
const onStart = attr.onStart;
attr.onStart = (context: JasmineSpec) => {
setState({currentTestName: context.getFullName()});
expect.setState({currentTestName: context.getFullName()});
onStart && onStart.call(attr, context);
};
super(attr);
Expand Down Expand Up @@ -115,7 +115,7 @@ export default async function setupJestGlobals({
updateSnapshot,
});
// @ts-expect-error: snapshotState is a jest extension of `expect`
setState({snapshotState, testPath});
expect.setState({snapshotState, testPath});
// Return it back to the outer scope (test runner outside the VM).
return snapshotState;
}
6 changes: 3 additions & 3 deletions packages/jest-jasmine2/src/types.ts
Expand Up @@ -7,7 +7,7 @@

import type {AssertionError} from 'assert';
import type {Config} from '@jest/types';
import type expect = require('expect');
import type {Expect} from 'expect';
import type CallTracker from './jasmine/CallTracker';
import type Env from './jasmine/Env';
import type JsApiReporter from './jasmine/JsApiReporter';
Expand Down Expand Up @@ -89,13 +89,13 @@ export type Jasmine = {
version: string;
testPath: Config.Path;
addMatchers: (matchers: JasmineMatchersObject) => void;
} & typeof expect &
} & Expect &
typeof globalThis;

declare global {
namespace NodeJS {
interface Global {
expect: typeof expect;
expect: Expect;
}
}
}
8 changes: 0 additions & 8 deletions yarn.lock
Expand Up @@ -2621,7 +2621,6 @@ __metadata:
"@typescript-eslint/parser": ^4.1.0
ansi-regex: ^5.0.1
ansi-styles: ^5.0.0
babel-plugin-replace-ts-export-assignment: ^0.0.2
camelcase: ^6.2.0
chalk: ^4.0.0
chokidar: ^3.3.0
Expand Down Expand Up @@ -6502,13 +6501,6 @@ __metadata:
languageName: node
linkType: hard

"babel-plugin-replace-ts-export-assignment@npm:^0.0.2":
version: 0.0.2
resolution: "babel-plugin-replace-ts-export-assignment@npm:0.0.2"
checksum: da749130fe0479cd9da73f8b3aafc62e05885b12732ce0e25976a7138dad1688a03366791b12633afdd8a702e2018ec01764c4ddb0ed0dbc3783b7e75b1b148a
languageName: node
linkType: hard

"babel-plugin-syntax-trailing-function-commas@npm:^7.0.0-beta.0":
version: 7.0.0-beta.0
resolution: "babel-plugin-syntax-trailing-function-commas@npm:7.0.0-beta.0"
Expand Down