Skip to content

Commit

Permalink
add rule prefer-lodash-chain
Browse files Browse the repository at this point in the history
  • Loading branch information
mariawix committed Nov 23, 2015
1 parent dec6a1f commit 0f38bcd
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 2 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Finally, enable all of the rules that you would like to use.
"rules": {
"lodash3/prop-shorthand": 1,
"lodash3/matches-prop-shorthand": 1,
"lodash3/matches-shorthand": 1,
"lodash3/matches-shorthand": [1,3],
"lodash3/prefer-chain": 1,
"lodash3/preferred-alias": 1,
"lodash3/no-single-chain": 1,
Expand All @@ -47,6 +47,7 @@ Finally, enable all of the rules that you would like to use.
"lodash3/prefer-wrapper-method": 1,
"lodash3/prefer-invoke": 1,
"lodash3/prefer-thru": 1,
"lodash3/prefer-lodash-chain": 1
"lodash3/prefer-lodash-method": 1,
"lodash3/prefer-lodash-typecheck": 1,
"lodash3/no-commit": 1,
Expand Down Expand Up @@ -75,6 +76,7 @@ Finally, enable all of the rules that you would like to use.
* [prefer-wrapper-method](docs/rules/prefer-wrapper-method.md): Prefer using array and string methods in the chain and not the initial value, e.g. `_(str).split(' ')...`
* [prefer-invoke](docs/rules/prefer-invoke.md): Prefer using `_.invoke` over `_.map` with a method call inside.
* [prefer-thru](docs/rules/prefer-thru.md): Prefer using `_.prototype.thru` in the chain and not call functions in the initial value, e.g. `_(x).thru(f).map(g)...`
* [prefer-lodash-chain](docs/rules/prefer-lodash-chain.md): Prefer using Lodash chains (e.g. `_.map`) over native and mixed chains.
* [prefer-lodash-method](docs/rules/prefer-lodash-method.md): Prefer using Lodash collection methods (e.g. `_.map`) over native array methods.
* [prefer-lodash-typecheck](docs/rules/prefer-lodash-typecheck.md): Prefer using `_.is*` methods over `typeof` and `instanceof` checks when applicable.
* [no-commit](docs/rules/no-commit.md): Do not use `.commit()` on chains that should end with `.value()`
Expand Down
34 changes: 34 additions & 0 deletions docs/rules/prefer-lodash-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Consistent chain

When chaining methods, it's often better to use only Lodash methods or wrappers.

## Rule Details

This rule takes no arguments.

The following patterns are considered warnings:

```js
var userNames = _.filter(users, {active: true}).map(function (user) {
return user.name.givenName;
});

var userNames = _(users).map("name.givenName").value().reduce(function (res, cur) {
return res + " " + cur;
});
```

The following patterns are not considered warnings:

```js
var userNames = users.map(function(user) {
return user.name;
});

var userNames = _(users).filter({active: true}).map("name").value();
```


## When Not To Use It

If you do not want to enforce using chains composed of Lodash functions, you should not use this rule.
28 changes: 28 additions & 0 deletions lib/rules/prefer-lodash-chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @fileoverview Rule to check if there's a JS native method in the lodash chain
*/
'use strict';

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function (context) {
var lodashUtil = require('../util/lodashUtil');
var astUtil = require('../util/astUtil');

var REPORT_MESSAGE = 'Prefer lodash chain';

return {
CallExpression: function (node) {
var isLodashWrapperMethod = lodashUtil.isLodashWrapperMethod(node);
if (!lodashUtil.isLodashCall(node) && (lodashUtil.canBeLodashMethod(astUtil.getMethodName(node)) || isLodashWrapperMethod)) {
var caller = astUtil.getCaller(node);
if (lodashUtil.isLodashCall(caller) && astUtil.getMethodName(caller) !== 'chain' && !isLodashWrapperMethod ||
lodashUtil.isLodashWrapper(astUtil.getCaller(caller)) && lodashUtil.isChainBreaker(caller)) {
context.report(node, REPORT_MESSAGE, {method: astUtil.getMethodName(node)});
}
}
}
};
};
37 changes: 37 additions & 0 deletions tests/lib/rules/prefer-lodash-chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

var rule = require('../../../lib/rules/prefer-lodash-chain');
var RuleTester = require('eslint').RuleTester;

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

var ruleTester = new RuleTester();
var errors = [{message: 'Prefer lodash chain'}];
ruleTester.run('prefer-lodash-method', rule, {
valid: [
'var userNames = users.map(function(user) { return user.name; });',
'var userNames = _(users).filter({active: true}).map("name").value();',
'var userNames = _(users).map("name.givenName").reduce(function (res, cur) { return res + " " + cur; });',
'var userNames = users.map(cb1).filter(cb2);',
'var userNames = _(users).map(cb1).reduce(cb2).map(cb3);',
'var userNames = _(users).map("name.givenName").join(" ");',
'var userNames = _.map(users, "name.givenName").join(" ");'
],
invalid: [
'var userNames = _.filter(users, cb1).map(cb2);',
'var userNames = _(users).map("name.givenName").value().join(" ");',
'var userNames = _.filter(users, {active: true}).map(function (user) { return user.name.givenName; });',
'var userNames = _(users).map("name.givenName").value().reduce(cb);',
'var userNames = _(users).map(cb1).filter(cb2).map(cb3).value().reduce(cb4);',
'var userNames = _(users).map("name.givenName").value().reduce(function (res, cur) { return res + " " + cur; });',
'var userNames = _.chain(users).filter("active").map("name.givenName").value().reduce(cb);'
].map(function (code) {
return {code: code, errors: errors};
})
});
2 changes: 1 addition & 1 deletion tests/lib/rules/prefer-times.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ruleTester.run('prefer-times', rule, {
'var x = _.map(a, "prop");',
'var x = _.map(arr, function(a) {return _.map(a, function(b) {return b + 1});});',
"var x = arr.map(function () {return str; }).join('')"
],
],
invalid: [{
code: '_(arr).map(function(){return g}).value()',
errors: errors
Expand Down

0 comments on commit 0f38bcd

Please sign in to comment.