Skip to content

Commit

Permalink
refactor(ast-utils): migrate custom node-utils to ASTUtils (#256)
Browse files Browse the repository at this point in the history
Closes #253 

* refactor(ast-utils): remove isIdentifier

* refactor(ast-utils): migrate isAwaitExpression

* refactor(ast-utils): use optional chaining for consistency
  • Loading branch information
Thomas Lombart authored Nov 17, 2020
1 parent 6018dd1 commit ae3eac7
Show file tree
Hide file tree
Showing 19 changed files with 155 additions and 120 deletions.
45 changes: 17 additions & 28 deletions lib/node-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@ export function isCallExpression(
export function isNewExpression(
node: TSESTree.Node
): node is TSESTree.NewExpression {
return node && node.type === 'NewExpression';
}

// TODO: remove this one and use ASTUtils one instead
export function isIdentifier(node: TSESTree.Node): node is TSESTree.Identifier {
return node && node.type === AST_NODE_TYPES.Identifier;
return node?.type === 'NewExpression';
}

export function isMemberExpression(
node: TSESTree.Node
): node is TSESTree.MemberExpression {
return node && node.type === AST_NODE_TYPES.MemberExpression;
return node?.type === AST_NODE_TYPES.MemberExpression;
}

export function isLiteral(
Expand All @@ -38,7 +33,7 @@ export function isLiteral(
export function isImportSpecifier(
node: TSESTree.Node
): node is TSESTree.ImportSpecifier {
return node && node.type === AST_NODE_TYPES.ImportSpecifier;
return node?.type === AST_NODE_TYPES.ImportSpecifier;
}

export function isImportNamespaceSpecifier(
Expand All @@ -50,25 +45,25 @@ export function isImportNamespaceSpecifier(
export function isImportDefaultSpecifier(
node: TSESTree.Node
): node is TSESTree.ImportDefaultSpecifier {
return node && node.type === AST_NODE_TYPES.ImportDefaultSpecifier;
return node?.type === AST_NODE_TYPES.ImportDefaultSpecifier;
}

export function isBlockStatement(
node: TSESTree.Node
): node is TSESTree.BlockStatement {
return node && node.type === AST_NODE_TYPES.BlockStatement;
return node?.type === AST_NODE_TYPES.BlockStatement;
}

export function isVariableDeclarator(
node: TSESTree.Node
): node is TSESTree.VariableDeclarator {
return node && node.type === AST_NODE_TYPES.VariableDeclarator;
return node?.type === AST_NODE_TYPES.VariableDeclarator;
}

export function isObjectPattern(
node: TSESTree.Node
): node is TSESTree.ObjectPattern {
return node && node.type === AST_NODE_TYPES.ObjectPattern;
return node?.type === AST_NODE_TYPES.ObjectPattern;
}

export function isProperty(
Expand All @@ -80,7 +75,7 @@ export function isProperty(
export function isJSXAttribute(
node: TSESTree.Node
): node is TSESTree.JSXAttribute {
return node && node.type === AST_NODE_TYPES.JSXAttribute;
return node?.type === AST_NODE_TYPES.JSXAttribute;
}

export function findClosestCallExpressionNode(
Expand All @@ -107,7 +102,7 @@ export function findClosestCallNode(

if (
isCallExpression(node) &&
isIdentifier(node.callee) &&
ASTUtils.isIdentifier(node.callee) &&
node.callee.name === name
) {
return node;
Expand All @@ -125,28 +120,21 @@ export function isObjectExpression(
export function hasThenProperty(node: TSESTree.Node): boolean {
return (
isMemberExpression(node) &&
isIdentifier(node.property) &&
ASTUtils.isIdentifier(node.property) &&
node.property.name === 'then'
);
}

// TODO: remove this one and use ASTUtils one instead
export function isAwaitExpression(
node: TSESTree.Node
): node is TSESTree.AwaitExpression {
return node && node.type === AST_NODE_TYPES.AwaitExpression;
}

export function isArrowFunctionExpression(
node: TSESTree.Node
): node is TSESTree.ArrowFunctionExpression {
return node && node.type === AST_NODE_TYPES.ArrowFunctionExpression;
return node?.type === AST_NODE_TYPES.ArrowFunctionExpression;
}

export function isReturnStatement(
node: TSESTree.Node
): node is TSESTree.ReturnStatement {
return node && node.type === AST_NODE_TYPES.ReturnStatement;
return node?.type === AST_NODE_TYPES.ReturnStatement;
}

export function isArrayExpression(
Expand All @@ -163,7 +151,7 @@ export function isImportDeclaration(

export function isAwaited(node: TSESTree.Node): boolean {
return (
isAwaitExpression(node) ||
ASTUtils.isAwaitExpression(node) ||
isArrowFunctionExpression(node) ||
isReturnStatement(node)
);
Expand Down Expand Up @@ -200,9 +188,10 @@ export function isRenderFunction(
// as well as `someLib.render` and `someUtils.customRenderFn`
return renderFunctions.some((name) => {
return (
(isIdentifier(callNode.callee) && name === callNode.callee.name) ||
(ASTUtils.isIdentifier(callNode.callee) &&
name === callNode.callee.name) ||
(isMemberExpression(callNode.callee) &&
isIdentifier(callNode.callee.property) &&
ASTUtils.isIdentifier(callNode.callee.property) &&
name === callNode.callee.property.name)
);
});
Expand All @@ -213,7 +202,7 @@ export function isRenderVariableDeclarator(
renderFunctions: string[]
): boolean {
if (node.init) {
if (isAwaitExpression(node.init)) {
if (ASTUtils.isAwaitExpression(node.init)) {
return (
node.init.argument &&
isRenderFunction(
Expand Down
11 changes: 7 additions & 4 deletions lib/rules/await-async-query.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';
import { getDocsUrl, LIBRARY_MODULES } from '../utils';
import {
isCallExpression,
isIdentifier,
isMemberExpression,
isAwaited,
isPromiseResolved,
Expand All @@ -23,13 +26,13 @@ function hasClosestExpectResolvesRejects(node: TSESTree.Node): boolean {

if (
isCallExpression(node) &&
isIdentifier(node.callee) &&
ASTUtils.isIdentifier(node.callee) &&
isMemberExpression(node.parent) &&
node.callee.name === 'expect'
) {
const expectMatcher = node.parent.property;
return (
isIdentifier(expectMatcher) &&
ASTUtils.isIdentifier(expectMatcher) &&
(expectMatcher.name === 'resolves' || expectMatcher.name === 'rejects')
);
} else {
Expand Down
11 changes: 7 additions & 4 deletions lib/rules/await-async-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';

import { getDocsUrl, ASYNC_UTILS, LIBRARY_MODULES } from '../utils';
import {
Expand All @@ -10,7 +14,6 @@ import {
isImportNamespaceSpecifier,
isCallExpression,
isArrayExpression,
isIdentifier,
} from '../node-utils';

export const RULE_NAME = 'await-async-utils';
Expand All @@ -23,9 +26,9 @@ const ASYNC_UTILS_REGEXP = new RegExp(`^(${ASYNC_UTILS.join('|')})$`);
function isPromiseAll(node: TSESTree.CallExpression) {
return (
isMemberExpression(node.callee) &&
isIdentifier(node.callee.object) &&
ASTUtils.isIdentifier(node.callee.object) &&
node.callee.object.name === 'Promise' &&
isIdentifier(node.callee.property) &&
ASTUtils.isIdentifier(node.callee.property) &&
node.callee.property.name === 'all'
);
}
Expand Down
10 changes: 7 additions & 3 deletions lib/rules/await-fire-event.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';
import { getDocsUrl } from '../utils';
import { isIdentifier, isAwaited, isPromiseResolved } from '../node-utils';
import { isAwaited, isPromiseResolved } from '../node-utils';

export const RULE_NAME = 'await-fire-event';
export type MessageIds = 'awaitFireEvent';
Expand Down Expand Up @@ -31,7 +35,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
const fireEventMethodNode = memberExpression.property;

if (
isIdentifier(fireEventMethodNode) &&
ASTUtils.isIdentifier(fireEventMethodNode) &&
!isAwaited(node.parent.parent.parent) &&
!isPromiseResolved(fireEventMethodNode.parent)
) {
Expand Down
10 changes: 7 additions & 3 deletions lib/rules/no-await-sync-events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ASTUtils,
ESLintUtils,
TSESTree,
} from '@typescript-eslint/experimental-utils';
import { getDocsUrl, SYNC_EVENTS } from '../utils';
import { isObjectExpression, isProperty, isIdentifier } from '../node-utils';
import { isObjectExpression, isProperty } from '../node-utils';
export const RULE_NAME = 'no-await-sync-events';
export type MessageIds = 'noAwaitSyncEvents';
type Options = [];
Expand Down Expand Up @@ -41,7 +45,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
callExpression.arguments[2].properties.some(
(property) =>
isProperty(property) &&
isIdentifier(property.key) &&
ASTUtils.isIdentifier(property.key) &&
property.key.name === 'delay'
);

Expand Down
21 changes: 12 additions & 9 deletions lib/rules/no-container.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';
import { getDocsUrl } from '../utils';
import {
isIdentifier,
isMemberExpression,
isObjectPattern,
isProperty,
Expand Down Expand Up @@ -54,12 +57,12 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
innerNode: TSESTree.MemberExpression
) {
if (isMemberExpression(innerNode)) {
if (isIdentifier(innerNode.object)) {
if (ASTUtils.isIdentifier(innerNode.object)) {
const isContainerName = innerNode.object.name === containerName;
const isRenderWrapper = innerNode.object.name === renderWrapperName;

containerCallsMethod =
isIdentifier(innerNode.property) &&
ASTUtils.isIdentifier(innerNode.property) &&
innerNode.property.name === 'container' &&
isRenderWrapper;

Expand All @@ -83,24 +86,24 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
const containerIndex = node.id.properties.findIndex(
(property) =>
isProperty(property) &&
isIdentifier(property.key) &&
ASTUtils.isIdentifier(property.key) &&
property.key.name === 'container'
);
const nodeValue =
containerIndex !== -1 && node.id.properties[containerIndex].value;
if (isIdentifier(nodeValue)) {
if (ASTUtils.isIdentifier(nodeValue)) {
containerName = nodeValue.name;
} else {
isObjectPattern(nodeValue) &&
nodeValue.properties.forEach(
(property) =>
isProperty(property) &&
isIdentifier(property.key) &&
ASTUtils.isIdentifier(property.key) &&
destructuredContainerPropNames.push(property.key.name)
);
}
} else {
renderWrapperName = isIdentifier(node.id) && node.id.name;
renderWrapperName = ASTUtils.isIdentifier(node.id) && node.id.name;
}
}
},
Expand All @@ -109,7 +112,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
if (isMemberExpression(node.callee)) {
showErrorIfChainedContainerMethod(node.callee);
} else {
isIdentifier(node.callee) &&
ASTUtils.isIdentifier(node.callee) &&
destructuredContainerPropNames.includes(node.callee.name) &&
context.report({
node,
Expand Down
13 changes: 8 additions & 5 deletions lib/rules/no-debug.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';
import {
getDocsUrl,
LIBRARY_MODULES,
Expand All @@ -7,7 +11,6 @@ import {
import {
isObjectPattern,
isProperty,
isIdentifier,
isCallExpression,
isLiteral,
isMemberExpression,
Expand Down Expand Up @@ -66,7 +69,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
node.id.properties.some(
(property) =>
isProperty(property) &&
isIdentifier(property.key) &&
ASTUtils.isIdentifier(property.key) &&
property.key.name === 'debug'
)
) {
Expand Down Expand Up @@ -102,7 +105,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
declaratorNode.id.properties.some(
(property) =>
isProperty(property) &&
isIdentifier(property.key) &&
ASTUtils.isIdentifier(property.key) &&
property.key.name === 'screen'
);
},
Expand Down Expand Up @@ -179,7 +182,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
const parent = ref.identifier.parent;
if (
isMemberExpression(parent) &&
isIdentifier(parent.property) &&
ASTUtils.isIdentifier(parent.property) &&
parent.property.name === 'debug' &&
isCallExpression(parent.parent)
) {
Expand Down
9 changes: 6 additions & 3 deletions lib/rules/no-multiple-assertions-wait-for.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import {
ESLintUtils,
TSESTree,
ASTUtils,
} from '@typescript-eslint/experimental-utils';
import { getDocsUrl } from '../utils';
import {
isBlockStatement,
isMemberExpression,
isCallExpression,
isIdentifier,
} from '../node-utils';

export const RULE_NAME = 'no-multiple-assertions-wait-for';
Expand Down Expand Up @@ -42,7 +45,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
const object: TSESTree.CallExpression =
node.expression.callee.object;
const expressionName: string =
isIdentifier(object.callee) && object.callee.name;
ASTUtils.isIdentifier(object.callee) && object.callee.name;
return expressionName === 'expect';
} else {
return false;
Expand Down
5 changes: 2 additions & 3 deletions lib/rules/no-node-access.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { TSESTree } from '@typescript-eslint/experimental-utils';
import { TSESTree, ASTUtils } from '@typescript-eslint/experimental-utils';
import { ALL_RETURNING_NODES } from '../utils';
import { isIdentifier } from '../node-utils';
import { createTestingLibraryRule } from '../create-testing-library-rule';

export const RULE_NAME = 'no-node-access';
Expand All @@ -27,7 +26,7 @@ export default createTestingLibraryRule<Options, MessageIds>({

create(context) {
function showErrorForNodeAccess(node: TSESTree.MemberExpression) {
isIdentifier(node.property) &&
ASTUtils.isIdentifier(node.property) &&
ALL_RETURNING_NODES.includes(node.property.name) &&
context.report({
node: node,
Expand Down
Loading

0 comments on commit ae3eac7

Please sign in to comment.