From 832a526bf2eab85abd94af478ce5693f13a200f0 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 11 Aug 2019 10:44:12 +1200 Subject: [PATCH 1/4] chore(no-identical-title): use `getAccessorValue` for things --- src/rules/tsUtils.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/rules/tsUtils.ts b/src/rules/tsUtils.ts index 87d1c8ceb..2cc4b6175 100644 --- a/src/rules/tsUtils.ts +++ b/src/rules/tsUtils.ts @@ -108,6 +108,41 @@ export const isStringNode = ( export const getStringValue = (node: StringNode): S => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value; +/** + * Represents a `MemberExpression` with a "known" `property`. + */ +interface KnownMemberExpression + extends TSESTree.MemberExpression { + property: AccessorNode; +} + +/** + * Represents a `CallExpression` with a "known" `property` accessor. + * + * i.e `KnownCallExpression<'includes'>` represents `.includes()`. + */ +export interface KnownCallExpression + extends TSESTree.CallExpression { + callee: CalledKnownMemberExpression; +} + +/** + * Represents a `MemberExpression` with a "known" `property`, that is called. + * + * This is `KnownCallExpression` from the perspective of the `MemberExpression` node. + */ +export interface CalledKnownMemberExpression + extends KnownMemberExpression { + parent: KnownCallExpression; +} + +/** + * An `Identifier` with a known `name` value - i.e `expect`. + */ +interface KnownIdentifier extends TSESTree.Identifier { + name: Name; +} + /** * Gets the value of the given `AccessorNode`, * account for the different node types. From 05b78609a0bb211e55b542bcc5fac45210800cd3 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 11 Aug 2019 11:44:51 +1200 Subject: [PATCH 2/4] chore(tsutils): remove unused interfaces --- src/rules/tsUtils.ts | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/src/rules/tsUtils.ts b/src/rules/tsUtils.ts index 2cc4b6175..87d1c8ceb 100644 --- a/src/rules/tsUtils.ts +++ b/src/rules/tsUtils.ts @@ -108,41 +108,6 @@ export const isStringNode = ( export const getStringValue = (node: StringNode): S => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value; -/** - * Represents a `MemberExpression` with a "known" `property`. - */ -interface KnownMemberExpression - extends TSESTree.MemberExpression { - property: AccessorNode; -} - -/** - * Represents a `CallExpression` with a "known" `property` accessor. - * - * i.e `KnownCallExpression<'includes'>` represents `.includes()`. - */ -export interface KnownCallExpression - extends TSESTree.CallExpression { - callee: CalledKnownMemberExpression; -} - -/** - * Represents a `MemberExpression` with a "known" `property`, that is called. - * - * This is `KnownCallExpression` from the perspective of the `MemberExpression` node. - */ -export interface CalledKnownMemberExpression - extends KnownMemberExpression { - parent: KnownCallExpression; -} - -/** - * An `Identifier` with a known `name` value - i.e `expect`. - */ -interface KnownIdentifier extends TSESTree.Identifier { - name: Name; -} - /** * Gets the value of the given `AccessorNode`, * account for the different node types. From 86f51ce1a1fa33ac23509106be64980e91365424 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 11 Aug 2019 16:23:17 +1200 Subject: [PATCH 3/4] chore(tsutils): create `hasOnlyOneArgument` utility guard --- src/rules/tsUtils.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/rules/tsUtils.ts b/src/rules/tsUtils.ts index 87d1c8ceb..4a8a5ff43 100644 --- a/src/rules/tsUtils.ts +++ b/src/rules/tsUtils.ts @@ -108,6 +108,27 @@ export const isStringNode = ( export const getStringValue = (node: StringNode): S => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value; +/** + * Represents a `CallExpression` with a single argument. + */ +export interface CallExpressionWithSingleArgument< + Argument extends TSESTree.Expression = TSESTree.Expression +> extends TSESTree.CallExpression { + arguments: [Argument]; +} + +/** + * Guards that the given `call` has only one `argument`. + * + * @param {CallExpression} call + * + * @return {call is CallExpressionWithSingleArgument} + */ +export const hasOnlyOneArgument = ( + call: TSESTree.CallExpression, +): call is CallExpressionWithSingleArgument => + call.arguments && call.arguments.length === 1; + /** * Gets the value of the given `AccessorNode`, * account for the different node types. From 24d07a3a7126d591b831da1b30543c681a53b1fe Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 11 Aug 2019 16:23:53 +1200 Subject: [PATCH 4/4] chore(prefer-todo): use `hasOnlyOneArgument` utility guard --- src/rules/prefer-todo.ts | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/rules/prefer-todo.ts b/src/rules/prefer-todo.ts index 829a14c41..2a7277b95 100644 --- a/src/rules/prefer-todo.ts +++ b/src/rules/prefer-todo.ts @@ -6,19 +6,15 @@ import { import { FunctionExpression, JestFunctionCallExpression, - StringLiteral, TestCaseName, createRule, getNodeName, + hasOnlyOneArgument, isFunction, isStringNode, isTestCase, } from './tsUtils'; -function isOnlyTestTitle(node: TSESTree.CallExpression) { - return node.arguments.length === 1; -} - function isFunctionBodyEmpty(node: FunctionExpression) { /* istanbul ignore next https://github.com/typescript-eslint/typescript-eslint/issues/734 */ if (!node.body) { @@ -49,16 +45,6 @@ function addTodo( return fixer.replaceText(node.callee, `${testName}.todo`); } -interface CallExpressionWithStringArgument extends TSESTree.CallExpression { - arguments: [StringLiteral | TSESTree.TemplateLiteral]; -} - -function isFirstArgString( - node: TSESTree.CallExpression, -): node is CallExpressionWithStringArgument { - return node.arguments[0] && isStringNode(node.arguments[0]); -} - const isTargetedTestCase = ( node: TSESTree.CallExpression, ): node is JestFunctionCallExpression => @@ -88,7 +74,9 @@ export default createRule({ create(context) { return { CallExpression(node) { - if (!isTargetedTestCase(node) || !isFirstArgString(node)) { + const [firstArg, secondArg] = node.arguments; + + if (!isTargetedTestCase(node) || !isStringNode(firstArg)) { return; } @@ -97,16 +85,13 @@ export default createRule({ messageId: 'todoOverEmpty', node, fix: fixer => [ - fixer.removeRange([ - node.arguments[0].range[1], - node.arguments[1].range[1], - ]), + fixer.removeRange([firstArg.range[1], secondArg.range[1]]), addTodo(node, fixer), ], }); } - if (isOnlyTestTitle(node)) { + if (hasOnlyOneArgument(node)) { context.report({ messageId: 'todoOverUnimplemented', node,