Skip to content

Commit

Permalink
Add prefer-trim-start-end rule (#440)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker authored and sindresorhus committed Nov 27, 2019
1 parent a496e96 commit 29e3b13
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 0 deletions.
19 changes: 19 additions & 0 deletions docs/rules/prefer-trim-start-end.md
@@ -0,0 +1,19 @@
# Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`

[`String#trimLeft()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimLeft) and [`String#trimRight()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimRight) are aliases of [`String#trimStart()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart) and [`String#trimEnd()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd)

This rule is fixable.

## Fail

```js
const foo = bar.trimStart();
const foo = bar.trimEnd();
```

## Pass

```js
const foo = bar.trimLeft();
const foo = bar.trimRight();
```
1 change: 1 addition & 0 deletions index.js
Expand Up @@ -57,6 +57,7 @@ module.exports = {
'unicorn/prefer-starts-ends-with': 'error',
'unicorn/prefer-string-slice': 'error',
'unicorn/prefer-text-content': 'error',
'unicorn/prefer-trim-start-end': 'error',
'unicorn/prefer-type-error': 'error',
'unicorn/prevent-abbreviations': 'error',
'unicorn/regex-shorthand': 'error',
Expand Down
2 changes: 2 additions & 0 deletions readme.md
Expand Up @@ -75,6 +75,7 @@ Configure it in `package.json`.
"unicorn/prefer-starts-ends-with": "error",
"unicorn/prefer-string-slice": "error",
"unicorn/prefer-text-content": "error",
"unicorn/prefer-trim-start-end": "error",
"unicorn/prefer-type-error": "error",
"unicorn/prevent-abbreviations": "error",
"unicorn/regex-shorthand": "error",
Expand Down Expand Up @@ -126,6 +127,7 @@ Configure it in `package.json`.
- [prefer-starts-ends-with](docs/rules/prefer-starts-ends-with.md) - Prefer `String#startsWith()` & `String#endsWith()` over more complex alternatives.
- [prefer-string-slice](docs/rules/prefer-string-slice.md) - Prefer `String#slice()` over `String#substr()` and `String#substring()`. *(partly fixable)*
- [prefer-text-content](docs/rules/prefer-text-content.md) - Prefer `.textContent` over `.innerText`. *(fixable)*
- [prefer-trim-start-end](docs/rules/prefer-trim-start-end.md) - Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`. *(fixable)*
- [prefer-type-error](docs/rules/prefer-type-error.md) - Enforce throwing `TypeError` in type checking conditions. *(fixable)*
- [prevent-abbreviations](docs/rules/prevent-abbreviations.md) - Prevent abbreviations. *(partly fixable)*
- [regex-shorthand](docs/rules/regex-shorthand.md) - Enforce the use of regex shorthands to improve readability. *(fixable)*
Expand Down
55 changes: 55 additions & 0 deletions rules/prefer-trim-start-end.js
@@ -0,0 +1,55 @@
'use strict';
const getDocumentationUrl = require('./utils/get-documentation-url');

const methods = new Map([
['trimLeft', 'trimStart'],
['trimRight', 'trimEnd']
]);

const messages = {};

for (const [method, replacement] of methods.entries()) {
messages[method] = `Prefer \`String#${method}()\` over \`String#${replacement}()\`.`;
}

const create = context => {
return {
CallExpression(node) {
const {callee, arguments: arguments_} = node;

if (
callee.type !== 'MemberExpression' ||
callee.property.type !== 'Identifier' ||
arguments_.length !== 0
) {
return;
}

const method = callee.property.name;

if (!methods.has(method)) {
return;
}

const replacement = methods.get(method);

context.report({
node,
messageId: method,
fix: fixer => fixer.replaceText(callee.property, replacement)
});
}
};
};

module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
url: getDocumentationUrl(__filename)
},
fixable: 'code',
messages
}
};
51 changes: 51 additions & 0 deletions test/prefer-trim-start-end.js
@@ -0,0 +1,51 @@
import test from 'ava';
import avaRuleTester from 'eslint-ava-rule-tester';
import rule from '../rules/prefer-trim-start-end';

const ruleTester = avaRuleTester(test, {
env: {
es6: true
}
});

const errorTrimLeft = {
ruleId: 'prefer-trim-start-end',
messageId: 'trimLeft'
};

const errorTrimRight = {
ruleId: 'prefer-trim-start-end',
messageId: 'trimRight'
};

ruleTester.run('prefer-flat-map', rule, {
valid: [
'foo.trimStart()',
'foo.trimEnd()',
// Extra arguments
'foo.trimLeft(1)',
// New
'new foo.trimLeft()',
// Function call
'trimLeft()',
// Not call
'foo.trimLeft'
],
invalid: [
{
code: 'foo.trimLeft()',
output: 'foo.trimStart()',
errors: [errorTrimLeft]
},
{
code: 'foo.trimRight()',
output: 'foo.trimEnd()',
errors: [errorTrimRight]
},
{
code: '"foo".trimLeft()',
output: '"foo".trimStart()',
errors: [errorTrimLeft]
}
]
});

0 comments on commit 29e3b13

Please sign in to comment.