Skip to content

Commit

Permalink
Merge pull request #16 from jogold/prefer-both-either
Browse files Browse the repository at this point in the history
Add prefer-both-either
  • Loading branch information
lo1tuma authored Mar 4, 2018
2 parents 64e6b5e + 7e18afd commit fec60a4
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Configure it in `package.json`.
"ramda/no-redundant-not": "error",
"ramda/no-redundant-or": "error",
"ramda/pipe-simplification": "error",
"ramda/prefer-both-either": "error",
"ramda/prefer-complement": "error",
"ramda/prefer-ramda-boolean": "error",
"ramda/prop-satisfies-simplification": "error",
Expand Down Expand Up @@ -77,6 +78,7 @@ Configure it in `package.json`.
- `no-redundant-not` - Forbids `not` with 1 parameter in favor of `!`
- `no-redundant-or` - Forbids `or` with 2 parameters in favor of `||`
- `pipe-simplification` - Detects when a function that has the same behavior already exists
- `prefer-both-either` - Enforces using `both`/`either` instead of `allPass`/`anyPass` with a list of only two predicates
- `prefer-complement` - Enforces using `complement` instead of compositions using `not`
- `prefer-ramda-boolean` - Enforces using `R.T` and `R.F` instead of explicit functions
- `prop-satisfies-simplification` - Detects when can replace `propSatisfies` by more simple functions
Expand Down
51 changes: 51 additions & 0 deletions rules/prefer-both-either.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';
const R = require('ramda');
const ast = require('../ast-helper');

const isCalling = ast.isCalling;
const getName = ast.getName;

const prefer = {
allPass: 'both',
anyPass: 'either'
}

const match = name => isCalling({
name,
arguments: R.where({
0: R.both(
R.propEq('type', 'ArrayExpression'),
R.pathEq(['elements', 'length'], 2)
),
})
})

const elementsToString = R.pipe(
R.prop('elements'),
R.map(getName),
R.join(', ')
);

const report = instead => `Instead of \`${instead}\`, prefer \`${prefer[instead]}\` when there are only two predicates`

const create = context => ({
CallExpression(node) {
if (match('allPass')(node) || match('anyPass')(node)) {
const callee = getName(node.callee);
context.report({
node,
message: report(callee)
});
}
}
});

module.exports = {
create,
meta: {
docs: {
description: 'Enforces using `both`/`either` instead of `allPass`/`anyPass` with a list of only two predicates',
recommended: 'off'
}
}
};
65 changes: 65 additions & 0 deletions test/prefer-both-either.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import test from 'ava';
import avaRuleTester from 'eslint-ava-rule-tester';
import rule from '../rules/prefer-both-either';

const ruleTester = avaRuleTester(test, {
env: {
es6: true
},
parserOptions: {
sourceType: 'module'
}
});

const prefer = {
allPass: 'both',
anyPass: 'either'
}

const error = instead => ({
ruleId: 'prefer-both-either',
message: `Instead of \`${instead}\`, prefer \`${prefer[instead]}\` when there are only two predicates`
});

ruleTester.run('prefer-both-either', rule, {
valid: [
'both(foo, bar)',
'either(foo, bar)',
'allPass([foo, bar, baz])',
'anyPass([foo, bar, baz])',
'allPass(predicates)',
'allPass(predicates, foo)',
'anyPass(predicates)',
'anyPass(predicates, foo)'
],
invalid: [
{
code: 'allPass([foo, bar])',
errors: [error('allPass')]
},
{
code: 'allPass([foo, bar], baz)',
errors: [error('allPass')]
},
{
code: 'allPass([(foo) => !foo, function () { return false; }])',
errors: [error('allPass')]
},
{
code: 'allPass([complement(foo), complement(bar)])',
errors: [error('allPass')]
},
{
code: 'anyPass([foo, bar])',
errors: [error('anyPass')]
},
{
code: 'anyPass([foo, bar], baz)',
errors: [error('anyPass')]
},
{
code: 'anyPass([R.T, R.F])',
errors: [error('anyPass')]
}
]
});

0 comments on commit fec60a4

Please sign in to comment.