Skip to content

Commit

Permalink
feat(to-have-length): support optional chaining operator
Browse files Browse the repository at this point in the history
  • Loading branch information
hekystyle committed Nov 26, 2022
1 parent 53d348d commit 5303d3d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
8 changes: 7 additions & 1 deletion src/rules/__tests__/prefer-to-have-length.test.ts
Expand Up @@ -5,7 +5,7 @@ import { espreeParser } from './test-utils';
const ruleTester = new TSESLint.RuleTester({
parser: espreeParser,
parserOptions: {
ecmaVersion: 2015,
ecmaVersion: 2020,
},
});

Expand All @@ -16,6 +16,7 @@ ruleTester.run('prefer-to-have-length', rule, {
'expect(files).toHaveLength(1);',
"expect(files.name).toBe('file');",
"expect(files[`name`]).toBe('file');",
'expect(users[0]?.permissions).toHaveLength(1);',
'expect(result).toBe(true);',
`expect(user.getUserName(5)).resolves.toEqual('Paul')`,
`expect(user.getUserName(5)).rejects.toEqual('Paul')`,
Expand Down Expand Up @@ -74,5 +75,10 @@ ruleTester.run('prefer-to-have-length', rule, {
output: 'expect(files).not.toHaveLength(1);',
errors: [{ messageId: 'useToHaveLength', column: 26, line: 1 }],
},
{
code: 'expect(users[0]?.permissions?.length).toBe(1);',
output: 'expect(users[0]?.permissions).toHaveLength(1);',
errors: [{ messageId: 'useToHaveLength', column: 39, line: 1 }],
},
],
});
25 changes: 20 additions & 5 deletions src/rules/prefer-to-have-length.ts
@@ -1,4 +1,4 @@
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import {
EqualityMatcher,
createRule,
Expand All @@ -7,6 +7,13 @@ import {
parseJestFnCall,
} from './utils';

const followOptionalChaining = (
expression: TSESTree.CallExpressionArgument,
): TSESTree.CallExpressionArgument =>
expression.type === AST_NODE_TYPES.ChainExpression
? followOptionalChaining(expression.expression)
: expression;

export default createRule({
name: __filename,
meta: {
Expand Down Expand Up @@ -41,10 +48,15 @@ export default createRule({
const [argument] = expect.arguments;
const { matcher } = jestFnCall;

if (!EqualityMatcher.hasOwnProperty(getAccessorValue(matcher))) {
return;
}

const expression = followOptionalChaining(argument);

if (
!EqualityMatcher.hasOwnProperty(getAccessorValue(matcher)) ||
argument?.type !== AST_NODE_TYPES.MemberExpression ||
!isSupportedAccessor(argument.property, 'length')
expression?.type !== AST_NODE_TYPES.MemberExpression ||
!isSupportedAccessor(expression.property, 'length')
) {
return;
}
Expand All @@ -54,7 +66,10 @@ export default createRule({
return [
// remove the "length" property accessor
fixer.removeRange([
argument.property.range[0] - 1,
expression.property.range[0] -
(expression.parent?.type === AST_NODE_TYPES.ChainExpression
? 2
: 1),
argument.range[1],
]),
// replace the current matcher with "toHaveLength"
Expand Down

0 comments on commit 5303d3d

Please sign in to comment.