Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import hello from './disable-automock'

jest.disableAutomock()

test('original implementation', () => {
// now we have the original implementation,
// even if we set the automocking in a jest configuration
expect(hello()).toBe('hi!')
})
3 changes: 3 additions & 0 deletions e2e/__cases__/hoisting/disable-automock/disable-automock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function() {
return 'hi!'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
jest.enableAutomock()

import hello from './enable-automock'

test('original implementation', () => {
// now we have the mocked implementation,
// @ts-ignore
expect(hello._isMockFunction).toBeTruthy()
})
3 changes: 3 additions & 0 deletions e2e/__cases__/hoisting/enable-automock/enable-automock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function() {
return 'hi!'
}
21 changes: 0 additions & 21 deletions e2e/__cases__/hoisting/hello.spec.ts

This file was deleted.

13 changes: 13 additions & 0 deletions e2e/__cases__/hoisting/mock-unmock/mock-unmock.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import hello from './mock-unmock'

jest.mock('./mock-unmock')

const original = jest.requireActual('./mock-unmock').default
it('should have been mocked', () => {
const msg = hello()
expect(hello).not.toBe(original)
expect(msg).toBeUndefined()
expect(hello).toHaveProperty('mock')
expect(require('foo')).toBe('bar')
jest.mock('foo', () => 'bar', { virtual: true })
})
722 changes: 540 additions & 182 deletions e2e/__tests__/__snapshots__/hoisting.test.ts.snap

Large diffs are not rendered by default.

39 changes: 36 additions & 3 deletions e2e/__tests__/hoisting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,47 @@ import { allValidPackageSets } from '../__helpers__/templates'
import { configureTestCase } from '../__helpers__/test-case'

describe('Hoisting jest.mock() & jest.unmock()', () => {
const testCase = configureTestCase('hoisting', { writeIo: true })
const testCase = configureTestCase('hoisting/mock-unmock', {
writeIo: true,
})

testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
it(testLabel, () => {
const result = runTest()
expect(result.status).toBe(0)
expect(result).toMatchSnapshot('output-mockUnmock')
expect(result.ioFor('mock-unmock.spec.ts')).toMatchSnapshot('io-mockUnmock')
})
})
})

describe('Hoisting jest.enableAutomock()', () => {
const testCase = configureTestCase('hoisting/enable-automock', { writeIo: true })

testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
it(testLabel, () => {
const result = runTest()
expect(result.status).toBe(0)
expect(result).toMatchSnapshot('output-enableAutomock')
expect(result.ioFor('enable-automock.spec.ts')).toMatchSnapshot('io-enableAutomock')
})
})
})

describe('Hoisting jest.disableAutomock()', () => {
const testCase = configureTestCase('hoisting/disable-automock', {
writeIo: true,
jestConfig: {
automock: true,
}
})

testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
it(testLabel, () => {
const result = runTest()
expect(result.status).toBe(0)
expect(result).toMatchSnapshot('output')
expect(result.ioFor('hello.spec.ts')).toMatchSnapshot('io')
expect(result).toMatchSnapshot('output-disableAutomock')
expect(result.ioFor('disable-automock.spec.ts')).toMatchSnapshot('io-disableAutomock')
})
})
})
20 changes: 19 additions & 1 deletion src/transformers/hoist-jest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ jest.enableAutomock()
jest.disableAutomock()
jest.mock('./foo')
jest.mock('./foo/bar', () => 'bar')
jest.unmock('./bar/foo').dontMock('./bar/bar')
jest.deepUnmock('./foo')
jest.mock('./foo').mock('./bar')
const func = () => {
const bar = 'bar'
console.log(bar)
jest.unmock('./foo')
jest.mock('./bar')
jest.mock('./bar/foo', () => 'foo')
jest.unmock('./foo/bar')
jest.unmock('./bar/foo').dontMock('./bar/bar')
jest.deepUnmock('./bar')
jest.mock('./foo').mock('./bar')
}
const func2 = () => {
const bar = 'bar'
Expand All @@ -25,6 +31,9 @@ const func2 = () => {
jest.unmock('./foo/bar')
jest.mock('./bar/foo', () => 'foo')
jest.unmock('./foo')
jest.unmock('./bar/foo').dontMock('./bar/bar')
jest.deepUnmock('./bar')
jest.mock('./foo').mock('./bar')
}
`
const logger = testing.createLoggerMock()
Expand All @@ -41,30 +50,39 @@ describe('hoisting', () => {
expect(typeof hoist.factory).toBe('function')
})

it('should hoist jest mock() and unmock() statements', () => {
it('should hoist jest.mock(), unmock(), disableAutomock() and enableAutomock()', () => {
const out = transpile(CODE_WITH_HOISTING)
expect(out.outputText).toMatchInlineSnapshot(`
"jest.enableAutomock();
jest.disableAutomock();
jest.mock('./foo');
jest.mock('./foo/bar', function () { return 'bar'; });
jest.deepUnmock('./foo');
jest.mock('./foo').mock('./bar');
var foo = 'foo';
console.log(foo);
jest.unmock('./bar/foo').dontMock('./bar/bar');
var func = function () {
jest.unmock('./foo');
jest.mock('./bar');
jest.mock('./bar/foo', function () { return 'foo'; });
jest.unmock('./foo/bar');
jest.deepUnmock('./bar');
jest.mock('./foo').mock('./bar');
var bar = 'bar';
console.log(bar);
jest.unmock('./bar/foo').dontMock('./bar/bar');
};
var func2 = function () {
jest.mock('./bar');
jest.unmock('./foo/bar');
jest.mock('./bar/foo', function () { return 'foo'; });
jest.unmock('./foo');
jest.deepUnmock('./bar');
jest.mock('./foo').mock('./bar');
var bar = 'bar';
console.log(bar);
jest.unmock('./bar/foo').dontMock('./bar/bar');
};
"
`)
Expand Down
22 changes: 12 additions & 10 deletions src/transformers/hoist-jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ConfigSet } from '../config/config-set'
/**
* What methods of `jest` should we hoist
*/
const HOIST_METHODS = ['mock', 'unmock', 'enableAutomock', 'disableAutomock']
const HOIST_METHODS = ['mock', 'unmock', 'enableAutomock', 'disableAutomock', 'deepUnmock']

/**
* @internal
Expand All @@ -41,20 +41,22 @@ export function factory(cs: ConfigSet) {
*/
const ts = cs.compilerModule

function shouldHoistExpression(expression: Node): boolean {
return (
ts.isCallExpression(expression) &&
ts.isPropertyAccessExpression(expression.expression) &&
HOIST_METHODS.includes(expression.expression.name.text) &&
((ts.isIdentifier(expression.expression.expression) && expression.expression.expression.text === 'jest') ||
shouldHoistExpression(expression.expression.expression))
)
}

/**
* Checks whether given node is a statement that we need to hoist
* @param node The node to test
*/
function shouldHoistNode(node: Node): node is ExpressionStatement {
return (
ts.isExpressionStatement(node) &&
ts.isCallExpression(node.expression) &&
ts.isPropertyAccessExpression(node.expression.expression) &&
ts.isIdentifier(node.expression.expression.expression) &&
node.expression.expression.expression.text === 'jest' &&
ts.isIdentifier(node.expression.expression.name) &&
HOIST_METHODS.includes(node.expression.expression.name.text)
)
return ts.isExpressionStatement(node) && shouldHoistExpression(node.expression)
}

/**
Expand Down