Skip to content

Commit

Permalink
fix(prefer-spy-on): improve autofix (#1308)
Browse files Browse the repository at this point in the history
  • Loading branch information
FloEdelmann authored Dec 15, 2022
1 parent f33b19e commit 5d1b7a7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
33 changes: 33 additions & 0 deletions src/rules/__tests__/prefer-spy-on.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,38 @@ ruleTester.run('prefer-spy-on', rule, {
},
],
},
{
// https://github.com/jest-community/eslint-plugin-jest/issues/1304
code: 'foo[bar] = jest.fn().mockReturnValue(undefined)',
output:
'jest.spyOn(foo, bar).mockImplementation().mockReturnValue(undefined)',
errors: [
{
messageId: 'useJestSpyOn',
type: AST_NODE_TYPES.AssignmentExpression,
},
],
},
{
// https://github.com/jest-community/eslint-plugin-jest/issues/1307
code: `
foo.bar = jest.fn().mockImplementation(baz => baz)
foo.bar = jest.fn(a => b).mockImplementation(baz => baz)
`,
output: `
jest.spyOn(foo, 'bar').mockImplementation(baz => baz)
jest.spyOn(foo, 'bar').mockImplementation(baz => baz)
`,
errors: [
{
messageId: 'useJestSpyOn',
type: AST_NODE_TYPES.AssignmentExpression,
},
{
messageId: 'useJestSpyOn',
type: AST_NODE_TYPES.AssignmentExpression,
},
],
},
],
});
36 changes: 29 additions & 7 deletions src/rules/prefer-spy-on.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils';
import { createRule, getNodeName } from './utils';

const findNodeObject = (
Expand Down Expand Up @@ -39,6 +39,27 @@ const getJestFnCall = (node: TSESTree.Node): TSESTree.CallExpression | null => {
return getJestFnCall(obj);
};

const getAutoFixMockImplementation = (
jestFnCall: TSESTree.CallExpression,
context: TSESLint.RuleContext<'useJestSpyOn', unknown[]>,
): string => {
const hasMockImplementationAlready =
jestFnCall.parent?.type === AST_NODE_TYPES.MemberExpression &&
jestFnCall.parent.property.type === AST_NODE_TYPES.Identifier &&
jestFnCall.parent.property.name === 'mockImplementation';

if (hasMockImplementationAlready) {
return '';
}

const [arg] = jestFnCall.arguments;
const argSource = arg && context.getSourceCode().getText(arg);

return argSource
? `.mockImplementation(${argSource})`
: '.mockImplementation()';
};

export default createRule({
name: __filename,
meta: {
Expand Down Expand Up @@ -71,12 +92,13 @@ export default createRule({
messageId: 'useJestSpyOn',
fix(fixer) {
const leftPropQuote =
left.property.type === AST_NODE_TYPES.Identifier ? "'" : '';
const [arg] = jestFnCall.arguments;
const argSource = arg && context.getSourceCode().getText(arg);
const mockImplementation = argSource
? `.mockImplementation(${argSource})`
: '.mockImplementation()';
left.property.type === AST_NODE_TYPES.Identifier && !left.computed
? "'"
: '';
const mockImplementation = getAutoFixMockImplementation(
jestFnCall,
context,
);

return [
fixer.insertTextBefore(left, `jest.spyOn(`),
Expand Down

0 comments on commit 5d1b7a7

Please sign in to comment.