-
Notifications
You must be signed in to change notification settings - Fork 148
Move rules settings to ESLint shared config: part 6 - refactor no-manual-cleanup rule #249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7db6f18
dac0e91
fcf1452
9e48245
8641739
0dd98b8
9e77544
07c0be2
ab35358
50a3cef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,9 @@ import { | |
import { RuleContext } from '@typescript-eslint/experimental-utils/dist/ts-eslint'; | ||
|
||
export function isCallExpression( | ||
node: TSESTree.Node | ||
node: TSESTree.Node | null | undefined | ||
): node is TSESTree.CallExpression { | ||
return node && node.type === AST_NODE_TYPES.CallExpression; | ||
return node?.type === AST_NODE_TYPES.CallExpression; | ||
} | ||
|
||
export function isNewExpression( | ||
|
@@ -17,6 +17,7 @@ export function isNewExpression( | |
return node && node.type === 'NewExpression'; | ||
} | ||
|
||
// TODO: remove this one and use ASTUtils one instead | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧐 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh man, I saw your |
||
export function isIdentifier(node: TSESTree.Node): node is TSESTree.Identifier { | ||
return node && node.type === AST_NODE_TYPES.Identifier; | ||
} | ||
|
@@ -69,8 +70,10 @@ export function isObjectPattern( | |
return node && node.type === AST_NODE_TYPES.ObjectPattern; | ||
} | ||
|
||
export function isProperty(node: TSESTree.Node): node is TSESTree.Property { | ||
return node && node.type === AST_NODE_TYPES.Property; | ||
export function isProperty( | ||
node: TSESTree.Node | null | undefined | ||
): node is TSESTree.Property { | ||
return node?.type === AST_NODE_TYPES.Property; | ||
} | ||
|
||
export function isJSXAttribute( | ||
|
@@ -126,6 +129,7 @@ export function hasThenProperty(node: TSESTree.Node): boolean { | |
); | ||
} | ||
|
||
// TODO: remove this one and use ASTUtils one instead | ||
export function isAwaitExpression( | ||
node: TSESTree.Node | ||
): node is TSESTree.AwaitExpression { | ||
|
@@ -150,6 +154,12 @@ export function isArrayExpression( | |
return node?.type === AST_NODE_TYPES.ArrayExpression; | ||
} | ||
|
||
export function isImportDeclaration( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added util for knowing if a node is ImportDeclaration 👍 |
||
node: TSESTree.Node | null | undefined | ||
): node is TSESTree.ImportDeclaration { | ||
return node?.type === AST_NODE_TYPES.ImportDeclaration; | ||
} | ||
|
||
export function isAwaited(node: TSESTree.Node): boolean { | ||
return ( | ||
isAwaitExpression(node) || | ||
|
@@ -176,7 +186,7 @@ export function getVariableReferences( | |
): TSESLint.Scope.Reference[] { | ||
return ( | ||
(isVariableDeclarator(node) && | ||
context.getDeclaredVariables(node)[0].references.slice(1)) || | ||
context.getDeclaredVariables(node)[0]?.references?.slice(1)) || | ||
[] | ||
); | ||
} | ||
|
@@ -220,3 +230,26 @@ export function isRenderVariableDeclarator( | |
|
||
return false; | ||
} | ||
|
||
// TODO: extract into types file? | ||
export type ImportModuleNode = | ||
| TSESTree.ImportDeclaration | ||
| TSESTree.CallExpression; | ||
|
||
export function getImportModuleName( | ||
node: ImportModuleNode | undefined | null | ||
): string | undefined { | ||
// import node of shape: import { foo } from 'bar' | ||
if (isImportDeclaration(node) && typeof node.source.value === 'string') { | ||
return node.source.value; | ||
} | ||
|
||
// import node of shape: const { foo } = require('bar') | ||
if ( | ||
isCallExpression(node) && | ||
isLiteral(node.arguments[0]) && | ||
typeof node.arguments[0].value === 'string' | ||
) { | ||
return node.arguments[0].value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,6 @@ | ||
import { | ||
AST_NODE_TYPES, | ||
TSESTree, | ||
} from '@typescript-eslint/experimental-utils'; | ||
import { isIdentifier, isLiteral } from '../node-utils'; | ||
import { TSESTree } from '@typescript-eslint/experimental-utils'; | ||
import { createTestingLibraryRule } from '../create-testing-library-rule'; | ||
import { isCallExpression } from '../node-utils'; | ||
|
||
export const RULE_NAME = 'no-dom-import'; | ||
export type MessageIds = 'noDomImport' | 'noDomImportFramework'; | ||
|
@@ -40,11 +37,10 @@ export default createTestingLibraryRule<Options, MessageIds>({ | |
|
||
create(context, [framework], helpers) { | ||
function report( | ||
node: TSESTree.ImportDeclaration | TSESTree.Identifier, | ||
node: TSESTree.ImportDeclaration | TSESTree.CallExpression, | ||
moduleName: string | ||
) { | ||
if (framework) { | ||
const isRequire = isIdentifier(node) && node.name === 'require'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. small doubt here: I guess some of the rules had support for require, but that only applied to a few. Are we dropping the support for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup in this case the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh ups nevermind, I saw the helpers consider require as well, great! 🚀 you're one step ahead There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I should have pointed this with a comment on this PR. But yest, I basically extracted the imported module checks from this rule (which were the best ones) into detection helpers. So now all refactores rules automatically getting the imports from either |
||
const correctModuleName = moduleName.replace('dom', framework); | ||
context.report({ | ||
node, | ||
|
@@ -53,18 +49,16 @@ export default createTestingLibraryRule<Options, MessageIds>({ | |
module: correctModuleName, | ||
}, | ||
fix(fixer) { | ||
if (isRequire) { | ||
const callExpression = node.parent as TSESTree.CallExpression; | ||
const name = callExpression.arguments[0] as TSESTree.Literal; | ||
if (isCallExpression(node)) { | ||
const name = node.arguments[0] as TSESTree.Literal; | ||
|
||
// Replace the module name with the raw module name as we can't predict which punctuation the user is going to use | ||
return fixer.replaceText( | ||
name, | ||
name.raw.replace(moduleName, correctModuleName) | ||
); | ||
} else { | ||
const importDeclaration = node as TSESTree.ImportDeclaration; | ||
const name = importDeclaration.source; | ||
const name = node.source; | ||
return fixer.replaceText( | ||
name, | ||
name.raw.replace(moduleName, correctModuleName) | ||
|
@@ -82,36 +76,22 @@ export default createTestingLibraryRule<Options, MessageIds>({ | |
|
||
return { | ||
'Program:exit'() { | ||
const importName = helpers.getTestingLibraryImportName(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reusing the new helper in this rule already refactored. |
||
const importNode = helpers.getTestingLibraryImportNode(); | ||
|
||
if (!importNode) { | ||
return; | ||
} | ||
|
||
// import node of shape: import { foo } from 'bar' | ||
if (importNode.type === AST_NODE_TYPES.ImportDeclaration) { | ||
const domModuleName = DOM_TESTING_LIBRARY_MODULES.find( | ||
(module) => module === importNode.source.value | ||
); | ||
const domModuleName = DOM_TESTING_LIBRARY_MODULES.find( | ||
(module) => module === importName | ||
); | ||
|
||
domModuleName && report(importNode, domModuleName); | ||
if (!domModuleName) { | ||
return; | ||
} | ||
|
||
// import node of shape: const { foo } = require('bar') | ||
if (importNode.type === AST_NODE_TYPES.CallExpression) { | ||
const literalNodeDomModuleName = importNode.arguments.find( | ||
(arg) => | ||
isLiteral(arg) && | ||
typeof arg.value === 'string' && | ||
DOM_TESTING_LIBRARY_MODULES.includes(arg.value) | ||
) as TSESTree.Literal; | ||
|
||
literalNodeDomModuleName && | ||
report( | ||
importNode.callee as TSESTree.Identifier, | ||
literalNodeDomModuleName.value as string | ||
); | ||
} | ||
report(importNode, domModuleName); | ||
}, | ||
}; | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two new helpers to get the name of Testing Library or Custom Module imports 💪