From 6b4f72149cdfa0cb54fc6e22152acf65ce33ab41 Mon Sep 17 00:00:00 2001 From: thessell Date: Thu, 27 Jan 2022 23:10:38 +1100 Subject: [PATCH] prefer-number-is-integer: update rule implementation from review --- configs/recommended.js | 2 +- docs/rules/prefer-number-is-integer.md | 7 ++++++ rules/prefer-number-is-integer.js | 34 +++++++++++++------------- test/prefer-number-is-integer.mjs | 6 ++--- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/configs/recommended.js b/configs/recommended.js index 7f8e8705c6..99a5651634 100644 --- a/configs/recommended.js +++ b/configs/recommended.js @@ -77,8 +77,8 @@ module.exports = { 'unicorn/prefer-module': 'error', 'unicorn/prefer-negative-index': 'error', 'unicorn/prefer-node-protocol': 'error', - 'unicorn/prefer-number-properties': 'error', 'unicorn/prefer-number-is-integer': 'error', + 'unicorn/prefer-number-properties': 'error', 'unicorn/prefer-object-from-entries': 'error', 'unicorn/prefer-optional-catch-binding': 'error', 'unicorn/prefer-prototype-methods': 'error', diff --git a/docs/rules/prefer-number-is-integer.md b/docs/rules/prefer-number-is-integer.md index 5e25433e69..fdde7b50c7 100644 --- a/docs/rules/prefer-number-is-integer.md +++ b/docs/rules/prefer-number-is-integer.md @@ -1,5 +1,12 @@ # Prefer `Number.isInteger()` for integer checking + + +✅ *This rule is part of the [recommended](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config) config.* + +💡 *This rule provides [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).* + + Enforces the use of [Number.isInteger()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger) for checking if a number is an integer. There are multiple ways to check if a variable is an integer, but these approaches tend to have slightly different behaviours. diff --git a/rules/prefer-number-is-integer.js b/rules/prefer-number-is-integer.js index efccf29758..31e29231fd 100644 --- a/rules/prefer-number-is-integer.js +++ b/rules/prefer-number-is-integer.js @@ -1,5 +1,6 @@ 'use strict'; +const {methodCallSelector} = require('./selectors/index.js'); const isSameReference = require('./utils/is-same-reference.js'); const MESSAGE_ID = 'preferNumberIsInteger'; @@ -11,7 +12,7 @@ const messages = { const equalsSelector = ':matches([operator="==="],[operator="=="])'; -// Value % 1 === 0 +// `value % 1 === 0` const modulo1Selector = [ 'BinaryExpression', '[left.type="BinaryExpression"]', @@ -21,7 +22,8 @@ const modulo1Selector = [ '[right.value="0"]', ].join(''); -// (value^0) === value OR (value | 0) === value +// `(value ^ 0) === value` +// `(value | 0) === value` const mathOperatorSelector = [ 'BinaryExpression', '[left.type="BinaryExpression"]', @@ -30,33 +32,30 @@ const mathOperatorSelector = [ equalsSelector, ].join(''); -// ParseInt(value,10) === value -const parseIntSelector = [ +// `Number.parseInt(value,10) === value` +const numberParseIntSelector = [ 'BinaryExpression', '[left.type="CallExpression"]', - '[left.callee.name="parseInt"]', + '[left.callee.type="MemberExpression"]', + '[left.callee.object.name="Number"]', + '[left.callee.property.name="parseInt"]', '[left.arguments.1.value=10]', equalsSelector, ].join(''); -// _.isInteger(value) +// `_.isInteger(value)` const lodashIsIntegerSelector = [ - 'CallExpression', - `:matches(${['_', 'lodash', 'underscore'].map(callee => `[callee.object.name="${callee}"]`).join(',')})`, - '[callee.property.name="isInteger"]', + methodCallSelector({method: 'isInteger', objects: ['_', 'lodash', 'underscore']}), ].join(''); -// Math.round(value) === value +// `Math.round(value) === value` const mathRoundSelector = [ 'BinaryExpression', - '[left.type="CallExpression"]', - '[left.callee.type="MemberExpression"]', - '[left.callee.object.name="Math"]', - '[left.callee.property.name="round"]', + methodCallSelector({method: 'round', object: 'Math', path: 'left'}), equalsSelector, ].join(''); -// ~~value === value +// `~~value === value` const bitwiseNotSelector = [ 'BinaryExpression', '[left.type="UnaryExpression"]', @@ -121,7 +120,7 @@ const create = context => { return getNodeName(node.right); } }), - [parseIntSelector]: createNodeListener(sourceCode, node => { + [numberParseIntSelector]: createNodeListener(sourceCode, node => { if ( isSameReference(node.left.arguments[0], node.right) ) { @@ -144,6 +143,7 @@ const create = context => { }; }; +/** @type {import('eslint').Rule.RuleModule} */ module.exports = { create, meta: { @@ -151,7 +151,7 @@ module.exports = { docs: { description: 'Prefer `Number.isInteger()` for integer checking.', }, - messages, hasSuggestions: true, + messages, }, }; diff --git a/test/prefer-number-is-integer.mjs b/test/prefer-number-is-integer.mjs index 6a5d6dba57..9f0470f067 100644 --- a/test/prefer-number-is-integer.mjs +++ b/test/prefer-number-is-integer.mjs @@ -20,7 +20,7 @@ test({ '(value^0) === notValue', '(value | 0) === notValue', 'Math.round(value) === notValue', - 'parseInt(value, 10) === notValue', + 'Number.parseInt(value, 10) === notValue', '~~value === notValue', ], invalid: [ @@ -48,11 +48,11 @@ test({ messageId: 'preferNumberIsIntegerSuggestion', output: 'Number.isInteger(value)', }]}), - suggestionCase({code: 'parseInt(value, 10) === value', suggestions: [{ + suggestionCase({code: 'Number.parseInt(value, 10) === value', suggestions: [{ messageId: 'preferNumberIsIntegerSuggestion', output: 'Number.isInteger(value)', }]}), - suggestionCase({code: 'parseInt(value, 10) == value', suggestions: [{ + suggestionCase({code: 'Number.parseInt(value, 10) == value', suggestions: [{ messageId: 'preferNumberIsIntegerSuggestion', output: 'Number.isInteger(value)', }]}),