feat: add jest.hoisted API for hoisting variables alongside jest.mock factories#16201
Open
ahnpnl wants to merge 1 commit into
Open
feat: add jest.hoisted API for hoisting variables alongside jest.mock factories#16201ahnpnl wants to merge 1 commit into
jest.hoisted API for hoisting variables alongside jest.mock factories#16201ahnpnl wants to merge 1 commit into
Conversation
✅ Deploy Preview for jestjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
ee4558a to
70e919c
Compare
5f2cf1d to
0589ac6
Compare
babel-jest
babel-plugin-jest-hoist
babel-preset-jest
create-jest
@jest/diff-sequences
expect
@jest/expect-utils
jest
jest-changed-files
jest-circus
jest-cli
jest-config
@jest/console
@jest/core
@jest/create-cache-key-function
jest-diff
jest-docblock
jest-each
@jest/environment
jest-environment-jsdom
@jest/environment-jsdom-abstract
jest-environment-node
@jest/expect
@jest/fake-timers
@jest/get-type
@jest/globals
jest-haste-map
jest-jasmine2
jest-leak-detector
jest-matcher-utils
jest-message-util
jest-mock
@jest/pattern
jest-phabricator
jest-regex-util
@jest/reporters
jest-resolve
jest-resolve-dependencies
jest-runner
jest-runtime
@jest/schemas
jest-snapshot
@jest/snapshot-utils
@jest/source-map
@jest/test-result
@jest/test-sequencer
@jest/transform
@jest/types
jest-util
jest-validate
jest-watcher
jest-worker
pretty-format
commit: |
There was a problem hiding this comment.
Pull request overview
Adds a new jest.hoisted(factory) API to support hoisting explicit variable initializers alongside jest.mock hoisting, enabling safe references from jest.mock factories without relying on the mock* naming allowlist.
Changes:
- Extend
babel-plugin-jest-hoistto recognize and hoistjest.hoisted(...)used in both declarations and bare statements, and to rewritejestreferences inside hoisted factories. - Add
jest.hoistedto the runtime-provided per-filejestobject and to theJestenvironment type interface. - Add unit + e2e coverage and document the new API (including changelog entry).
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/jest-runtime/src/internals/JestGlobals.ts | Exposes hoisted on the per-file jest object implementation. |
| packages/jest-environment/src/index.ts | Adds hoisted<T>(factory) to the Jest interface with documentation. |
| packages/babel-plugin-jest-hoist/src/index.ts | Implements detection, validation, rewriting, and hoisting for jest.hoisted(...). |
| packages/babel-plugin-jest-hoist/src/tests/hoistPlugin.nodejs18.test.ts | Adds transform tests covering jest.hoisted syntax/behavior and errors. |
| packages/babel-plugin-jest-hoist/src/tests/snapshots/hoistPlugin.nodejs20plus.test.ts.snap | Updates snapshots for the new hoisting transforms (Babel 7/8). |
| packages/babel-plugin-jest-hoist/src/tests/snapshots/hoistPlugin.nodejs18.test.ts.snap | Adds snapshots for the new hoisting transforms (Node 18 suite). |
| packages/babel-plugin-jest-hoist/README.md | Documents that the plugin also hoists jest.hoisted calls. |
| e2e/babel-plugin-jest-hoist/tests/hoistedOrdering.test.js | E2E fixture asserting hoist ordering relative to module import initialization. |
| e2e/babel-plugin-jest-hoist/tests/hoisted.test.js | E2E fixture asserting jest.hoisted bindings are visible in jest.mock factories. |
| e2e/babel-plugin-jest-hoist/test_modules/relyOnHoisted.js | Module used by the e2e ordering test to observe import-time state. |
| e2e/tests/babelPluginJestHoist.test.ts | Updates the expected number of fixture test suites. |
| docs/JestObjectAPI.md | Adds public API documentation for jest.hoisted(factory). |
| CHANGELOG.md | Adds a Features entry describing the new jest.hoisted API. |
0589ac6 to
1016558
Compare
…jest.mock factories # Conflicts: # CHANGELOG.md
1016558 to
d018ac7
Compare
jest.hoisted API for hoisting variables alongside jest.mock factories
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
jest.hoisted(factory)API, mirroringvi.hoistedfrom VitestMotivation
jest.mockfactories run before module imports. Today the only escape hatch for referencing variables from ajest.mockfactory is themock-prefix allowlist (any identifier matching/^mock/i). For everything else,babel-plugin-jest-hoistthrows:jest.hoistedprovides an explicit, opt-in mechanism: any variable declared viajest.hoistedis hoisted to the top of the file alongsidejest.mockcalls, so it is available insidejest.mockfactory bodies — regardless of naming.Example
Scope
Sync overload only:
jest.hoisted<T>(factory: () => T): T.The async overload (
() => Promise<T>) is intentionally not included. It would only be useful in native ESM (top-levelawait), but the underlying_getJestObj()template inbabel-plugin-jest-hoistusesrequire('@jest/globals'), which is undefined under--experimental-vm-modules. This is a pre-existing limitation that also affectsjest.mockand is out of scope for this PR.Changes
babel-plugin-jest-hoist— recognisesjest.hoisted(factory)as a hoistable call in bothVariableDeclarationandExpressionStatementpositions. Supportsconst/let/varand destructuring. Rewritesjest.*references inside the factory body to_getJestObj().*. ThrowsReferenceErrorfor non-top-level usage, nestedjest.mock/jest.hoistedinside a hoisted factory, andTypeErrorfor non-function arguments or wrong arity.jest-runtime— addshoisted: factory => factory()to the per-file jest object built inJestGlobals.jestObjectFor, shared by both CJS and ESM module loaders.jest-environment— addshoisted<T>(factory: () => T): Tto theJestinterface.docs/JestObjectAPI.md, README update inbabel-plugin-jest-hoist,CHANGELOG.mdentry.Validation rules (vitest parity)
const x = jest.hoisted(() => 1)at top leveljest.hoisted(() => { ... })at top levellet/var/ destructurejest.hoistedcallsjest.hoistedinsideif (true) { ... }ReferenceErrorjest.hoistedinsidejest.mockfactoryReferenceErrorjest.mockinsidejest.hoistedfactoryReferenceErrorjest.hoisted({notAFunction: true})TypeErrorjest.hoisted()TypeErrorTest plan
E2E fixture
e2e/babel-plugin-jest-hoist/__tests__/hoistedOrdering.test.jsproves hoist order by settingglobalThis.__jestHoistedValue__inside a barejest.hoistedfactory and observing it from a sibling module's import-time snapshot — mirrors Vitest'shoisted-simple.test.ts.