From d6a1c5bdc2d7d1acf723d98d1bff662962a80901 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 29 Dec 2021 10:37:31 +1300 Subject: [PATCH 1/4] fix(prefer-to-have-length): support square bracket accessors --- .../__tests__/prefer-to-have-length.test.ts | 22 +++++++++----- src/rules/prefer-to-have-length.ts | 30 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/rules/__tests__/prefer-to-have-length.test.ts b/src/rules/__tests__/prefer-to-have-length.test.ts index 532d504fb..b3aea3b8a 100644 --- a/src/rules/__tests__/prefer-to-have-length.test.ts +++ b/src/rules/__tests__/prefer-to-have-length.test.ts @@ -18,16 +18,19 @@ ruleTester.run('prefer-to-have-length', rule, { `expect(user.getUserName(5)).resolves.toEqual('Paul')`, `expect(user.getUserName(5)).rejects.toEqual('Paul')`, 'expect(a);', - 'expect(files["length"]).toBe(1);', ], invalid: [ - // todo: support this - // { - // code: 'expect(files["length"]).toBe(1);', - // errors: [{ messageId: 'useToHaveLength', column: 22, line: 1 }], - // output: 'expect(files).toHaveLength(1);', - // }, + { + code: 'expect(files["length"]).toBe(1);', + output: 'expect(files).toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 25, line: 1 }], + }, + { + code: 'expect(files["length"])["not"].toBe(1);', + output: 'expect(files)["not"].toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 32, line: 1 }], + }, { code: 'expect(files.length).toBe(1);', output: 'expect(files).toHaveLength(1);', @@ -43,5 +46,10 @@ ruleTester.run('prefer-to-have-length', rule, { output: 'expect(files).toHaveLength(1);', errors: [{ messageId: 'useToHaveLength', column: 22, line: 1 }], }, + { + code: 'expect(files.length).not.toStrictEqual(1);', + output: 'expect(files).not.toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 26, line: 1 }], + }, ], }); diff --git a/src/rules/prefer-to-have-length.ts b/src/rules/prefer-to-have-length.ts index 4da493aff..1bdd23e96 100644 --- a/src/rules/prefer-to-have-length.ts +++ b/src/rules/prefer-to-have-length.ts @@ -41,34 +41,50 @@ export default createRule({ !matcher || !isParsedEqualityMatcherCall(matcher) || argument?.type !== AST_NODE_TYPES.MemberExpression || - !isSupportedAccessor(argument.property, 'length') || - argument.property.type !== AST_NODE_TYPES.Identifier + !isSupportedAccessor(argument.property, 'length') ) { return; } context.report({ fix(fixer) { - const propertyDot = context + const accessorStartToken = context .getSourceCode() .getFirstTokenBetween( argument.object, argument.property, - token => token.value === '.', + token => token.value === '.' || token.value === '[', ); /* istanbul ignore if */ - if (propertyDot === null) { + if (accessorStartToken === null) { throw new Error( `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`, ); } - return [ - fixer.remove(propertyDot), + const fixers = [ + fixer.remove(accessorStartToken), fixer.remove(argument.property), fixer.replaceText(matcher.node.property, 'toHaveLength'), ]; + + if (accessorStartToken.value === '[') { + const accessorStopToken = context + .getSourceCode() + .getTokenAfter(argument.property); + + /* istanbul ignore if */ + if (accessorStopToken === null) { + throw new Error( + `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`, + ); + } + + fixers.push(fixer.remove(accessorStopToken)); + } + + return fixers; }, messageId: 'useToHaveLength', node: matcher.node.property, From 3bf9fb9a2c89b80214f9dfc5d9639b378535d38c Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 29 Dec 2021 10:48:11 +1300 Subject: [PATCH 2/4] refactor(prefer-to-have-length): simplify fixer --- src/rules/prefer-to-have-length.ts | 40 ++++-------------------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/src/rules/prefer-to-have-length.ts b/src/rules/prefer-to-have-length.ts index 1bdd23e96..39cf90c93 100644 --- a/src/rules/prefer-to-have-length.ts +++ b/src/rules/prefer-to-have-length.ts @@ -48,43 +48,13 @@ export default createRule({ context.report({ fix(fixer) { - const accessorStartToken = context - .getSourceCode() - .getFirstTokenBetween( - argument.object, - argument.property, - token => token.value === '.' || token.value === '[', - ); - - /* istanbul ignore if */ - if (accessorStartToken === null) { - throw new Error( - `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`, - ); - } - - const fixers = [ - fixer.remove(accessorStartToken), - fixer.remove(argument.property), + return [ + fixer.removeRange([ + argument.property.range[0] - 1, + argument.range[1], + ]), fixer.replaceText(matcher.node.property, 'toHaveLength'), ]; - - if (accessorStartToken.value === '[') { - const accessorStopToken = context - .getSourceCode() - .getTokenAfter(argument.property); - - /* istanbul ignore if */ - if (accessorStopToken === null) { - throw new Error( - `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`, - ); - } - - fixers.push(fixer.remove(accessorStopToken)); - } - - return fixers; }, messageId: 'useToHaveLength', node: matcher.node.property, From 27c31b61373bdb4a8447dedcb3f1436cc4dfbc0d Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 29 Dec 2021 11:00:53 +1300 Subject: [PATCH 3/4] refactor(prefer-to-have-length): simplify fixer further --- src/rules/__tests__/prefer-to-have-length.test.ts | 15 +++++++++++++++ src/rules/prefer-to-have-length.ts | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/rules/__tests__/prefer-to-have-length.test.ts b/src/rules/__tests__/prefer-to-have-length.test.ts index b3aea3b8a..5f577bd80 100644 --- a/src/rules/__tests__/prefer-to-have-length.test.ts +++ b/src/rules/__tests__/prefer-to-have-length.test.ts @@ -31,6 +31,21 @@ ruleTester.run('prefer-to-have-length', rule, { output: 'expect(files)["not"].toHaveLength(1);', errors: [{ messageId: 'useToHaveLength', column: 32, line: 1 }], }, + { + code: 'expect(files["length"])["toBe"](1);', + output: 'expect(files).toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 25, line: 1 }], + }, + { + code: 'expect(files["length"]).not["toBe"](1);', + output: 'expect(files).not.toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 29, line: 1 }], + }, + { + code: 'expect(files["length"])["not"]["toBe"](1);', + output: 'expect(files)["not"].toHaveLength(1);', + errors: [{ messageId: 'useToHaveLength', column: 32, line: 1 }], + }, { code: 'expect(files.length).toBe(1);', output: 'expect(files).toHaveLength(1);', diff --git a/src/rules/prefer-to-have-length.ts b/src/rules/prefer-to-have-length.ts index 39cf90c93..35df18f67 100644 --- a/src/rules/prefer-to-have-length.ts +++ b/src/rules/prefer-to-have-length.ts @@ -53,7 +53,10 @@ export default createRule({ argument.property.range[0] - 1, argument.range[1], ]), - fixer.replaceText(matcher.node.property, 'toHaveLength'), + fixer.replaceTextRange( + [matcher.node.object.range[1], matcher.node.range[1]], + '.toHaveLength', + ), ]; }, messageId: 'useToHaveLength', From 1354b15d024e0d3d178690cc486a41dbbf6b07c4 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 29 Dec 2021 11:01:30 +1300 Subject: [PATCH 4/4] chore(prefer-to-have-length): add comments --- src/rules/prefer-to-have-length.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rules/prefer-to-have-length.ts b/src/rules/prefer-to-have-length.ts index 35df18f67..0b5c4df63 100644 --- a/src/rules/prefer-to-have-length.ts +++ b/src/rules/prefer-to-have-length.ts @@ -49,10 +49,12 @@ export default createRule({ context.report({ fix(fixer) { return [ + // remove the "length" property accessor fixer.removeRange([ argument.property.range[0] - 1, argument.range[1], ]), + // replace the current matcher with "toHaveLength" fixer.replaceTextRange( [matcher.node.object.range[1], matcher.node.range[1]], '.toHaveLength',