-
-
Notifications
You must be signed in to change notification settings - Fork 364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add prefer-math-min-max
#2432
Merged
+761
−0
Merged
Add prefer-math-min-max
#2432
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
bd6f6cc
Add `prefer-math-min-max`
axetroy fbefd9a
Update prefer-math-min-max.js
sindresorhus dc5aedc
simplify the switch case
axetroy 7948804
Remove unnecessary placeholder
axetroy 92babf1
update description
axetroy 87815e9
fix edge case
axetroy 48de8a4
Fix edge case in `prefer-math-min-max` rule
axetroy 5164a5e
update docs
axetroy 7cd3d39
remove context.report() with return statement
axetroy 616e3d0
update docs
axetroy f0cf4bc
refactor code to improve readability and performance
axetroy 9b27968
support edge case `(0,foo) > 10 ? 10 : (0,foo)`
axetroy 82130fd
refactor code to improve readability and performance
axetroy 6b7c587
add more test case
axetroy 1dd9b4c
add more edge test case
axetroy 63b9d31
add more edge case
axetroy f5afe1e
refactor code to use fixSpaceAroundKeyword in prefer-math-min-max rule
axetroy f88e226
improve codecov
axetroy 49d6e0e
Simplify the code
axetroy 2d8b9aa
rename `reportPreferMathMinOrMax` to `getProblem`
axetroy 9feae75
refactor prefer-math-min-max rule to improve readability and performance
axetroy 9bdef77
refactor prefer-math-min-max rule for improved readability and perfor…
axetroy 9544a1d
update format
axetroy 6ae06c6
Add test
fisker 8d08770
Fix tests / Simplify rule
fisker a58b6c8
Linting
fisker File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Prefer `Math.min()` and `Math.max()` over ternary expressions for simple comparisons | ||
|
||
💼 This rule is enabled in the ✅ `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs). | ||
|
||
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). | ||
|
||
<!-- end auto-generated rule header --> | ||
<!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` --> | ||
|
||
Enforce the use of `Math.min()` and `Math.max()` instead of ternary expressions for simple comparisons. This makes the code more readable. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is repeating the title. |
||
|
||
## Examples | ||
|
||
<!-- Math.min() --> | ||
|
||
```js | ||
height > 50 ? 50 : height; // ❌ | ||
Math.min(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height >= 50 ? 50 : height; // ❌ | ||
Math.min(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height < 50 ? height : 50; // ❌ | ||
Math.min(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height <= 50 ? height : 50; // ❌ | ||
Math.min(height, 50); // ✅ | ||
``` | ||
|
||
<!-- Math.max() --> | ||
|
||
```js | ||
height > 50 ? height : 50; // ❌ | ||
Math.max(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height >= 50 ? height : 50; // ❌ | ||
Math.max(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height < 50 ? 50 : height; // ❌ | ||
Math.max(height, 50); // ✅ | ||
``` | ||
|
||
```js | ||
height <= 50 ? 50 : height; // ❌ | ||
Math.max(height, 50); // ✅ | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
'use strict'; | ||
|
||
const MESSAGE_ID = 'prefer-math-min-max'; | ||
const messages = { | ||
[MESSAGE_ID]: 'Prefer `{{replacement}}` to simplify ternary expressions.', | ||
}; | ||
|
||
/** | ||
|
||
@param {import('eslint').Rule.RuleContext} context | ||
@param {import('estree').ConditionalExpression} node | ||
@param {string} method | ||
*/ | ||
function reportPreferMathMinOrMax(context, node, left, right, method) { | ||
const {sourceCode} = context; | ||
|
||
context.report({ | ||
fisker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
node, | ||
messageId: MESSAGE_ID, | ||
data: { | ||
replacement: `${method}()`, | ||
value: sourceCode.getText(node), | ||
fisker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
fix: fixer => fixer.replaceText(node, `${method}(${sourceCode.getText(left)}, ${sourceCode.getText(right)})`), | ||
}); | ||
} | ||
|
||
/** @param {import('eslint').Rule.RuleContext} context */ | ||
const create = context => ({ | ||
/** @param {import('estree').ConditionalExpression} node */ | ||
ConditionalExpression(node) { | ||
const {test, consequent, alternate} = node; | ||
|
||
if (test.type !== 'BinaryExpression') { | ||
return; | ||
} | ||
|
||
const {sourceCode} = context; | ||
const {operator, left, right} = test; | ||
|
||
const leftCode = sourceCode.getText(left); | ||
const rightCode = sourceCode.getText(right); | ||
const alternateCode = sourceCode.getText(alternate); | ||
const consequentCode = sourceCode.getText(consequent); | ||
|
||
switch (operator) { | ||
fisker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case '>': | ||
case '>=': { | ||
if (leftCode === alternateCode && rightCode === consequentCode) { | ||
// Example `height > 50 ? 50 : height` | ||
// Prefer `Math.min()` | ||
reportPreferMathMinOrMax(context, node, left, right, 'Math.min'); | ||
} else if (leftCode === consequentCode && rightCode === alternateCode) { | ||
// Example `height > 50 ? height : 50` | ||
// Prefer `Math.max()` | ||
reportPreferMathMinOrMax(context, node, left, right, 'Math.max'); | ||
} | ||
|
||
break; | ||
} | ||
|
||
case '<': | ||
case '<=': { | ||
if (leftCode === consequentCode && rightCode === alternateCode) { | ||
// Example `height < 50 ? height : 50` | ||
// Prefer `Math.min()` | ||
reportPreferMathMinOrMax(context, node, left, right, 'Math.min'); | ||
} else if (leftCode === alternateCode && rightCode === consequentCode) { | ||
// Example `height < 50 ? 50 : height` | ||
// Prefer `Math.max()` | ||
reportPreferMathMinOrMax(context, node, left, right, 'Math.max'); | ||
} | ||
|
||
break; | ||
} | ||
|
||
default: { | ||
break; | ||
} | ||
} | ||
}, | ||
}); | ||
|
||
/** @type {import('eslint').Rule.RuleModule} */ | ||
module.exports = { | ||
create, | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: 'Prefer `Math.min()` and `Math.max()` over ternary expressions for simple comparisons.', | ||
recommended: true, | ||
}, | ||
fixable: 'code', | ||
messages, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {getTester} from './utils/test.mjs'; | ||
|
||
const {test} = getTester(import.meta); | ||
|
||
test.snapshot({ | ||
valid: [ | ||
'height > 10 ? height : 20', | ||
'height > 50 ? Math.min(50, height) : height', | ||
], | ||
invalid: [ | ||
// Prefer `Math.min()` | ||
'height > 50 ? 50 : height', | ||
'height >= 50 ? 50 : height', | ||
'height < 50 ? height : 50', | ||
'height <= 50 ? height : 50', | ||
|
||
// Prefer `Math.min()` | ||
'height > maxHeight ? maxHeight : height', | ||
'height < maxHeight ? height : maxHeight', | ||
|
||
// Prefer `Math.min()` | ||
'window.height > 50 ? 50 : window.height', | ||
'window.height < 50 ? window.height : 50', | ||
|
||
// Prefer `Math.max()` | ||
'height > 50 ? height : 50', | ||
'height >= 50 ? height : 50', | ||
'height < 50 ? 50 : height', | ||
'height <= 50 ? 50 : height', | ||
|
||
// Prefer `Math.max()` | ||
'height > maxHeight ? height : maxHeight', | ||
'height < maxHeight ? maxHeight : height', | ||
], | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.