diff --git a/e2e/__tests__/__snapshots__/transform.test.ts.snap b/e2e/__tests__/__snapshots__/transform.test.ts.snap index 2a45dc91b63d..a34e43eb753a 100644 --- a/e2e/__tests__/__snapshots__/transform.test.ts.snap +++ b/e2e/__tests__/__snapshots__/transform.test.ts.snap @@ -6,7 +6,7 @@ exports[`babel-jest ignored tells user to match ignored files 1`] = ` babel-jest: Babel ignores __tests__/ignoredFile.test.js - make sure to include the file in Jest's transformIgnorePatterns as well. - at assertLoadedBabelConfig (../../../packages/babel-jest/build/index.js:137:11)" + at assertLoadedBabelConfig (../../../packages/babel-jest/build/index.js:148:11)" `; exports[`babel-jest instruments only specific files and collects coverage 1`] = ` diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index 94955b34f30d..78c61efd19be 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -29,12 +29,13 @@ "slash": "^3.0.0" }, "devDependencies": { + "@babel-8/core": "npm:@babel/core@8.0.0-beta.1", "@babel/core": "^7.27.4", "@jest/test-utils": "workspace:*", "@types/graceful-fs": "^4.1.9" }, "peerDependencies": { - "@babel/core": "^7.11.0" + "@babel/core": "^7.11.0 || ^8.0.0-0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" diff --git a/packages/babel-jest/src/__tests__/getCacheKey.test.ts b/packages/babel-jest/src/__tests__/getCacheKey.test.ts index eb9b2da1107b..ced41a7e479a 100644 --- a/packages/babel-jest/src/__tests__/getCacheKey.test.ts +++ b/packages/babel-jest/src/__tests__/getCacheKey.test.ts @@ -9,6 +9,16 @@ import type {TransformOptions as BabelTransformOptions} from '@babel/core'; import type {SyncTransformer, TransformOptions} from '@jest/transform'; import babelJest from '../index'; +// We need to use the Node.js implementation of `require` to load Babel 8 +// packages, instead of our sandboxed implementation, because Babel 8 is +// written in ESM and we don't support require(esm) yet. +import Module from 'node:module'; +import {pathToFileURL} from 'node:url'; +const createOriginalNodeRequire = Object.getPrototypeOf(Module).createRequire; +const originalNodeRequire = createOriginalNodeRequire( + pathToFileURL(__filename), +); + const {getCacheKey} = babelJest.createTransformer() as SyncTransformer; @@ -33,173 +43,207 @@ afterEach(() => { } }); -describe('getCacheKey', () => { - const sourceText = 'mock source'; - const sourcePath = 'mock-source-path.js'; - - const transformOptions = { - config: {rootDir: 'mock-root-dir'}, - configString: 'mock-config-string', - instrument: true, - } as TransformOptions; - - const oldCacheKey = getCacheKey!(sourceText, sourcePath, transformOptions); +describe('babel 7', () => { + defineTests({babel: require('@babel/core')}); +}); - test('returns cache key hash', () => { - expect(oldCacheKey).toHaveLength(32); +if (Number.parseInt(process.versions.node, 10) >= 20) { + describe('babel 8', () => { + defineTests({ + babel: originalNodeRequire('@babel-8/core'), + }); }); - - test('if `THIS_FILE` value is changing', async () => { - jest.doMock('graceful-fs', () => ({ - readFileSync: () => 'new this file', - })); - - const {createTransformer} = - require('../index') as typeof import('../index'); - - const newCacheKey = (await createTransformer()).getCacheKey!( - sourceText, - sourcePath, - transformOptions, - ); - - expect(oldCacheKey).not.toEqual(newCacheKey); +} else { + // eslint-disable-next-line jest/no-identical-title + describe.skip('babel 8', () => { + defineTests({babel: null as unknown as typeof import('@babel-8/core')}); }); +} - test('if `babelOptions.options` value is changing', async () => { - jest.doMock('../loadBabelConfig', () => { - const babel = require('@babel/core') as typeof import('@babel/core'); +function defineTests({babel}: {babel: typeof import('@babel-8/core')}) { + describe('getCacheKey', () => { + const sourceText = 'mock source'; + const sourcePath = 'mock-source-path.js'; - return { - loadPartialConfig: (options: BabelTransformOptions) => ({ - ...babel.loadPartialConfig(options), - options: 'new-options', - }), - }; - }); - - const {createTransformer} = - require('../index') as typeof import('../index'); + const transformOptions = { + config: {rootDir: 'mock-root-dir'}, + configString: 'mock-config-string', + instrument: true, + } as TransformOptions; - const newCacheKey = (await createTransformer()).getCacheKey!( - sourceText, - sourcePath, - transformOptions, - ); - - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + const oldCacheKey = getCacheKey!(sourceText, sourcePath, transformOptions); - test('if `sourceText` value is changing', () => { - const newCacheKey = getCacheKey!( - 'new source text', - sourcePath, - transformOptions, - ); + test('returns cache key hash', () => { + expect(oldCacheKey).toHaveLength(32); + }); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + test('if `THIS_FILE` value is changing', async () => { + jest.doMock('graceful-fs', () => ({ + readFileSync: () => 'new this file', + })); - test('if `sourcePath` value is changing', () => { - const newCacheKey = getCacheKey!( - sourceText, - 'new-source-path.js', - transformOptions, - ); + const {createTransformer} = + require('../index') as typeof import('../index'); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + const newCacheKey = (await createTransformer()).getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); - test('if `configString` value is changing', () => { - const newCacheKey = getCacheKey!(sourceText, sourcePath, { - ...transformOptions, - configString: 'new-config-string', + expect(oldCacheKey).not.toEqual(newCacheKey); }); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + test('if `babelOptions.options` value is changing', async () => { + jest.doMock('../babel', () => { + return { + ...babel, + loadPartialConfigSync: ( + options: Parameters[0], + ) => ({ + ...babel.loadPartialConfigSync(options), + options: 'new-options', + }), + }; + }); + + const {createTransformer} = + require('../index') as typeof import('../index'); + + const newCacheKey = (await createTransformer()).getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); + + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - test('if `babelOptions.config` value is changing', async () => { - jest.doMock('../loadBabelConfig', () => { - const babel = require('@babel/core') as typeof import('@babel/core'); + test('if `sourceText` value is changing', () => { + const newCacheKey = getCacheKey!( + 'new source text', + sourcePath, + transformOptions, + ); - return { - loadPartialConfig: (options: BabelTransformOptions) => ({ - ...babel.loadPartialConfig(options), - config: 'new-config', - }), - }; + expect(oldCacheKey).not.toEqual(newCacheKey); }); - const {createTransformer} = - require('../index') as typeof import('../index'); - - const newCacheKey = (await createTransformer()).getCacheKey!( - sourceText, - sourcePath, - transformOptions, - ); + test('if `sourcePath` value is changing', () => { + const newCacheKey = getCacheKey!( + sourceText, + 'new-source-path.js', + transformOptions, + ); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - test('if `babelOptions.babelrc` value is changing', async () => { - jest.doMock('../loadBabelConfig', () => { - const babel = require('@babel/core') as typeof import('@babel/core'); + test('if `configString` value is changing', () => { + const newCacheKey = getCacheKey!(sourceText, sourcePath, { + ...transformOptions, + configString: 'new-config-string', + }); - return { - loadPartialConfig: (options: BabelTransformOptions) => ({ - ...babel.loadPartialConfig(options), - babelrc: 'new-babelrc', - }), - }; + expect(oldCacheKey).not.toEqual(newCacheKey); }); - const {createTransformer} = - require('../index') as typeof import('../index'); + test('if `babelOptions.config` value is changing', async () => { + jest.doMock('../babel', () => { + return { + ...babel, + loadPartialConfigSync: ( + options: Parameters[0], + ) => ({ + ...babel.loadPartialConfigSync(options), + config: 'new-config', + }), + }; + }); + + const {createTransformer} = + require('../index') as typeof import('../index'); + + const newCacheKey = (await createTransformer()).getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); + + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - const newCacheKey = (await createTransformer()).getCacheKey!( - sourceText, - sourcePath, - transformOptions, - ); + test('if `babelOptions.babelrc` value is changing', async () => { + jest.doMock('../babel', () => { + return { + ...babel, + loadPartialConfig: ( + options: Parameters[0], + ) => ({ + ...babel.loadPartialConfig(options), + babelrc: 'new-babelrc', + }), + }; + }); + + const {createTransformer} = + require('../index') as typeof import('../index'); + + const newCacheKey = (await createTransformer()).getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); + + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + test('if `instrument` value is changing', () => { + const newCacheKey = getCacheKey!(sourceText, sourcePath, { + ...transformOptions, + instrument: false, + }); - test('if `instrument` value is changing', () => { - const newCacheKey = getCacheKey!(sourceText, sourcePath, { - ...transformOptions, - instrument: false, + expect(oldCacheKey).not.toEqual(newCacheKey); }); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); - - test('if `process.env.NODE_ENV` value is changing', () => { - process.env.NODE_ENV = 'NEW_NODE_ENV'; + test('if `process.env.NODE_ENV` value is changing', () => { + process.env.NODE_ENV = 'NEW_NODE_ENV'; - const newCacheKey = getCacheKey!(sourceText, sourcePath, transformOptions); + const newCacheKey = getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - test('if `process.env.BABEL_ENV` value is changing', () => { - process.env.BABEL_ENV = 'NEW_BABEL_ENV'; + test('if `process.env.BABEL_ENV` value is changing', () => { + process.env.BABEL_ENV = 'NEW_BABEL_ENV'; - const newCacheKey = getCacheKey!(sourceText, sourcePath, transformOptions); + const newCacheKey = getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); - expect(oldCacheKey).not.toEqual(newCacheKey); - }); + expect(oldCacheKey).not.toEqual(newCacheKey); + }); - test('if node version is changing', () => { - // @ts-expect-error: Testing purpose - delete process.version; - // @ts-expect-error: Testing purpose - process.version = 'new-node-version'; + test('if node version is changing', () => { + // @ts-expect-error: Testing purpose + delete process.version; + // @ts-expect-error: Testing purpose + process.version = 'new-node-version'; - const newCacheKey = getCacheKey!(sourceText, sourcePath, transformOptions); + const newCacheKey = getCacheKey!( + sourceText, + sourcePath, + transformOptions, + ); - expect(oldCacheKey).not.toEqual(newCacheKey); + expect(oldCacheKey).not.toEqual(newCacheKey); + }); }); -}); +} diff --git a/packages/babel-jest/src/__tests__/index.ts b/packages/babel-jest/src/__tests__/index.ts index b18844220fc7..639bda3e2675 100644 --- a/packages/babel-jest/src/__tests__/index.ts +++ b/packages/babel-jest/src/__tests__/index.ts @@ -12,20 +12,35 @@ import type { import {makeProjectConfig} from '@jest/test-utils'; import type {SyncTransformer, TransformOptions} from '@jest/transform'; import babelJest, {createTransformer} from '../index'; -import {loadPartialConfig} from '../loadBabelConfig'; - -jest.mock('../loadBabelConfig', () => { - const actual = - jest.requireActual('@babel/core'); - - return { - loadPartialConfig: jest.fn((...args) => - actual.loadPartialConfig(...args), - ), - loadPartialConfigAsync: jest.fn( - (...args) => actual.loadPartialConfigAsync(...args), - ), - }; + +// We need to use the Node.js implementation of `require` to load Babel 8 +// packages, instead of our sandboxed implementation, because Babel 8 is +// written in ESM and we don't support require(esm) yet. +import Module from 'node:module'; +import {pathToFileURL} from 'node:url'; +const createOriginalNodeRequire = Object.getPrototypeOf(Module).createRequire; +const originalNodeRequire = createOriginalNodeRequire( + pathToFileURL(__filename), +); + +type BabelCore = typeof import('@babel-8/core'); + +// We need to use `var` so that it's hoisted and we can set it in `jest.mock`. +// eslint-disable-next-line no-var +var mockedBabel!: { + transformSync: jest.Mock; + transformAsync: jest.Mock; + loadPartialConfigSync: jest.Mock; + loadPartialConfigAsync: jest.Mock; +}; + +jest.mock('../babel', () => { + return (mockedBabel = { + loadPartialConfigAsync: jest.fn(), + loadPartialConfigSync: jest.fn(), + transformAsync: jest.fn(), + transformSync: jest.fn(), + }); }); const defaultBabelJestTransformer = @@ -44,159 +59,188 @@ const customMultiply = (obj, mul) => { customMultiply({a: 32, dummy: "test"}, 2); `; -beforeEach(() => { - jest.clearAllMocks(); +describe('babel 7', () => { + defineTests({babel: require('@babel/core')}); }); -test('Returns source string with inline maps when no transformOptions is passed', () => { - const result = defaultBabelJestTransformer.process( - sourceString, - 'dummy_path.js', - { - cacheFS: new Map(), - config: makeProjectConfig(), - configString: JSON.stringify(makeProjectConfig()), - instrument: false, - transformerConfig: {}, - } as TransformOptions, - ); - - expect(typeof result).toBe('object'); - expect(result.code).toBeDefined(); - expect(result.map).toBeDefined(); - expect(result.code).toMatch('//# sourceMappingURL'); - expect(result.code).toMatch('customMultiply'); - expect((result as BabelFileResult).map!.sources).toEqual(['dummy_path.js']); - expect( - JSON.stringify((result as BabelFileResult).map!.sourcesContent), - ).toMatch('customMultiply'); -}); +if (Number.parseInt(process.versions.node, 10) >= 20) { + describe('babel 8', () => { + defineTests({ + babel: originalNodeRequire('@babel-8/core'), + }); + }); +} else { + // eslint-disable-next-line jest/no-identical-title + describe('babel 8', () => { + defineTests({babel: null as unknown as typeof import('@babel-8/core')}); + }); +} -test('Returns source string with inline maps when no transformOptions is passed async', async () => { - const result = await defaultBabelJestTransformer.processAsync!( - sourceString, - 'dummy_path.js', - { - cacheFS: new Map(), - config: makeProjectConfig(), - configString: JSON.stringify(makeProjectConfig()), - instrument: false, - transformerConfig: {}, - } as TransformOptions, - ); +function defineTests({babel}: {babel: BabelCore}) { + beforeEach(() => { + jest.clearAllMocks(); + + mockedBabel.transformSync.mockImplementation(babel.transformSync); + mockedBabel.transformAsync.mockImplementation(babel.transformAsync); + mockedBabel.loadPartialConfigSync.mockImplementation( + babel.loadPartialConfigSync, + ); + mockedBabel.loadPartialConfigAsync.mockImplementation( + babel.loadPartialConfigAsync, + ); + }); + test('Returns source string with inline maps when no transformOptions is passed', () => { + const result = defaultBabelJestTransformer.process( + sourceString, + 'dummy_path.js', + { + cacheFS: new Map(), + config: makeProjectConfig(), + configString: JSON.stringify(makeProjectConfig()), + instrument: false, + transformerConfig: {}, + } as TransformOptions, + ); - expect(typeof result).toBe('object'); - expect(result.code).toBeDefined(); - expect(result.map).toBeDefined(); - expect(result.code).toMatch('//# sourceMappingURL'); - expect(result.code).toMatch('customMultiply'); + expect(typeof result).toBe('object'); + expect(result.code).toBeDefined(); + expect(result.map).toBeDefined(); + expect(result.code).toMatch('//# sourceMappingURL'); + expect(result.code).toMatch('customMultiply'); + expect((result as BabelFileResult).map!.sources).toEqual(['dummy_path.js']); + expect( + JSON.stringify((result as BabelFileResult).map!.sourcesContent), + ).toMatch('customMultiply'); + }); - const {map} = result; + test('Returns source string with inline maps when no transformOptions is passed async', async () => { + const result = await defaultBabelJestTransformer.processAsync!( + sourceString, + 'dummy_path.js', + { + cacheFS: new Map(), + config: makeProjectConfig(), + configString: JSON.stringify(makeProjectConfig()), + instrument: false, + transformerConfig: {}, + } as TransformOptions, + ); - expect(map).toBeTruthy(); - expect(typeof map).not.toBe('string'); + expect(typeof result).toBe('object'); + expect(result.code).toBeDefined(); + expect(result.map).toBeDefined(); + expect(result.code).toMatch('//# sourceMappingURL'); + expect(result.code).toMatch('customMultiply'); - if (map == null || typeof map === 'string') { - throw new Error('dead code'); - } + const {map} = result; - expect(map.sources).toEqual(['dummy_path.js']); - expect(JSON.stringify(map.sourcesContent)).toMatch('customMultiply'); -}); + expect(map).toBeTruthy(); + expect(typeof map).not.toBe('string'); -describe('caller option correctly merges from defaults and options', () => { - test.each([ - [ - {supportsDynamicImport: true, supportsStaticESM: true}, - {supportsDynamicImport: true, supportsStaticESM: true}, - ], - [ - {supportsDynamicImport: false, supportsStaticESM: false}, - {supportsDynamicImport: false, supportsStaticESM: false}, - ], - [ - {supportsStaticESM: false}, - {supportsDynamicImport: false, supportsStaticESM: false}, - ], - [ - {supportsDynamicImport: true}, - {supportsDynamicImport: true, supportsStaticESM: false}, - ], - ])('%j -> %j', (input, output) => { - defaultBabelJestTransformer.process(sourceString, 'dummy_path.js', { + if (map == null || typeof map === 'string') { + throw new Error('dead code'); + } + + expect(map.sources).toEqual(['dummy_path.js']); + expect(JSON.stringify(map.sourcesContent)).toMatch('customMultiply'); + }); + + describe('caller option correctly merges from defaults and options', () => { + test.each([ + [ + {supportsDynamicImport: true, supportsStaticESM: true}, + {supportsDynamicImport: true, supportsStaticESM: true}, + ], + [ + {supportsDynamicImport: false, supportsStaticESM: false}, + {supportsDynamicImport: false, supportsStaticESM: false}, + ], + [ + {supportsStaticESM: false}, + {supportsDynamicImport: false, supportsStaticESM: false}, + ], + [ + {supportsDynamicImport: true}, + {supportsDynamicImport: true, supportsStaticESM: false}, + ], + ])('%j -> %j', (input, output) => { + defaultBabelJestTransformer.process(sourceString, 'dummy_path.js', { + cacheFS: new Map(), + config: makeProjectConfig(), + configString: JSON.stringify(makeProjectConfig()), + instrument: false, + transformerConfig: {}, + ...input, + } as TransformOptions); + + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledTimes(1); + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledWith( + expect.objectContaining({ + caller: { + name: 'babel-jest', + ...output, + supportsExportNamespaceFrom: false, + supportsTopLevelAwait: false, + }, + }), + ); + }); + }); + + test('can pass null to createTransformer', async () => { + const transformer = await createTransformer(); + transformer.process(sourceString, 'dummy_path.js', { cacheFS: new Map(), config: makeProjectConfig(), configString: JSON.stringify(makeProjectConfig()), instrument: false, transformerConfig: {}, - ...input, } as TransformOptions); - expect(loadPartialConfig).toHaveBeenCalledTimes(1); - expect(loadPartialConfig).toHaveBeenCalledWith( + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledTimes(1); + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledWith( expect.objectContaining({ caller: { name: 'babel-jest', - ...output, + supportsDynamicImport: false, supportsExportNamespaceFrom: false, + supportsStaticESM: false, supportsTopLevelAwait: false, }, }), ); }); -}); -test('can pass null to createTransformer', async () => { - const transformer = await createTransformer(); - transformer.process(sourceString, 'dummy_path.js', { - cacheFS: new Map(), - config: makeProjectConfig(), - configString: JSON.stringify(makeProjectConfig()), - instrument: false, - transformerConfig: {}, - } as TransformOptions); - - expect(loadPartialConfig).toHaveBeenCalledTimes(1); - expect(loadPartialConfig).toHaveBeenCalledWith( - expect.objectContaining({ - caller: { - name: 'babel-jest', - supportsDynamicImport: false, - supportsExportNamespaceFrom: false, - supportsStaticESM: false, - supportsTopLevelAwait: false, - }, - }), - ); -}); + test('include babel-preset-jest by default', () => { + defaultBabelJestTransformer.process(sourceString, 'dummy_path.js', { + cacheFS: new Map(), + config: makeProjectConfig(), + configString: JSON.stringify(makeProjectConfig()), + instrument: false, + transformerConfig: {}, + } as TransformOptions); -test('include babel-preset-jest by default', () => { - defaultBabelJestTransformer.process(sourceString, 'dummy_path.js', { - cacheFS: new Map(), - config: makeProjectConfig(), - configString: JSON.stringify(makeProjectConfig()), - instrument: false, - transformerConfig: {}, - } as TransformOptions); - - expect(loadPartialConfig).toHaveBeenCalledTimes(1); - expect(loadPartialConfig).toHaveBeenCalledWith( - expect.objectContaining({presets: [require.resolve('babel-preset-jest')]}), - ); -}); + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledTimes(1); + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledWith( + expect.objectContaining({ + presets: [require.resolve('babel-preset-jest')], + }), + ); + }); -test('can opting out of babel-preset-jest by passing excludeJestPreset: true', async () => { - const transformer = await createTransformer({excludeJestPreset: true}); - transformer.process(sourceString, 'dummy_path.js', { - cacheFS: new Map(), - config: makeProjectConfig(), - configString: JSON.stringify(makeProjectConfig()), - instrument: false, - transformerConfig: {}, - } as TransformOptions); - - expect(loadPartialConfig).toHaveBeenCalledTimes(1); - expect(loadPartialConfig).toHaveBeenCalledWith( - expect.objectContaining({presets: []}), - ); -}); + test('can opting out of babel-preset-jest by passing excludeJestPreset: true', async () => { + const transformer = await createTransformer({excludeJestPreset: true}); + transformer.process(sourceString, 'dummy_path.js', { + cacheFS: new Map(), + config: makeProjectConfig(), + configString: JSON.stringify(makeProjectConfig()), + instrument: false, + transformerConfig: {}, + } as TransformOptions); + + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledTimes(1); + expect(mockedBabel.loadPartialConfigSync).toHaveBeenCalledWith( + expect.objectContaining({presets: []}), + ); + }); +} diff --git a/packages/babel-jest/src/babel.ts b/packages/babel-jest/src/babel.ts new file mode 100644 index 000000000000..bf42d7231d39 --- /dev/null +++ b/packages/babel-jest/src/babel.ts @@ -0,0 +1,24 @@ +/** + * 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. + */ + +// this is a separate file so it can be mocked in tests +export { + loadPartialConfigAsync, + transformSync, + transformAsync, +} from '@babel/core'; + +import { + loadPartialConfig, + // @ts-expect-error -- Wrong @types/babel__core definition + loadPartialConfigSync, +} from '@babel/core'; + +// Old babel 7 versions didn't have loadPartialConfigSync +const _loadPartialConfigSync: typeof loadPartialConfig = + loadPartialConfigSync ?? loadPartialConfig; +export {_loadPartialConfigSync as loadPartialConfigSync}; diff --git a/packages/babel-jest/src/index.ts b/packages/babel-jest/src/index.ts index 71b19dc7eeac..e83a6e03815f 100644 --- a/packages/babel-jest/src/index.ts +++ b/packages/babel-jest/src/index.ts @@ -7,11 +7,9 @@ import {createHash} from 'crypto'; import * as path from 'path'; -import { - type TransformOptions as BabelTransformOptions, - type PartialConfig, - transformSync as babelTransform, - transformAsync as babelTransformAsync, +import type { + TransformOptions as BabelTransformOptions, + PartialConfig, } from '@babel/core'; import chalk from 'chalk'; import * as fs from 'graceful-fs'; @@ -21,7 +19,12 @@ import type { SyncTransformer, TransformerCreator, } from '@jest/transform'; -import {loadPartialConfig, loadPartialConfigAsync} from './loadBabelConfig'; +import { + transformSync as babelTransform, + transformAsync as babelTransformAsync, + loadPartialConfigAsync, + loadPartialConfigSync, +} from './babel'; interface TransformerConfig extends BabelTransformOptions { excludeJestPreset?: boolean; @@ -112,7 +115,7 @@ function loadBabelConfig( filename: string, transformOptions: BabelTransformOptions, ): PartialConfig { - const babelConfig = loadPartialConfig(transformOptions); + const babelConfig = loadPartialConfigSync(transformOptions); assertLoadedBabelConfig(babelConfig, cwd, filename); diff --git a/packages/babel-jest/src/loadBabelConfig.ts b/packages/babel-jest/src/loadBabelConfig.ts deleted file mode 100644 index 0c53df81a24b..000000000000 --- a/packages/babel-jest/src/loadBabelConfig.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * 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. - */ - -// this is a separate file so it can be mocked in tests -export {loadPartialConfig, loadPartialConfigAsync} from '@babel/core'; diff --git a/packages/babel-plugin-jest-hoist/package.json b/packages/babel-plugin-jest-hoist/package.json index 4696f7892fae..5c3bfc839972 100644 --- a/packages/babel-plugin-jest-hoist/package.json +++ b/packages/babel-plugin-jest-hoist/package.json @@ -22,14 +22,16 @@ "./package.json": "./package.json" }, "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", "@types/babel__core": "^7.20.5" }, "devDependencies": { + "@babel-8/core": "npm:@babel/core@8.0.0-beta.1", + "@babel-8/preset-react": "npm:@babel/preset-react@8.0.0-beta.1", + "@babel-8/preset-typescript": "npm:@babel/preset-typescript@8.0.0-beta.1", "@babel/core": "^7.27.4", "@babel/preset-react": "^7.27.1", "@babel/preset-typescript": "^7.27.1", + "@babel/types": "^7.27.3", "@prettier/sync": "^0.5.5", "@types/babel__template": "^7.4.4", "@types/babel__traverse": "^7.20.7", diff --git a/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap b/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap index 2f15308e94f8..df0656ba7f69 100644 --- a/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap +++ b/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`babel-plugin-jest-hoist 1. automatic react runtime: 1. automatic react runtime 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 1. automatic react runtime: 1. automatic react runtime 1`] = ` jest.mock('./App', () => () =>
Hello world
); @@ -35,7 +35,7 @@ function _getJestObj() { `; -exports[`babel-plugin-jest-hoist 2. top level mocking: 2. top level mocking 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 2. top level mocking: 2. top level mocking 1`] = ` require('x'); @@ -56,7 +56,7 @@ require('x'); `; -exports[`babel-plugin-jest-hoist 3. within a block: 3. within a block 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 3. within a block: 3. within a block 1`] = ` beforeEach(() => { require('x'); @@ -78,7 +78,7 @@ beforeEach(() => { `; -exports[`babel-plugin-jest-hoist 4. within a block with no siblings: 4. within a block with no siblings 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 4. within a block with no siblings: 4. within a block with no siblings 1`] = ` beforeEach(() => { jest.mock('someNode'); @@ -98,7 +98,7 @@ beforeEach(() => { `; -exports[`babel-plugin-jest-hoist 5. required \`jest\` within \`jest\`: 5. required \`jest\` within \`jest\` 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 5. required \`jest\` within \`jest\`: 5. required \`jest\` within \`jest\` 1`] = ` const {jest} = require('@jest/globals'); @@ -116,7 +116,7 @@ jest.mock('some-module', () => { `; -exports[`babel-plugin-jest-hoist 6. imported jest.mock within jest.mock: 6. imported jest.mock within jest.mock 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 6. imported jest.mock within jest.mock: 6. imported jest.mock within jest.mock 1`] = ` import {jest} from '@jest/globals'; @@ -139,7 +139,7 @@ import {jest} from '@jest/globals'; `; -exports[`babel-plugin-jest-hoist 7. global jest.mock within jest.mock: 7. global jest.mock within jest.mock 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 7. global jest.mock within jest.mock: 7. global jest.mock within jest.mock 1`] = ` jest.mock('some-module', () => { jest.mock('some-module'); @@ -159,7 +159,7 @@ function _getJestObj() { `; -exports[`babel-plugin-jest-hoist 8. imported jest.requireActual in jest.mock: 8. imported jest.requireActual in jest.mock 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 8. imported jest.requireActual in jest.mock: 8. imported jest.requireActual in jest.mock 1`] = ` import {jest} from '@jest/globals'; @@ -185,7 +185,7 @@ jest.requireActual('some-module'); `; -exports[`babel-plugin-jest-hoist 9. global jest.requireActual in jest.mock: 9. global jest.requireActual in jest.mock 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 9. global jest.requireActual in jest.mock: 9. global jest.requireActual in jest.mock 1`] = ` jest.mock('some-module', () => { jest.requireActual('some-module'); @@ -208,7 +208,7 @@ jest.requireActual('some-module'); `; -exports[`babel-plugin-jest-hoist 10. TS typeof usage in jest.mock: 10. TS typeof usage in jest.mock 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 10. TS typeof usage in jest.mock: 10. TS typeof usage in jest.mock 1`] = ` jest.mock('some-module', () => { const actual = jest.requireActual('some-module'); @@ -231,7 +231,7 @@ function _getJestObj() { `; -exports[`babel-plugin-jest-hoist 11. jest.spyOn call on the imported module: 11. jest.spyOn call on the imported module 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 11. jest.spyOn call on the imported module: 11. jest.spyOn call on the imported module 1`] = ` jest.mock('some-module', () => { const module = jest.requireActual('some-module'); @@ -255,7 +255,294 @@ function _getJestObj() { `; -exports[`babel-plugin-jest-hoist 12. jest.spyOn call in class constructor: 12. jest.spyOn call in class constructor 1`] = ` +exports[`babel 7 babel-plugin-jest-hoist 12. jest.spyOn call in class constructor: 12. jest.spyOn call in class constructor 1`] = ` + +jest.mock('some-module', () => { + const Actual = jest.requireActual('some-module'); + return class Mocked extends Actual { + constructor() { + super(); + jest.spyOn(this, 'add'); + } + }; +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + const Actual = jest.requireActual('some-module'); + return class Mocked extends Actual { + constructor() { + super(); + _getJestObj().spyOn(this, 'add'); + } + }; +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} + +`; + +exports[`babel 8 babel-plugin-jest-hoist 13. automatic react runtime: 13. automatic react runtime 1`] = ` + +jest.mock('./App', () => () =>
Hello world
); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +var _jsxFileName = '/root/project/src/file.js'; +_getJestObj().mock( + './App', + () => () => + /*#__PURE__*/ _jsxDEV( + 'div', + { + children: 'Hello world', + }, + void 0, + false, + { + fileName: _jsxFileName, + lineNumber: 1, + columnNumber: 32, + }, + this, + ), +); +import {jsxDEV as _jsxDEV} from 'react/jsx-dev-runtime'; +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} + +`; + +exports[`babel 8 babel-plugin-jest-hoist 14. top level mocking: 14. top level mocking 1`] = ` + +require('x'); + +jest.enableAutomock(); +jest.disableAutomock(); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().enableAutomock(); +_getJestObj().disableAutomock(); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +require('x'); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 15. within a block: 15. within a block 1`] = ` + +beforeEach(() => { + require('x'); + jest.mock('someNode'); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +beforeEach(() => { + _getJestObj().mock('someNode'); + require('x'); +}); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 16. within a block with no siblings: 16. within a block with no siblings 1`] = ` + +beforeEach(() => { + jest.mock('someNode'); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +beforeEach(() => { + _getJestObj().mock('someNode'); +}); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 17. required \`jest\` within \`jest\`: 17. required \`jest\` within \`jest\` 1`] = ` + +const {jest} = require('@jest/globals'); + +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +const {jest} = require('@jest/globals'); +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 18. imported jest.mock within jest.mock: 18. imported jest.mock within jest.mock 1`] = ` + +import {jest} from '@jest/globals'; + +jest.mock('some-module', () => { + jest.mock('some-module'); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().mock('some-module'); +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +import {jest} from '@jest/globals'; + +`; + +exports[`babel 8 babel-plugin-jest-hoist 19. global jest.mock within jest.mock: 19. global jest.mock within jest.mock 1`] = ` + +jest.mock('some-module', () => { + jest.mock('some-module'); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().mock('some-module'); +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} + +`; + +exports[`babel 8 babel-plugin-jest-hoist 20. imported jest.requireActual in jest.mock: 20. imported jest.requireActual in jest.mock 1`] = ` + +import {jest} from '@jest/globals'; + +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + +jest.requireActual('some-module'); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().requireActual('some-module'); +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +import {jest} from '@jest/globals'; +jest.requireActual('some-module'); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 21. global jest.requireActual in jest.mock: 21. global jest.requireActual in jest.mock 1`] = ` + +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + +jest.requireActual('some-module'); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().requireActual('some-module'); +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} +jest.requireActual('some-module'); + +`; + +exports[`babel 8 babel-plugin-jest-hoist 22. TS typeof usage in jest.mock: 22. TS typeof usage in jest.mock 1`] = ` + +jest.mock('some-module', () => { + const actual = jest.requireActual('some-module'); + + return jest.fn(); +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + const actual = jest.requireActual('some-module'); + return jest.fn(); +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} + +`; + +exports[`babel 8 babel-plugin-jest-hoist 23. jest.spyOn call on the imported module: 23. jest.spyOn call on the imported module 1`] = ` + +jest.mock('some-module', () => { + const module = jest.requireActual('some-module'); + jest.spyOn(module, 'add'); + return module; +}); + + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + const module = jest.requireActual('some-module'); + _getJestObj().spyOn(module, 'add'); + return module; +}); +function _getJestObj() { + const {jest} = require('@jest/globals'); + _getJestObj = () => jest; + return jest; +} + +`; + +exports[`babel 8 babel-plugin-jest-hoist 24. jest.spyOn call in class constructor: 24. jest.spyOn call in class constructor 1`] = ` jest.mock('some-module', () => { const Actual = jest.requireActual('some-module'); diff --git a/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts b/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts index 642fbd31f885..7a26964a7e8f 100644 --- a/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts +++ b/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts @@ -12,6 +12,16 @@ import pluginTester from 'babel-plugin-tester'; import type {Options} from 'prettier'; import babelPluginJestHoist from '..'; +// We need to use the Node.js implementation of `require` to load Babel 8 +// packages, instead of our sandboxed implementation, because Babel 8 is +// written in ESM and we don't support require(esm) yet. +import Module from 'node:module'; +import {pathToFileURL} from 'node:url'; +const createOriginalNodeRequire = Object.getPrototypeOf(Module).createRequire; +const originalNodeRequire = createOriginalNodeRequire( + pathToFileURL(__filename), +); + const prettierOptions: Options = { ...resolveConfig(__filename), filepath: __filename, @@ -20,165 +30,198 @@ const prettierOptions: Options = { const formatResult = (code: string) => formatCode(code, prettierOptions); -pluginTester({ - plugin: babelPluginJestHoist, - pluginName: 'babel-plugin-jest-hoist', - tests: { - /* eslint-disable sort-keys */ - 'automatic react runtime': { - babelOptions: { - babelrc: false, - configFile: false, - filename: path.resolve(__dirname, '../file.js'), - presets: [ - [ - require.resolve('@babel/preset-react'), - {development: true, runtime: 'automatic'}, - ], - ], +describe('babel 7', () => { + defineTests({ + babel: require('@babel/core'), + presetReact: require('@babel/preset-react').default, + presetTypescript: require('@babel/preset-typescript').default, + }); +}); + +if (Number.parseInt(process.versions.node, 10) >= 20) { + describe('babel 8', () => { + defineTests({ + babel: originalNodeRequire('@babel-8/core'), + presetReact: originalNodeRequire('@babel-8/preset-react'), + presetTypescript: originalNodeRequire('@babel-8/preset-typescript'), + }); + }); +} else { + // eslint-disable-next-line jest/no-identical-title + describe.skip('babel 8', () => { + defineTests({ + babel: null as any, + presetReact: null, + presetTypescript: null, + }); + }); +} + +function defineTests({ + babel, + presetReact, + presetTypescript, +}: { + babel: typeof import('@babel/core'); + presetReact: any; + presetTypescript: any; +}) { + pluginTester({ + babel, + plugin: babelPluginJestHoist, + pluginName: 'babel-plugin-jest-hoist', + tests: { + /* eslint-disable sort-keys */ + 'automatic react runtime': { + babelOptions: { + babelrc: false, + configFile: false, + filename: path.resolve(__dirname, '../file.js'), + presets: [[presetReact, {development: true, runtime: 'automatic'}]], + }, + code: formatResult(` + jest.mock('./App', () => () =>
Hello world
); + `), + formatResult(code) { + // replace the filename with something that will be the same across OSes and machine + const codeWithoutSystemPath = code.replace( + /var _jsxFileName = ".*";/, + 'var _jsxFileName = "/root/project/src/file.js";', + ); + + return formatResult(codeWithoutSystemPath); + }, + snapshot: true, }, - code: formatResult(` - jest.mock('./App', () => () =>
Hello world
); - `), - formatResult(code) { - // replace the filename with something that will be the same across OSes and machine - const codeWithoutSystemPath = code.replace( - /var _jsxFileName = ".*";/, - 'var _jsxFileName = "/root/project/src/file.js";', - ); - - return formatResult(codeWithoutSystemPath); + 'top level mocking': { + code: formatResult(` + require('x'); + + jest.enableAutomock(); + jest.disableAutomock(); + `), + formatResult, + snapshot: true, + }, + 'within a block': { + code: formatResult(` + beforeEach(() => { + require('x') + jest.mock('someNode') + }) + `), + formatResult, + snapshot: true, + }, + 'within a block with no siblings': { + code: formatResult(` + beforeEach(() => { + jest.mock('someNode') + }) + `), + formatResult, + snapshot: true, }, - snapshot: true, - }, - 'top level mocking': { - code: formatResult(` - require('x'); - - jest.enableAutomock(); - jest.disableAutomock(); - `), - formatResult, - snapshot: true, - }, - 'within a block': { - code: formatResult(` - beforeEach(() => { - require('x') - jest.mock('someNode') - }) - `), - formatResult, - snapshot: true, - }, - 'within a block with no siblings': { - code: formatResult(` - beforeEach(() => { - jest.mock('someNode') - }) - `), - formatResult, - snapshot: true, - }, - 'required `jest` within `jest`': { - code: formatResult(` - const {jest} = require('@jest/globals'); + 'required `jest` within `jest`': { + code: formatResult(` + const {jest} = require('@jest/globals'); - jest.mock('some-module', () => { - jest.requireActual('some-module'); - }); - `), - formatResult, - snapshot: true, - }, - 'imported jest.mock within jest.mock': { - code: formatResult(` - import {jest} from '@jest/globals'; - - jest.mock('some-module', () => { - jest.mock('some-module'); - }); - `), - formatResult, - snapshot: true, - }, - 'global jest.mock within jest.mock': { - code: formatResult(` - jest.mock('some-module', () => { - jest.mock('some-module'); - }); - `), - formatResult, - snapshot: true, - }, - 'imported jest.requireActual in jest.mock': { - code: formatResult(` - import {jest} from '@jest/globals'; + jest.mock('some-module', () => { + jest.requireActual('some-module'); + }); + `), + formatResult, + snapshot: true, + }, + 'imported jest.mock within jest.mock': { + code: formatResult(` + import {jest} from '@jest/globals'; + + jest.mock('some-module', () => { + jest.mock('some-module'); + }); + `), + formatResult, + snapshot: true, + }, + 'global jest.mock within jest.mock': { + code: formatResult(` + jest.mock('some-module', () => { + jest.mock('some-module'); + }); + `), + formatResult, + snapshot: true, + }, + 'imported jest.requireActual in jest.mock': { + code: formatResult(` + import {jest} from '@jest/globals'; + + jest.mock('some-module', () => { + jest.requireActual('some-module'); + }); - jest.mock('some-module', () => { jest.requireActual('some-module'); - }); + `), + formatResult, + snapshot: true, + }, + 'global jest.requireActual in jest.mock': { + code: formatResult(` + jest.mock('some-module', () => { + jest.requireActual('some-module'); + }); - jest.requireActual('some-module'); - `), - formatResult, - snapshot: true, - }, - 'global jest.requireActual in jest.mock': { - code: formatResult(` - jest.mock('some-module', () => { jest.requireActual('some-module'); - }); + `), + formatResult, + snapshot: true, + }, + 'TS typeof usage in jest.mock': { + babelOptions: { + babelrc: false, + configFile: false, + filename: path.resolve(__dirname, '../file.ts'), + presets: [presetTypescript], + }, + code: formatResult(` + jest.mock('some-module', () => { + const actual = jest.requireActual('some-module'); - jest.requireActual('some-module'); - `), - formatResult, - snapshot: true, - }, - 'TS typeof usage in jest.mock': { - babelOptions: { - babelrc: false, - configFile: false, - filename: path.resolve(__dirname, '../file.ts'), - presets: [[require.resolve('@babel/preset-typescript')]], + return jest.fn(); + }); + `), + formatResult, + snapshot: true, + }, + 'jest.spyOn call on the imported module': { + code: formatResult(` + jest.mock('some-module', () => { + const module = jest.requireActual('some-module'); + jest.spyOn(module, 'add'); + return module; + }); + `), + formatResult, + snapshot: true, + }, + 'jest.spyOn call in class constructor': { + code: formatResult(` + jest.mock('some-module', () => { + const Actual = jest.requireActual('some-module'); + return class Mocked extends Actual { + constructor() { + super(); + jest.spyOn(this, 'add'); + } + }; + }); + `), + formatResult, + snapshot: true, }, - code: formatResult(` - jest.mock('some-module', () => { - const actual = jest.requireActual('some-module'); - - return jest.fn(); - }); - `), - formatResult, - snapshot: true, - }, - 'jest.spyOn call on the imported module': { - code: formatResult(` - jest.mock('some-module', () => { - const module = jest.requireActual('some-module'); - jest.spyOn(module, 'add'); - return module; - }); - `), - formatResult, - snapshot: true, - }, - 'jest.spyOn call in class constructor': { - code: formatResult(` - jest.mock('some-module', () => { - const Actual = jest.requireActual('some-module'); - return class Mocked extends Actual { - constructor() { - super(); - jest.spyOn(this, 'add'); - } - }; - }); - `), - formatResult, - snapshot: true, }, - }, - /* eslint-enable */ -}); + /* eslint-enable */ + }); +} diff --git a/packages/babel-plugin-jest-hoist/src/index.ts b/packages/babel-plugin-jest-hoist/src/index.ts index c59632ce9e63..4340b38026bc 100644 --- a/packages/babel-plugin-jest-hoist/src/index.ts +++ b/packages/babel-plugin-jest-hoist/src/index.ts @@ -7,22 +7,19 @@ */ import type {PluginObj} from '@babel/core'; -import {statement} from '@babel/template'; import type {NodePath} from '@babel/traverse'; -import { - type CallExpression, - type Expression, - type Identifier, - type ImportDeclaration, - type MemberExpression, - type Node, - type Statement, - type Super, - type VariableDeclaration, - type VariableDeclarator, - callExpression, - isIdentifier, - variableDeclaration, +import type { + CallExpression, + Expression, + Identifier, + ImportDeclaration, + MemberExpression, + Node, + Statement, + StringLiteral, + Super, + VariableDeclaration, + VariableDeclarator, } from '@babel/types'; const JEST_GLOBAL_NAME = 'jest'; @@ -170,10 +167,12 @@ FUNCTIONS.mock = args => { } else if (binding?.path.isImportSpecifier()) { const importDecl = binding.path .parentPath as NodePath; - const imported = binding.path.node.imported; + const imported = binding.path.get('imported'); if ( importDecl.node.source.value === JEST_GLOBALS_MODULE_NAME && - (isIdentifier(imported) ? imported.name : imported.value) === + (imported.isIdentifier() + ? imported.node.name + : (imported.node as StringLiteral).value) === JEST_GLOBALS_MODULE_JEST_EXPORT_NAME ) { isAllowedIdentifier = true; @@ -208,14 +207,6 @@ FUNCTIONS.deepUnmock = args => args.length === 1 && args[0].isStringLiteral(); FUNCTIONS.disableAutomock = FUNCTIONS.enableAutomock = args => args.length === 0; -const createJestObjectGetter = statement` -function GETTER_NAME() { - const { JEST_GLOBALS_MODULE_JEST_EXPORT_NAME } = require("JEST_GLOBALS_MODULE_NAME"); - GETTER_NAME = () => JEST_GLOBALS_MODULE_JEST_EXPORT_NAME; - return JEST_GLOBALS_MODULE_JEST_EXPORT_NAME; -} -`; - const isJestObject = ( expression: NodePath, ): expression is NodePath => { @@ -310,10 +301,22 @@ const extractJestObjExprIfHoistable = (expr: NodePath): JestObjInfo | null => { }; /* eslint-disable sort-keys */ -export default function jestHoist(): PluginObj<{ +export default function jestHoist( + babel: typeof import('@babel/core'), +): PluginObj<{ declareJestObjGetterIdentifier: () => Identifier; jestObjGetterIdentifier?: Identifier; }> { + const {template, types: t} = babel; + + const createJestObjectGetter = template.statement` + function GETTER_NAME() { + const { JEST_GLOBALS_MODULE_JEST_EXPORT_NAME } = require("JEST_GLOBALS_MODULE_NAME"); + GETTER_NAME = () => JEST_GLOBALS_MODULE_JEST_EXPORT_NAME; + return JEST_GLOBALS_MODULE_JEST_EXPORT_NAME; + } + `; + return { pre({path: program}) { this.declareJestObjGetterIdentifier = () => { @@ -341,7 +344,7 @@ export default function jestHoist(): PluginObj<{ exprStmt.get('expression'), ); if (jestObjInfo) { - const jestCallExpr = callExpression( + const jestCallExpr = t.callExpression( this.declareJestObjGetterIdentifier(), [], ); @@ -388,7 +391,9 @@ export default function jestHoist(): PluginObj<{ } else { varDecl.remove(); } - stack.at(-1)!.vars.push(variableDeclaration(kind, [varDecl.node])); + stack + .at(-1)! + .vars.push(t.variableDeclaration(kind, [varDecl.node])); } }, }); diff --git a/packages/babel-preset-jest/package.json b/packages/babel-preset-jest/package.json index bcc56adbba63..734059aff8f6 100644 --- a/packages/babel-preset-jest/package.json +++ b/packages/babel-preset-jest/package.json @@ -14,10 +14,10 @@ }, "dependencies": { "babel-plugin-jest-hoist": "workspace:*", - "babel-preset-current-node-syntax": "^1.1.0" + "babel-preset-current-node-syntax": "^1.2.0" }, "peerDependencies": { - "@babel/core": "^7.11.0" + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index 491c75f1e9a4..4ff9b96cd40f 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -29,7 +29,7 @@ "@jest/snapshot-utils": "workspace:*", "@jest/transform": "workspace:*", "@jest/types": "workspace:*", - "babel-preset-current-node-syntax": "^1.1.0", + "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", "expect": "workspace:*", "graceful-fs": "^4.2.11", diff --git a/yarn.lock b/yarn.lock index 5b0b6c123f91..1dec89af0b3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -363,6 +363,65 @@ __metadata: languageName: node linkType: hard +"@babel-8/core@npm:@babel/core@8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/core@npm:8.0.0-beta.1" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^8.0.0-beta.1" + "@babel/generator": "npm:^8.0.0-beta.1" + "@babel/helper-compilation-targets": "npm:^8.0.0-beta.1" + "@babel/helpers": "npm:^8.0.0-beta.1" + "@babel/parser": "npm:^8.0.0-beta.1" + "@babel/template": "npm:^8.0.0-beta.1" + "@babel/traverse": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + "@types/gensync": "npm:^1.0.0" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^7.3.4" + peerDependencies: + "@babel/preset-typescript": ^7.21.4 || ^8.0.0-0 + peerDependenciesMeta: + "@babel/preset-typescript": + optional: true + checksum: 10/c486f9eeedf92903dcf73b68e5589f8086a01c46780688fad47a090e0b015908b01f8a507804bb6a32b87cd48ae3cc664cdcb12f7ee8f31e8b2dc40d87b1da44 + languageName: node + linkType: hard + +"@babel-8/preset-react@npm:@babel/preset-react@8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/preset-react@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + "@babel/helper-validator-option": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-react-display-name": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-react-jsx": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-react-jsx-development": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-react-pure-annotations": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/53cabfd5c8b96e77438b0270ebf40c6a33626da888ddbd2969dd6348408dce8e35c42d793e807da68eef815e485daaf5d0a1587108f6203c680bcf524452fd2c + languageName: node + linkType: hard + +"@babel-8/preset-typescript@npm:@babel/preset-typescript@8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/preset-typescript@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + "@babel/helper-validator-option": "npm:^8.0.0-beta.1" + "@babel/plugin-syntax-jsx": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-modules-commonjs": "npm:^8.0.0-beta.1" + "@babel/plugin-transform-typescript": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/4fbca261c45acc43cc07ab81b09acd10c161d75d260066b5f41859a20245453340aac25b35ac4fadede8f8fcfd42acc2052362347ade59bf9c831c89448a5a78 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" @@ -374,6 +433,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/code-frame@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^8.0.0-beta.1" + js-tokens: "npm:^8.0.0" + picocolors: "npm:^1.1.1" + checksum: 10/3d60a5514b6dce15332c5b5256b609fdfc0c5bd205147a6c97e1d683c53fdaf27a506f7207cc19aa80d750119398abc851886bb413e5e3bee225c048946434ca + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.27.2": version: 7.27.2 resolution: "@babel/compat-data@npm:7.27.2" @@ -381,6 +451,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/compat-data@npm:8.0.0-beta.1" + checksum: 10/10d5bae7048cfdcd6914412a71ffd406d08001405f9da5b302009e4272913d61458609dcfb1bb2becff81010c6aa08bc3b1e5db35863847fb4b8c29a8fb776ef + languageName: node + linkType: hard + "@babel/core@npm:^7.13.16, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2, @babel/core@npm:^7.25.9, @babel/core@npm:^7.27.4": version: 7.27.4 resolution: "@babel/core@npm:7.27.4" @@ -417,6 +494,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/generator@npm:8.0.0-beta.1" + dependencies: + "@babel/parser": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10/ca377af327d996f31b86639241414b0cb96cc3c41de698a998dcd64a0bbb14297afc68bfe106ef60465e2e29c33491b180c6ef3a325bd4ca7ee1c7fd442bee75 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-annotate-as-pure@npm:7.27.1" @@ -426,6 +516,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-annotate-as-pure@npm:8.0.0-beta.1" + dependencies: + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/d200ef2ad21d39d692e1e5e84e9158505d4b902a7e721c7ac6875b2125bd9ea1356a89e244fd44c83d2292c358b8b3053dc1d060f2e59d5a475535ded1dfaebe + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": version: 7.27.2 resolution: "@babel/helper-compilation-targets@npm:7.27.2" @@ -439,6 +538,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-compilation-targets@npm:8.0.0-beta.1" + dependencies: + "@babel/compat-data": "npm:^8.0.0-beta.1" + "@babel/helper-validator-option": "npm:^8.0.0-beta.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^7.14.1" + semver: "npm:^7.3.4" + checksum: 10/abc86605e31ba07ee6eecc592b47d6569a0658507bdd60a435a0f1264e8b2af43d27e04f1699e87ada800e04bb716d2503800d7f61f05765f440db694bf1140a + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1" @@ -456,6 +568,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-create-class-features-plugin@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^8.0.0-beta.1" + "@babel/helper-member-expression-to-functions": "npm:^8.0.0-beta.1" + "@babel/helper-optimise-call-expression": "npm:^8.0.0-beta.1" + "@babel/helper-replace-supers": "npm:^8.0.0-beta.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^8.0.0-beta.1" + "@babel/traverse": "npm:^8.0.0-beta.1" + semver: "npm:^7.3.4" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/0b9aa2e8c52ae4141e9fa179e887daaa2dc2c8bb9677e6ba3b678f4bad08556e0ce58816c2704a6e74c77e23e12ab39f18f2dc5975b76037002c1585375cb8cf + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.1" @@ -484,6 +613,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-globals@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-globals@npm:8.0.0-beta.1" + checksum: 10/414e0358f1d74b177c5031378b655be40aa0b4f1b58ac990e1bf11b3cdfec461827104ff83bdc604309b06fdda972dac97b0ba2cd27d39beb17e85847f5b6b7b + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1" @@ -494,6 +630,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-member-expression-to-functions@npm:8.0.0-beta.1" + dependencies: + "@babel/traverse": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/523897dd0bf91dbeca9cedeca04d4e3f82478cb73cb797412cfd407e7d06693d414b1e99c9da8bc084b1191f6cc71b86f8f039aa448ca7ea0bc81661f1054f2c + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" @@ -504,6 +650,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-module-imports@npm:8.0.0-beta.1" + dependencies: + "@babel/traverse": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/7ce7a80ab8cd35c015fc3880118ab4402aa6d26b87fe8cae2226eddd25c13fe34603485ea1ba7dda0bd85f0b23e1bc265c1cdaaba85f5dfcda31fda3c300e74d + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-module-transforms@npm:7.27.3" @@ -517,6 +673,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-module-transforms@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-module-imports": "npm:^8.0.0-beta.1" + "@babel/helper-validator-identifier": "npm:^8.0.0-beta.1" + "@babel/traverse": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/9d24e9e7af9ef42b05c7dd00625aad929637630a6628fe5e5a3f91c1f3a33a8ff901c78e216b7963ec87c462eb3abfc610d7695348fd4c23996f8adda3ae8005 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" @@ -526,6 +695,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-optimise-call-expression@npm:8.0.0-beta.1" + dependencies: + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/1ce45306f1335ca5f1e78d2b19ae74ddc341c264664381b9df04e0a0b965caa10388ccaabb8707b75fab5694b07ba2fff0632220109e6c973f9e4b9ec818e28e + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.27.1 resolution: "@babel/helper-plugin-utils@npm:7.27.1" @@ -533,6 +711,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-plugin-utils@npm:8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/66aee91a5fe32adf8cc39bb47bcceda2fc9893839bb891a8c502916f1aafd5350be8c08d2313abffb43f9c9bc94ed25b65c07e6f586dbd26a9bb829d4ebbec54 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" @@ -559,6 +746,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-replace-supers@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^8.0.0-beta.1" + "@babel/helper-optimise-call-expression": "npm:^8.0.0-beta.1" + "@babel/traverse": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/a3b5b33322ef1299bc1e65e2718f5762753f1d611c77d88dc219bb3bf2b900b44ec047f6abc6873aabbc1df7f9b0e1c40d4d88ec4e38ba7d0233d6d76ed9e717 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -569,6 +769,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:8.0.0-beta.1" + dependencies: + "@babel/traverse": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/1af15f949a93205fd3b7c19ad3fa0d61a9261d7cfdd605129f1569adf8bdb9dca0b0b5547f40fa5c03841c2a38b5b7de01b0a8632f889014495a3867533b7c8d + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-string-parser@npm:7.27.1" @@ -576,6 +786,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-string-parser@npm:8.0.0-beta.1" + checksum: 10/73f4d84ff62197e8e83ed493c475771ad44b43f0c86d29317b19188a5d3f635d0b6d22d44d52a701d4d1a0c600d8921bd199af71110321c5bf2ff7d543067d84 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-identifier@npm:7.27.1" @@ -583,6 +800,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-validator-identifier@npm:8.0.0-beta.1" + checksum: 10/03764d83050e638a0f609512d676048e6474601c5dc43ab341ca3a88b7f47bcd83e75f448f6d969a5a560a9a32dc8d8143aca1d3905d01d642b9f0b6a419f6b0 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-option@npm:7.27.1" @@ -590,6 +814,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helper-validator-option@npm:8.0.0-beta.1" + checksum: 10/bd1119a305d15dabe6a10689113163cfbfcba7651f5bcf7e44d29ebec32d320c1512268d8011cbfc23c3d5d28084894bfc5a2aab67e29e096b3d7cb2f957f8f8 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-wrap-function@npm:7.27.1" @@ -611,6 +842,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/helpers@npm:8.0.0-beta.1" + dependencies: + "@babel/template": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/99d88bdb97a5dc8ab4aa8884b72afbbe1566d57bb0c09fb078013b509a5702e7cb112efd390e51834b03a4f1dee9389663e72c58c542f53fb6b0bd5775127904 + languageName: node + linkType: hard + "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.27.1, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.4, @babel/parser@npm:^7.27.5": version: 7.27.5 resolution: "@babel/parser@npm:7.27.5" @@ -622,6 +863,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/parser@npm:8.0.0-beta.1" + dependencies: + "@babel/types": "npm:^8.0.0-beta.1" + bin: + parser: ./bin/babel-parser.js + checksum: 10/35863d2c3d2c2806bfce87c212299ff09ca72e96f445e69c49a9f6dc205ee3a61805e7a9a071b25d0fc1c26b7b3f63b45dc3080caee0b0847cce11695f1428f6 + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" @@ -894,6 +1146,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-syntax-jsx@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/208489f482b3420b8e1e39092fe4ee0f697cb7704c4602b2e95a507b7bb6fb02b205dc42c20b658a84221f33d50957fefa818cca2a7c096a124cf368ac77832d + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -993,6 +1256,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-syntax-typescript@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/038b3950561c71daf5eab6fa47c3cbf6e373dc587aadb7805290287141c138826ed166136cf646d2e11c2166b8d4eeefc04ee11fa13192db54dd435606f9011f + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1300,6 +1574,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-module-transforms": "npm:^8.0.0-beta.1" + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/1906ce306fd57047503a7dcb728cd55b465c71b2a383b2f0503073a5063673716ba415b7576cc5bf280b880149588b4ec91ed76910d6cd4194d3d3f2294a125c + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.27.1" @@ -1489,6 +1775,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-display-name@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-react-display-name@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/43b3004a2a90d0d63f145e5f7d31d751c0208bb9eb75b16b611f53f6b2fe48f6ef343fd6787d1668147dda75224ad07e9d5e869b9d104ea1e8b805e5f2625a48 + languageName: node + linkType: hard + "@babel/plugin-transform-react-jsx-development@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-react-jsx-development@npm:7.27.1" @@ -1500,6 +1797,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-jsx-development@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-react-jsx-development@npm:8.0.0-beta.1" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/09053e6319af5d3a1f231ff8705a590b26a70a3f57b516dc0fa6f2199f2bc220244218270a3ac43441d1a64e0d6bba1023f8fd57843e164780b5093a24b46f3c + languageName: node + linkType: hard + "@babel/plugin-transform-react-jsx-self@npm:^7.24.7": version: 7.27.1 resolution: "@babel/plugin-transform-react-jsx-self@npm:7.27.1" @@ -1537,6 +1845,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-jsx@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-react-jsx@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^8.0.0-beta.1" + "@babel/helper-module-imports": "npm:^8.0.0-beta.1" + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + "@babel/plugin-syntax-jsx": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/8cca4a4d0f9cee7f30751fe125bf32e2d8c794d6a7c1f92dd209877757540ca03f99e604ec92731382afc04b0f50a6d9e763246d8822f07be746029d28aa7cff + languageName: node + linkType: hard + "@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.27.1" @@ -1549,6 +1872,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-pure-annotations@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^8.0.0-beta.1" + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/cfe1a8a1eeca765ab3f852b3d45753dea284657f45ad49115021b11200abdfcff915dd735f22e3e33907eda0e1dcb0b904c883d44525a669d68d4fed460a6dd5 + languageName: node + linkType: hard + "@babel/plugin-transform-regenerator@npm:^7.24.7, @babel/plugin-transform-regenerator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-regenerator@npm:7.27.1" @@ -1670,6 +2005,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/plugin-transform-typescript@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^8.0.0-beta.1" + "@babel/helper-create-class-features-plugin": "npm:^8.0.0-beta.1" + "@babel/helper-plugin-utils": "npm:^8.0.0-beta.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^8.0.0-beta.1" + "@babel/plugin-syntax-typescript": "npm:^8.0.0-beta.1" + peerDependencies: + "@babel/core": ^8.0.0-beta.1 + checksum: 10/5d818fe5ee87bb00ef12d86dcf84cb8c05dc6051b0e4f416cc38e0a148e9b03fe64e35d8c67f107e12bf0906bf23b5e668b0b2f008ec66adb909bcea7278d41b + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" @@ -1895,6 +2245,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/template@npm:8.0.0-beta.1" + dependencies: + "@babel/code-frame": "npm:^8.0.0-beta.1" + "@babel/parser": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + checksum: 10/ac267409100661293088563fc5eb18a033acabc66babaa441b2e5c6d85db9b880d0ede8943ced3eddc4353b31dba2911f0c1cb15cd30fbf0d4b94fd1406825c9 + languageName: node + linkType: hard + "@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3": version: 7.27.1 resolution: "@babel/traverse@npm:7.27.1" @@ -1925,6 +2286,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/traverse@npm:8.0.0-beta.1" + dependencies: + "@babel/code-frame": "npm:^8.0.0-beta.1" + "@babel/generator": "npm:^8.0.0-beta.1" + "@babel/helper-globals": "npm:^8.0.0-beta.1" + "@babel/parser": "npm:^8.0.0-beta.1" + "@babel/template": "npm:^8.0.0-beta.1" + "@babel/types": "npm:^8.0.0-beta.1" + debug: "npm:^4.3.1" + checksum: 10/8a2ba75ae46ab97a88ba54cf235c2c828cc165191cd680501ad378497d6d4fe93cd7d99dfdfea49cca6617fbc34dae8525392dbc2a42b1f4dcffb0f6602292d0 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.2, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.4.4": version: 7.27.3 resolution: "@babel/types@npm:7.27.3" @@ -1935,6 +2311,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^8.0.0-beta.1": + version: 8.0.0-beta.1 + resolution: "@babel/types@npm:8.0.0-beta.1" + dependencies: + "@babel/helper-string-parser": "npm:^8.0.0-beta.1" + "@babel/helper-validator-identifier": "npm:^8.0.0-beta.1" + checksum: 10/387992998c93cec8f89218af092ec54ea9efdc349b20f1b1b4a4c8f78411f26d307b899688e893a3c90ec8aec2bffe53aec2bf8ba90be75d75839c4856c71dcb + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -4248,14 +4634,13 @@ __metadata: languageName: unknown linkType: soft -"@jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.8 - resolution: "@jridgewell/gen-mapping@npm:0.3.8" +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.12 + resolution: "@jridgewell/gen-mapping@npm:0.3.12" dependencies: - "@jridgewell/set-array": "npm:^1.2.1" - "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/sourcemap-codec": "npm:^1.5.0" "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/9d3a56ab3612ab9b85d38b2a93b87f3324f11c5130859957f6500e4ac8ce35f299d5ccc3ecd1ae87597601ecf83cee29e9afd04c18777c24011073992ff946df + checksum: 10/151667531566417a940d4dd0a319724979f7a90b9deb9f1617344e1183887d78c835bc1a9209c1ee10fc8a669cdd7ac8120a43a2b6bc8d0d5dd18a173059ff4b languageName: node linkType: hard @@ -4266,13 +4651,6 @@ __metadata: languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.2.1": - version: 1.2.1 - resolution: "@jridgewell/set-array@npm:1.2.1" - checksum: 10/832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 - languageName: node - linkType: hard - "@jridgewell/source-map@npm:^0.3.3": version: 0.3.6 resolution: "@jridgewell/source-map@npm:0.3.6" @@ -4283,10 +4661,10 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": - version: 1.5.0 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" - checksum: 10/4ed6123217569a1484419ac53f6ea0d9f3b57e5b57ab30d7c267bdb27792a27eb0e4b08e84a2680aa55cc2f2b411ffd6ec3db01c44fdc6dc43aca4b55f8374fd +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.4 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.4" + checksum: 10/f677787f52224c6c971a7a41b7a074243240a6917fa75eceb9f7a442866f374fb0522b505e0496ee10a650c5936727e76d11bf36a6d0ae9e6c3b726c9e284cc7 languageName: node linkType: hard @@ -4300,13 +4678,13 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": - version: 0.3.25 - resolution: "@jridgewell/trace-mapping@npm:0.3.25" +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.29 + resolution: "@jridgewell/trace-mapping@npm:0.3.29" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10/dced32160a44b49d531b80a4a2159dceab6b3ddf0c8e95a0deae4b0e894b172defa63d5ac52a19c2068e1fe7d31ea4ba931fbeec103233ecb4208953967120fc + checksum: 10/64e1ce0dc3a9e56b0118eaf1b2f50746fd59a36de37516cc6855b5370d5f367aa8229e1237536d738262e252c70ee229619cb04e3f3b822146ee3eb1b7ab297f languageName: node linkType: hard @@ -6102,6 +6480,13 @@ __metadata: languageName: node linkType: hard +"@types/gensync@npm:^1.0.0": + version: 1.0.4 + resolution: "@types/gensync@npm:1.0.4" + checksum: 10/99c3aa0d3f1198973c7e51bea5947b815f3338ce89ce09a39ac8abb41cd844c5b95189da254ea45e50a395fe25fd215664d8ca76c5438814963597afb01f686e + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.9": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -7599,6 +7984,7 @@ __metadata: version: 0.0.0-use.local resolution: "babel-jest@workspace:packages/babel-jest" dependencies: + "@babel-8/core": "npm:@babel/core@8.0.0-beta.1" "@babel/core": "npm:^7.27.4" "@jest/test-utils": "workspace:*" "@jest/transform": "workspace:*" @@ -7610,7 +7996,7 @@ __metadata: graceful-fs: "npm:^4.2.11" slash: "npm:^3.0.0" peerDependencies: - "@babel/core": ^7.11.0 + "@babel/core": ^7.11.0 || ^8.0.0-0 languageName: unknown linkType: soft @@ -7653,10 +8039,12 @@ __metadata: version: 0.0.0-use.local resolution: "babel-plugin-jest-hoist@workspace:packages/babel-plugin-jest-hoist" dependencies: + "@babel-8/core": "npm:@babel/core@8.0.0-beta.1" + "@babel-8/preset-react": "npm:@babel/preset-react@8.0.0-beta.1" + "@babel-8/preset-typescript": "npm:@babel/preset-typescript@8.0.0-beta.1" "@babel/core": "npm:^7.27.4" "@babel/preset-react": "npm:^7.27.1" "@babel/preset-typescript": "npm:^7.27.1" - "@babel/template": "npm:^7.27.2" "@babel/types": "npm:^7.27.3" "@prettier/sync": "npm:^0.5.5" "@types/babel__core": "npm:^7.20.5" @@ -7755,9 +8143,9 @@ __metadata: languageName: node linkType: hard -"babel-preset-current-node-syntax@npm:^1.1.0": - version: 1.1.0 - resolution: "babel-preset-current-node-syntax@npm:1.1.0" +"babel-preset-current-node-syntax@npm:^1.2.0": + version: 1.2.0 + resolution: "babel-preset-current-node-syntax@npm:1.2.0" dependencies: "@babel/plugin-syntax-async-generators": "npm:^7.8.4" "@babel/plugin-syntax-bigint": "npm:^7.8.3" @@ -7775,8 +8163,8 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/46331111ae72b7121172fd9e6a4a7830f651ad44bf26dbbf77b3c8a60a18009411a3eacb5e72274004290c110371230272109957d5224d155436b4794ead2f1b + "@babel/core": ^7.0.0 || ^8.0.0-0 + checksum: 10/3608fa671cfa46364ea6ec704b8fcdd7514b7b70e6ec09b1199e13ae73ed346c51d5ce2cb6d4d5b295f6a3f2cad1fdeec2308aa9e037002dd7c929194cc838ea languageName: node linkType: hard @@ -7785,9 +8173,9 @@ __metadata: resolution: "babel-preset-jest@workspace:packages/babel-preset-jest" dependencies: babel-plugin-jest-hoist: "workspace:*" - babel-preset-current-node-syntax: "npm:^1.1.0" + babel-preset-current-node-syntax: "npm:^1.2.0" peerDependencies: - "@babel/core": ^7.11.0 + "@babel/core": ^7.11.0 || ^8.0.0-beta.1 languageName: unknown linkType: soft @@ -13908,7 +14296,7 @@ __metadata: "@types/semver": "npm:^7.7.0" ansi-regex: "npm:^5.0.1" ansi-styles: "npm:^5.2.0" - babel-preset-current-node-syntax: "npm:^1.1.0" + babel-preset-current-node-syntax: "npm:^1.2.0" chalk: "npm:^4.1.2" expect: "workspace:*" graceful-fs: "npm:^4.2.11" @@ -14185,6 +14573,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^8.0.0": + version: 8.0.3 + resolution: "js-tokens@npm:8.0.3" + checksum: 10/af5ed8ddbc446a868c026599214f4a482ab52461edb82e547949255f98910a14bd81ddab88a8d570d74bd7dc96c6d4df7f963794ec5aaf13c53918cc46b9caa6 + languageName: node + linkType: hard + "js-yaml@npm:^3.13.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -14731,6 +15126,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^7.14.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: 10/6029ca5aba3aacb554e919d7ef804fffd4adfc4c83db00fac8248c7c78811fb6d4b6f70f7fd9d55032b3823446546a007edaa66ad1f2377ae833bd983fac5d98 + languageName: node + linkType: hard + "lru-cache@patch:lru-cache@npm:10.4.3#./.yarn/patches/lru-cache-npm-10.4.3-30c10b861a.patch::locator=%40jest%2Fmonorepo%40workspace%3A.": version: 10.4.3 resolution: "lru-cache@patch:lru-cache@npm%3A10.4.3#./.yarn/patches/lru-cache-npm-10.4.3-30c10b861a.patch::version=10.4.3&hash=e5e8aa&locator=%40jest%2Fmonorepo%40workspace%3A." @@ -19669,7 +20071,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2": +"semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: