From d0d73faf184aef9f8c6fb6be794ddc85de1d5d14 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 29 Oct 2020 09:55:50 +0100 Subject: [PATCH] hack a "fix" --- .../__snapshots__/hoistPlugin.test.ts.snap | 37 ++++++++++++ .../src/__tests__/hoistPlugin.test.ts | 2 +- packages/babel-plugin-jest-hoist/src/index.ts | 56 ++++++++++--------- 3 files changed, 68 insertions(+), 27 deletions(-) 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 0c1a8424ff4f..4ce0fdde3291 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,5 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`babel-plugin-jest-hoist automatic react runtime: automatic react runtime 1`] = ` + +jest.mock('./App', () => () =>
Hello world
); + + ↓ ↓ ↓ ↓ ↓ ↓ + +_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"; +var _jsxFileName = ""; + +function _getJestObj() { + const { jest } = require("@jest/globals"); + + _getJestObj = () => jest; + + return jest; +} + + +`; + exports[`babel-plugin-jest-hoist top level mocking: top level mocking 1`] = ` require('x'); 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 a2a7fead5459..70a47f154a47 100644 --- a/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts +++ b/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts @@ -23,7 +23,7 @@ pluginTester({ ], }, code: ` - jest.mock('./App', () => () =>
Hello world
, {virtual: true}); + jest.mock('./App', () => () =>
Hello world
); `, snapshot: true, }, diff --git a/packages/babel-plugin-jest-hoist/src/index.ts b/packages/babel-plugin-jest-hoist/src/index.ts index 15e2c5bf5ae7..28c2b07819d5 100644 --- a/packages/babel-plugin-jest-hoist/src/index.ts +++ b/packages/babel-plugin-jest-hoist/src/index.ts @@ -120,41 +120,45 @@ FUNCTIONS.mock = args => { moduleFactory.traverse(IDVisitor, {ids}); for (const id of ids) { const {name} = id.node; - let found = false; let scope = id.scope; while (scope !== parentScope) { if (scope.bindings[name]) { - found = true; - break; + return true; } scope = scope.parent; } - if (!found) { - const isAllowedIdentifier = - (scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name)) || - /^mock/i.test(name) || - // Allow istanbul's coverage variable to pass. - /^(?:__)?cov/.test(name); - - if (!isAllowedIdentifier) { - throw id.buildCodeFrameError( - 'The module factory of `jest.mock()` is not allowed to ' + - 'reference any out-of-scope variables.\n' + - 'Invalid variable access: ' + - name + - '\n' + - 'Allowed objects: ' + - Array.from(ALLOWED_IDENTIFIERS).join(', ') + - '.\n' + - 'Note: This is a precaution to guard against uninitialized mock ' + - 'variables. If it is ensured that the mock is required lazily, ' + - 'variable names prefixed with `mock` (case insensitive) are permitted.\n', - ReferenceError, - ); - } + const binding = scope.bindings[name]; + + // @ts-expect-error `init` does not exist + if (binding?.constant && scope.isPure(binding.path.node.init, true)) { + // how to hoist??? + return true; + } + + const isAllowedIdentifier = + (scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name)) || + /^mock/i.test(name) || + // Allow istanbul's coverage variable to pass. + /^(?:__)?cov/.test(name); + + if (!isAllowedIdentifier) { + throw id.buildCodeFrameError( + 'The module factory of `jest.mock()` is not allowed to ' + + 'reference any out-of-scope variables.\n' + + 'Invalid variable access: ' + + name + + '\n' + + 'Allowed objects: ' + + Array.from(ALLOWED_IDENTIFIERS).join(', ') + + '.\n' + + 'Note: This is a precaution to guard against uninitialized mock ' + + 'variables. If it is ensured that the mock is required lazily, ' + + 'variable names prefixed with `mock` (case insensitive) are permitted.\n', + ReferenceError, + ); } }