diff --git a/CHANGELOG.md b/CHANGELOG.md index df696b313ca1..50486755eb58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ ### Chore & Maintenance +- `[jest-changed-files, jest-circus, jest-console, @jest/core, @jest/runtime, @jest/transform]` Use `invariant` and `notEmpty` from `jest-util` rather than own internal ([#14366](https://github.com/jestjs/jest/pull/14366)) - `[@jest/core]` Use `pluralize` from `jest-util` rather than own internal ([#14322](https://github.com/jestjs/jest/pull/14322)) ## 29.6.1 diff --git a/e2e/__tests__/__snapshots__/circusDeclarationErrors.test.ts.snap b/e2e/__tests__/__snapshots__/circusDeclarationErrors.test.ts.snap index 59acd31aae2f..0e49b62527c6 100644 --- a/e2e/__tests__/__snapshots__/circusDeclarationErrors.test.ts.snap +++ b/e2e/__tests__/__snapshots__/circusDeclarationErrors.test.ts.snap @@ -16,7 +16,7 @@ exports[`defining tests and hooks asynchronously throws 1`] = ` 14 | }); 15 | }); - at eventHandler (../../packages/jest-circus/build/eventHandler.js:140:11) + at eventHandler (../../packages/jest-circus/build/eventHandler.js:141:11) at test (__tests__/asyncDefinition.test.js:12:5) ● Test suite failed to run @@ -31,7 +31,7 @@ exports[`defining tests and hooks asynchronously throws 1`] = ` 15 | }); 16 | - at eventHandler (../../packages/jest-circus/build/eventHandler.js:103:11) + at eventHandler (../../packages/jest-circus/build/eventHandler.js:104:11) at afterAll (__tests__/asyncDefinition.test.js:13:5) ● Test suite failed to run @@ -46,7 +46,7 @@ exports[`defining tests and hooks asynchronously throws 1`] = ` 20 | }); 21 | - at eventHandler (../../packages/jest-circus/build/eventHandler.js:140:11) + at eventHandler (../../packages/jest-circus/build/eventHandler.js:141:11) at test (__tests__/asyncDefinition.test.js:18:3) ● Test suite failed to run @@ -60,6 +60,6 @@ exports[`defining tests and hooks asynchronously throws 1`] = ` 20 | }); 21 | - at eventHandler (../../packages/jest-circus/build/eventHandler.js:103:11) + at eventHandler (../../packages/jest-circus/build/eventHandler.js:104:11) at afterAll (__tests__/asyncDefinition.test.js:19:3)" `; diff --git a/packages/jest-changed-files/package.json b/packages/jest-changed-files/package.json index a0a5c5cd1e25..6dda0ea22cb1 100644 --- a/packages/jest-changed-files/package.json +++ b/packages/jest-changed-files/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "execa": "^5.0.0", + "jest-util": "workspace:^", "p-limit": "^3.1.0" }, "engines": { diff --git a/packages/jest-changed-files/src/index.ts b/packages/jest-changed-files/src/index.ts index df3cb0723c34..3577d49e05ee 100644 --- a/packages/jest-changed-files/src/index.ts +++ b/packages/jest-changed-files/src/index.ts @@ -7,6 +7,7 @@ */ import pLimit = require('p-limit'); +import {isNonNullable} from 'jest-util'; import git from './git'; import hg from './hg'; import sl from './sl'; @@ -16,10 +17,6 @@ type RootPromise = ReturnType<SCMAdapter['getRoot']>; export type {ChangedFiles, ChangedFilesPromise} from './types'; -function notEmpty<T>(value: T | null | undefined): value is T { - return value != null; -} - // This is an arbitrary number. The main goal is to prevent projects with // many roots (50+) from spawning too many processes at once. const mutex = pLimit(5); @@ -78,8 +75,8 @@ export const findRepos = async (roots: Array<string>): Promise<Repos> => { const slRepos = await Promise.all(roots.map(findSlRoot)); return { - git: new Set(gitRepos.filter(notEmpty)), - hg: new Set(hgRepos.filter(notEmpty)), - sl: new Set(slRepos.filter(notEmpty)), + git: new Set(gitRepos.filter(isNonNullable)), + hg: new Set(hgRepos.filter(isNonNullable)), + sl: new Set(slRepos.filter(isNonNullable)), }; }; diff --git a/packages/jest-changed-files/tsconfig.json b/packages/jest-changed-files/tsconfig.json index 12688a2879d6..aad1b761e910 100644 --- a/packages/jest-changed-files/tsconfig.json +++ b/packages/jest-changed-files/tsconfig.json @@ -4,5 +4,6 @@ "rootDir": "src", "outDir": "build" }, - "include": ["./src/**/*"] + "include": ["./src/**/*"], + "references": [{"path": "../jest-util"}] } diff --git a/packages/jest-circus/src/eventHandler.ts b/packages/jest-circus/src/eventHandler.ts index 0a437df1ed9a..4c401cada760 100644 --- a/packages/jest-circus/src/eventHandler.ts +++ b/packages/jest-circus/src/eventHandler.ts @@ -6,6 +6,7 @@ */ import type {Circus} from '@jest/types'; +import {invariant} from 'jest-util'; import { injectGlobalErrorHandlers, restoreGlobalErrorHandlers, @@ -15,7 +16,6 @@ import { addErrorToEachTestUnderDescribe, describeBlockHasTests, getTestDuration, - invariant, makeDescribe, makeTest, } from './utils'; diff --git a/packages/jest-circus/src/run.ts b/packages/jest-circus/src/run.ts index 02766579678f..eac6a20b06e6 100644 --- a/packages/jest-circus/src/run.ts +++ b/packages/jest-circus/src/run.ts @@ -9,6 +9,7 @@ import {AsyncLocalStorage} from 'async_hooks'; import pLimit = require('p-limit'); import {jestExpect} from '@jest/expect'; import type {Circus} from '@jest/types'; +import {invariant} from 'jest-util'; import shuffleArray, {RandomNumberGenerator, rngBuilder} from './shuffleArray'; import {dispatch, getState} from './state'; import {RETRY_TIMES} from './types'; @@ -17,7 +18,6 @@ import { getAllHooksForDescribe, getEachHooksForTest, getTestID, - invariant, makeRunResult, } from './utils'; diff --git a/packages/jest-circus/src/utils.ts b/packages/jest-circus/src/utils.ts index 9e1c8d74838b..fa45f4fbb744 100644 --- a/packages/jest-circus/src/utils.ts +++ b/packages/jest-circus/src/utils.ts @@ -17,6 +17,7 @@ import { ErrorWithStack, convertDescriptorToString, formatTime, + invariant, isPromise, } from 'jest-util'; import {format as prettyFormat} from 'pretty-format'; @@ -456,15 +457,6 @@ export const addErrorToEachTestUnderDescribe = ( } }; -export function invariant( - condition: unknown, - message?: string, -): asserts condition { - if (!condition) { - throw new Error(message); - } -} - type TestDescription = { ancestorTitles: Array<string>; fullName: string; diff --git a/packages/jest-console/src/BufferedConsole.ts b/packages/jest-console/src/BufferedConsole.ts index 526d51c38fdf..2ab7d73688ed 100644 --- a/packages/jest-console/src/BufferedConsole.ts +++ b/packages/jest-console/src/BufferedConsole.ts @@ -9,7 +9,7 @@ import {AssertionError, strict as assert} from 'assert'; import {Console} from 'console'; import {InspectOptions, format, formatWithOptions, inspect} from 'util'; import chalk = require('chalk'); -import {ErrorWithStack, formatTime} from 'jest-util'; +import {ErrorWithStack, formatTime, invariant} from 'jest-util'; import type { ConsoleBuffer, LogCounters, @@ -180,9 +180,3 @@ export default class BufferedConsole extends Console { return this._buffer.length ? this._buffer : undefined; } } - -function invariant(condition: boolean, message?: string): asserts condition { - if (!condition) { - throw new Error(message); - } -} diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index 2c53db5a41fc..77caa9a95c3f 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -38,7 +38,7 @@ import { buildSnapshotResolver, cleanup as cleanupSnapshots, } from 'jest-snapshot'; -import {ErrorWithStack, requireOrImportModule} from 'jest-util'; +import {ErrorWithStack, invariant, requireOrImportModule} from 'jest-util'; import type {TestWatcher} from 'jest-watcher'; import ReporterDispatcher from './ReporterDispatcher'; import {shouldRunInBand} from './testSchedulerHelper'; @@ -425,12 +425,6 @@ class TestScheduler { } } -function invariant(condition: unknown, message?: string): asserts condition { - if (!condition) { - throw new Error(message); - } -} - const createAggregatedResults = (numTotalTestSuites: number) => { const result = makeEmptyAggregatedTestResult(); result.numTotalTestSuites = numTotalTestSuites; diff --git a/packages/jest-core/src/lib/watchPluginsHelpers.ts b/packages/jest-core/src/lib/watchPluginsHelpers.ts index 08cf4cae06ad..0479f544beb4 100644 --- a/packages/jest-core/src/lib/watchPluginsHelpers.ts +++ b/packages/jest-core/src/lib/watchPluginsHelpers.ts @@ -6,6 +6,7 @@ */ import type {Config} from '@jest/types'; +import {isNonNullable} from 'jest-util'; import type {UsageData, WatchPlugin} from 'jest-watcher'; export const filterInteractivePlugins = ( @@ -27,10 +28,6 @@ export const filterInteractivePlugins = ( }); }; -function notEmpty<T>(value: T | null | undefined): value is T { - return value != null; -} - export const getSortedUsageRows = ( watchPlugins: Array<WatchPlugin>, globalConfig: Config.GlobalConfig, @@ -56,4 +53,4 @@ export const getSortedUsageRows = ( return 0; }) .map(p => p.getUsageInfo && p.getUsageInfo(globalConfig)) - .filter(notEmpty); + .filter(isNonNullable); diff --git a/packages/jest-haste-map/src/index.ts b/packages/jest-haste-map/src/index.ts index 5012d6ef1af5..37d7c0e2b171 100644 --- a/packages/jest-haste-map/src/index.ts +++ b/packages/jest-haste-map/src/index.ts @@ -13,7 +13,7 @@ import {deserialize, serialize} from 'v8'; import {Stats, readFileSync, writeFileSync} from 'graceful-fs'; import type {Config} from '@jest/types'; import {escapePathForRegex} from 'jest-regex-util'; -import {requireOrImportModule} from 'jest-util'; +import {invariant, requireOrImportModule} from 'jest-util'; import {JestWorkerFarm, Worker} from 'jest-worker'; import HasteFS from './HasteFS'; import HasteModuleMap from './ModuleMap'; @@ -131,12 +131,6 @@ const VCS_DIRECTORIES = ['.git', '.hg', '.sl'] .map(vcs => escapePathForRegex(path.sep + vcs + path.sep)) .join('|'); -function invariant(condition: unknown, message?: string): asserts condition { - if (!condition) { - throw new Error(message); - } -} - /** * HasteMap is a JavaScript implementation of Facebook's haste module system. * diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index d54ed63fb325..9b5647215101 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -53,7 +53,12 @@ import type {MockMetadata, ModuleMocker} from 'jest-mock'; import {escapePathForRegex} from 'jest-regex-util'; import Resolver, {ResolveModuleConfig} from 'jest-resolve'; import {EXTENSION as SnapshotExtension} from 'jest-snapshot'; -import {createDirectory, deepCyclicCopy} from 'jest-util'; +import { + createDirectory, + deepCyclicCopy, + invariant, + isNonNullable, +} from 'jest-util'; import { createOutsideJestVmPath, decodePossibleOutsideJestVmPath, @@ -1587,7 +1592,7 @@ export default class Runtime { module.path, // __dirname module.filename, // __filename lastArgs[0], - ...lastArgs.slice(1).filter(notEmpty), + ...lastArgs.slice(1).filter(isNonNullable), ); } catch (error: any) { this.handleExecutionError(error, module); @@ -2434,7 +2439,7 @@ export default class Runtime { '__filename', this._config.injectGlobals ? 'jest' : undefined, ...this._config.sandboxInjectedGlobals, - ].filter(notEmpty); + ].filter(isNonNullable); } private handleExecutionError(e: Error, module: Module): never { @@ -2546,16 +2551,6 @@ export default class Runtime { } } -function invariant(condition: unknown, message?: string): asserts condition { - if (!condition) { - throw new Error(message); - } -} - -function notEmpty<T>(value: T | null | undefined): value is T { - return value !== null && value !== undefined; -} - async function evaluateSyntheticModule(module: SyntheticModule) { await module.link(() => { throw new Error('This should never happen'); diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 6728407dfcb9..8ee6aa12d8f1 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -20,6 +20,7 @@ import type {Config} from '@jest/types'; import HasteMap from 'jest-haste-map'; import { createDirectory, + invariant, isPromise, requireOrImportModule, tryRealpath, @@ -1034,12 +1035,6 @@ const calcTransformRegExp = (config: Config.ProjectConfig) => { return transformRegexp; }; -function invariant(condition: unknown, message?: string): asserts condition { - if (condition == null || condition === false || condition === '') { - throw new Error(message); - } -} - function assertSyncTransformer( transformer: Transformer, name: string | undefined, diff --git a/packages/jest-util/src/index.ts b/packages/jest-util/src/index.ts index 1e73c92e0d18..531acfe4aa3a 100644 --- a/packages/jest-util/src/index.ts +++ b/packages/jest-util/src/index.ts @@ -28,3 +28,5 @@ export {default as pluralize} from './pluralize'; export {default as formatTime} from './formatTime'; export {default as tryRealpath} from './tryRealpath'; export {default as requireOrImportModule} from './requireOrImportModule'; +export {default as invariant} from './invariant'; +export {default as isNonNullable} from './isNonNullable'; diff --git a/packages/jest-util/src/invariant.ts b/packages/jest-util/src/invariant.ts new file mode 100644 index 000000000000..2e86440ae791 --- /dev/null +++ b/packages/jest-util/src/invariant.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export default function invariant( + condition: unknown, + message = '', +): asserts condition { + if (!condition) { + throw new Error(message); + } +} diff --git a/packages/jest-util/src/isNonNullable.ts b/packages/jest-util/src/isNonNullable.ts new file mode 100644 index 000000000000..34eddf095ef5 --- /dev/null +++ b/packages/jest-util/src/isNonNullable.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export default function isNonNullable<T>(value: T): value is NonNullable<T> { + return value != null; +} diff --git a/yarn.lock b/yarn.lock index 68ff4925f6ec..a83a4736f19b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12347,6 +12347,7 @@ __metadata: resolution: "jest-changed-files@workspace:packages/jest-changed-files" dependencies: execa: ^5.0.0 + jest-util: "workspace:^" p-limit: ^3.1.0 languageName: unknown linkType: soft