Skip to content

Commit

Permalink
feat(expect): migrate to ESM (#12344)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Feb 9, 2022
1 parent 1b402ab commit 7f7b3fb
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 59 deletions.
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

0 comments on commit 7f7b3fb

Please sign in to comment.