Skip to content

Commit 0fbbc00

Browse files
authoredFeb 5, 2020
fix(transformer): add deepUnmock to hoist method list (#1372)
* fix(transformers): add deepUnmock to hoist methods * fix(transformers): add deepUnmock to hoist methods
1 parent 23f676c commit 0fbbc00

File tree

11 files changed

+644
-217
lines changed

11 files changed

+644
-217
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import hello from './disable-automock'
2+
3+
jest.disableAutomock()
4+
5+
test('original implementation', () => {
6+
// now we have the original implementation,
7+
// even if we set the automocking in a jest configuration
8+
expect(hello()).toBe('hi!')
9+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function() {
2+
return 'hi!'
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
jest.enableAutomock()
2+
3+
import hello from './enable-automock'
4+
5+
test('original implementation', () => {
6+
// now we have the mocked implementation,
7+
// @ts-ignore
8+
expect(hello._isMockFunction).toBeTruthy()
9+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function() {
2+
return 'hi!'
3+
}

‎e2e/__cases__/hoisting/hello.spec.ts

-21
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import hello from './mock-unmock'
2+
3+
jest.mock('./mock-unmock')
4+
5+
const original = jest.requireActual('./mock-unmock').default
6+
it('should have been mocked', () => {
7+
const msg = hello()
8+
expect(hello).not.toBe(original)
9+
expect(msg).toBeUndefined()
10+
expect(hello).toHaveProperty('mock')
11+
expect(require('foo')).toBe('bar')
12+
jest.mock('foo', () => 'bar', { virtual: true })
13+
})

‎e2e/__tests__/__snapshots__/hoisting.test.ts.snap

+540-182
Large diffs are not rendered by default.

‎e2e/__tests__/hoisting.test.ts

+36-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,47 @@ import { allValidPackageSets } from '../__helpers__/templates'
22
import { configureTestCase } from '../__helpers__/test-case'
33

44
describe('Hoisting jest.mock() & jest.unmock()', () => {
5-
const testCase = configureTestCase('hoisting', { writeIo: true })
5+
const testCase = configureTestCase('hoisting/mock-unmock', {
6+
writeIo: true,
7+
})
8+
9+
testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
10+
it(testLabel, () => {
11+
const result = runTest()
12+
expect(result.status).toBe(0)
13+
expect(result).toMatchSnapshot('output-mockUnmock')
14+
expect(result.ioFor('mock-unmock.spec.ts')).toMatchSnapshot('io-mockUnmock')
15+
})
16+
})
17+
})
18+
19+
describe('Hoisting jest.enableAutomock()', () => {
20+
const testCase = configureTestCase('hoisting/enable-automock', { writeIo: true })
21+
22+
testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
23+
it(testLabel, () => {
24+
const result = runTest()
25+
expect(result.status).toBe(0)
26+
expect(result).toMatchSnapshot('output-enableAutomock')
27+
expect(result.ioFor('enable-automock.spec.ts')).toMatchSnapshot('io-enableAutomock')
28+
})
29+
})
30+
})
31+
32+
describe('Hoisting jest.disableAutomock()', () => {
33+
const testCase = configureTestCase('hoisting/disable-automock', {
34+
writeIo: true,
35+
jestConfig: {
36+
automock: true,
37+
}
38+
})
639

740
testCase.runWithTemplates(allValidPackageSets, 0, (runTest, { testLabel }) => {
841
it(testLabel, () => {
942
const result = runTest()
1043
expect(result.status).toBe(0)
11-
expect(result).toMatchSnapshot('output')
12-
expect(result.ioFor('hello.spec.ts')).toMatchSnapshot('io')
44+
expect(result).toMatchSnapshot('output-disableAutomock')
45+
expect(result.ioFor('disable-automock.spec.ts')).toMatchSnapshot('io-disableAutomock')
1346
})
1447
})
1548
})

‎src/transformers/hoist-jest.spec.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ jest.enableAutomock()
1010
jest.disableAutomock()
1111
jest.mock('./foo')
1212
jest.mock('./foo/bar', () => 'bar')
13+
jest.unmock('./bar/foo').dontMock('./bar/bar')
14+
jest.deepUnmock('./foo')
15+
jest.mock('./foo').mock('./bar')
1316
const func = () => {
1417
const bar = 'bar'
1518
console.log(bar)
1619
jest.unmock('./foo')
1720
jest.mock('./bar')
1821
jest.mock('./bar/foo', () => 'foo')
1922
jest.unmock('./foo/bar')
23+
jest.unmock('./bar/foo').dontMock('./bar/bar')
24+
jest.deepUnmock('./bar')
25+
jest.mock('./foo').mock('./bar')
2026
}
2127
const func2 = () => {
2228
const bar = 'bar'
@@ -25,6 +31,9 @@ const func2 = () => {
2531
jest.unmock('./foo/bar')
2632
jest.mock('./bar/foo', () => 'foo')
2733
jest.unmock('./foo')
34+
jest.unmock('./bar/foo').dontMock('./bar/bar')
35+
jest.deepUnmock('./bar')
36+
jest.mock('./foo').mock('./bar')
2837
}
2938
`
3039
const logger = testing.createLoggerMock()
@@ -41,30 +50,39 @@ describe('hoisting', () => {
4150
expect(typeof hoist.factory).toBe('function')
4251
})
4352

44-
it('should hoist jest mock() and unmock() statements', () => {
53+
it('should hoist jest.mock(), unmock(), disableAutomock() and enableAutomock()', () => {
4554
const out = transpile(CODE_WITH_HOISTING)
4655
expect(out.outputText).toMatchInlineSnapshot(`
4756
"jest.enableAutomock();
4857
jest.disableAutomock();
4958
jest.mock('./foo');
5059
jest.mock('./foo/bar', function () { return 'bar'; });
60+
jest.deepUnmock('./foo');
61+
jest.mock('./foo').mock('./bar');
5162
var foo = 'foo';
5263
console.log(foo);
64+
jest.unmock('./bar/foo').dontMock('./bar/bar');
5365
var func = function () {
5466
jest.unmock('./foo');
5567
jest.mock('./bar');
5668
jest.mock('./bar/foo', function () { return 'foo'; });
5769
jest.unmock('./foo/bar');
70+
jest.deepUnmock('./bar');
71+
jest.mock('./foo').mock('./bar');
5872
var bar = 'bar';
5973
console.log(bar);
74+
jest.unmock('./bar/foo').dontMock('./bar/bar');
6075
};
6176
var func2 = function () {
6277
jest.mock('./bar');
6378
jest.unmock('./foo/bar');
6479
jest.mock('./bar/foo', function () { return 'foo'; });
6580
jest.unmock('./foo');
81+
jest.deepUnmock('./bar');
82+
jest.mock('./foo').mock('./bar');
6683
var bar = 'bar';
6784
console.log(bar);
85+
jest.unmock('./bar/foo').dontMock('./bar/bar');
6886
};
6987
"
7088
`)

‎src/transformers/hoist-jest.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ConfigSet } from '../config/config-set'
1717
/**
1818
* What methods of `jest` should we hoist
1919
*/
20-
const HOIST_METHODS = ['mock', 'unmock', 'enableAutomock', 'disableAutomock']
20+
const HOIST_METHODS = ['mock', 'unmock', 'enableAutomock', 'disableAutomock', 'deepUnmock']
2121

2222
/**
2323
* @internal
@@ -41,20 +41,22 @@ export function factory(cs: ConfigSet) {
4141
*/
4242
const ts = cs.compilerModule
4343

44+
function shouldHoistExpression(expression: Node): boolean {
45+
return (
46+
ts.isCallExpression(expression) &&
47+
ts.isPropertyAccessExpression(expression.expression) &&
48+
HOIST_METHODS.includes(expression.expression.name.text) &&
49+
((ts.isIdentifier(expression.expression.expression) && expression.expression.expression.text === 'jest') ||
50+
shouldHoistExpression(expression.expression.expression))
51+
)
52+
}
53+
4454
/**
4555
* Checks whether given node is a statement that we need to hoist
4656
* @param node The node to test
4757
*/
4858
function shouldHoistNode(node: Node): node is ExpressionStatement {
49-
return (
50-
ts.isExpressionStatement(node) &&
51-
ts.isCallExpression(node.expression) &&
52-
ts.isPropertyAccessExpression(node.expression.expression) &&
53-
ts.isIdentifier(node.expression.expression.expression) &&
54-
node.expression.expression.expression.text === 'jest' &&
55-
ts.isIdentifier(node.expression.expression.name) &&
56-
HOIST_METHODS.includes(node.expression.expression.name.text)
57-
)
59+
return ts.isExpressionStatement(node) && shouldHoistExpression(node.expression)
5860
}
5961

6062
/**

0 commit comments

Comments
 (0)
Please sign in to comment.