├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json ├── src └── rules │ └── prefer-reject.js └── test ├── .eslintrc └── lib └── rules └── prefer-reject.js /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | ./index.js 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "arrowFunctions": true, 4 | "blockBindings": true, 5 | "regexUFlag": true, 6 | "regexYFlag": true, 7 | "templateStrings": true, 8 | "binaryLiterals": true, 9 | "octalLiterals": true, 10 | "unicodeCodePointEscapes": true, 11 | "superInFunctions": true, 12 | "defaultParams": true, 13 | "restParams": true, 14 | "forOf": true, 15 | "objectLiteralComputedProperties": true, 16 | "objectLiteralShorthandMethods": true, 17 | "objectLiteralShorthandProperties": true, 18 | "objectLiteralDuplicateProperties": true, 19 | "generators": true, 20 | "destructuring": true, 21 | "classes": true, 22 | "spread": true, 23 | "newTarget": true, 24 | "modules": true, 25 | "jsx": false, 26 | "globalReturn": false, 27 | "experimentalObjectRestSpread": false 28 | }, 29 | "env": { 30 | "builtin": true, 31 | "browser": true, 32 | "commonjs": false, 33 | "node": true, 34 | "worker": false, 35 | "amd": false, 36 | "mocha": false, 37 | "nashorn": false, 38 | "jasmine": false, 39 | "jest": false, 40 | "phantomjs": false, 41 | "jquery": false, 42 | "qunit": false, 43 | "prototypejs": false, 44 | "protractor": false, 45 | "shelljs": false, 46 | "meteor": false, 47 | "mongo": false, 48 | "applescript": false, 49 | "serviceworker": false, 50 | "embertest": false, 51 | "es6": true 52 | }, 53 | "rules": { 54 | "complexity": [ 55 | 2, 56 | 4 57 | ], 58 | "no-inner-declarations": [ 59 | 2, 60 | "functions" 61 | ], 62 | "one-var": [ 63 | 2, 64 | { 65 | "var": "always", 66 | "let": "never", 67 | "const": "never" 68 | } 69 | ], 70 | "constructor-super": 2, 71 | "radix": 2, 72 | "no-octal": 2, 73 | "max-len": [ 74 | 2, 75 | 120, 76 | 4 77 | ], 78 | "no-implied-eval": 2, 79 | "no-shadow-restricted-names": 2, 80 | "no-duplicate-case": 2, 81 | "no-inline-comments": 2, 82 | "space-before-keywords": [ 83 | 2, 84 | "always" 85 | ], 86 | "no-native-reassign": 2, 87 | "no-param-reassign": [ 88 | 2, 89 | { 90 | "props": true 91 | } 92 | ], 93 | "require-jsdoc": 0, 94 | "no-fallthrough": 2, 95 | "no-extra-boolean-cast": 2, 96 | "no-self-compare": 2, 97 | "operator-assignment": [ 98 | 2, 99 | "always" 100 | ], 101 | "yoda": [ 102 | 2, 103 | "never" 104 | ], 105 | "key-spacing": [ 106 | 2, 107 | { 108 | "beforeColon": false, 109 | "afterColon": true 110 | } 111 | ], 112 | "no-alert": 2, 113 | "no-var": 2, 114 | "generator-star-spacing": [ 115 | 2, 116 | { 117 | "before": true, 118 | "after": false 119 | } 120 | ], 121 | "no-multi-spaces": 2, 122 | "no-empty-character-class": 2, 123 | "no-return-assign": 2, 124 | "no-regex-spaces": 2, 125 | "accessor-pairs": 0, 126 | "no-empty-label": 2, 127 | "no-dupe-args": 2, 128 | "consistent-this": [ 129 | 2, 130 | "self" 131 | ], 132 | "sort-vars": 0, 133 | "no-invalid-this": 0, 134 | "max-nested-callbacks": [ 135 | 2, 136 | 3 137 | ], 138 | "no-implicit-coercion": 2, 139 | "no-process-env": 2, 140 | "eol-last": 2, 141 | "no-plusplus": 2, 142 | "no-sequences": 2, 143 | "no-invalid-regexp": 2, 144 | "no-labels": 2, 145 | "curly": [ 146 | 2, 147 | "all" 148 | ], 149 | "no-extend-native": 2, 150 | "no-irregular-whitespace": 2, 151 | "max-depth": [ 152 | 2, 153 | 3 154 | ], 155 | "space-return-throw-case": 2, 156 | "no-delete-var": 2, 157 | "strict": [ 158 | 2, 159 | "global" 160 | ], 161 | "no-octal-escape": 2, 162 | "no-debugger": 2, 163 | "id-length": 0, 164 | "quote-props": [ 165 | 2, 166 | "as-needed" 167 | ], 168 | "no-floating-decimal": 2, 169 | "no-undef-init": 2, 170 | "no-eq-null": 2, 171 | "no-control-regex": 2, 172 | "no-restricted-syntax": 0, 173 | "no-spaced-func": 2, 174 | "no-new-object": 2, 175 | "space-in-parens": [ 176 | 2, 177 | "never" 178 | ], 179 | "object-shorthand": [ 180 | 2, 181 | "always" 182 | ], 183 | "space-after-keywords": [ 184 | 2, 185 | "always" 186 | ], 187 | "no-process-exit": 2, 188 | "no-continue": 2, 189 | "dot-location": [ 190 | 2, 191 | "property" 192 | ], 193 | "no-catch-shadow": 2, 194 | "no-loop-func": 2, 195 | "no-array-constructor": 2, 196 | "no-extra-parens": 2, 197 | "require-yield": 2, 198 | "no-negated-in-lhs": 2, 199 | "no-useless-concat": 0, 200 | "space-unary-ops": 2, 201 | "func-style": 0, 202 | "no-use-before-define": 2, 203 | "no-useless-call": 2, 204 | "new-parens": 2, 205 | "no-shadow": 2, 206 | "no-mixed-requires": 0, 207 | "arrow-spacing": [ 208 | 2, 209 | { 210 | "before": true, 211 | "after": true 212 | } 213 | ], 214 | "object-curly-spacing": [ 215 | 2, 216 | "always" 217 | ], 218 | "prefer-template": 2, 219 | "no-obj-calls": 2, 220 | "no-new-func": 2, 221 | "no-new-require": 2, 222 | "arrow-parens": 2, 223 | "no-redeclare": 2, 224 | "no-script-url": 2, 225 | "block-scoped-var": 0, 226 | "no-proto": 2, 227 | "computed-property-spacing": [ 228 | 2, 229 | "never" 230 | ], 231 | "valid-jsdoc": 0, 232 | "no-constant-condition": 2, 233 | "no-void": 2, 234 | "vars-on-top": 2, 235 | "max-params": [ 236 | 2, 237 | 4 238 | ], 239 | "no-underscore-dangle": 0, 240 | "array-bracket-spacing": [ 241 | 2, 242 | "always" 243 | ], 244 | "no-restricted-modules": 0, 245 | "no-throw-literal": 2, 246 | "block-spacing": 0, 247 | "no-this-before-super": 2, 248 | "space-before-blocks": [ 249 | 2, 250 | "always" 251 | ], 252 | "no-multiple-empty-lines": [ 253 | 2, 254 | { 255 | "max": 1 256 | } 257 | ], 258 | "no-extra-bind": 2, 259 | "prefer-spread": 2, 260 | "no-sync": 2, 261 | "space-before-function-paren": [ 262 | 2, 263 | { 264 | "anonymous": "always", 265 | "named": "never" 266 | } 267 | ], 268 | "no-dupe-keys": 2, 269 | "space-infix-ops": 2, 270 | "max-statements": [ 271 | 2, 272 | 10 273 | ], 274 | "prefer-reflect": 2, 275 | "id-match": 0, 276 | "no-console": 2, 277 | "no-negated-condition": 0, 278 | "init-declarations": 0, 279 | "lines-around-comment": 0, 280 | "no-unused-expressions": 2, 281 | "no-lone-blocks": 2, 282 | "semi": 2, 283 | "no-caller": 2, 284 | "wrap-regex": 2, 285 | "no-ternary": 0, 286 | "consistent-return": 2, 287 | "no-warning-comments": [ 288 | 2, 289 | { 290 | "terms": [ 291 | "todo", 292 | "fixme", 293 | "wtf", 294 | "falls through", 295 | "istanbul" 296 | ], 297 | "location": "anywhere" 298 | } 299 | ], 300 | "no-div-regex": 2, 301 | "no-dupe-class-members": 2, 302 | "no-extra-semi": 2, 303 | "no-undefined": 0, 304 | "no-unreachable": 2, 305 | "quotes": [ 306 | 2, 307 | "single" 308 | ], 309 | "no-ex-assign": 2, 310 | "wrap-iife": [ 311 | 2, 312 | "outside" 313 | ], 314 | "no-label-var": 2, 315 | "no-with": 2, 316 | "use-isnan": 2, 317 | "newline-after-var": [ 318 | 2, 319 | "always" 320 | ], 321 | "guard-for-in": 2, 322 | "no-const-assign": 2, 323 | "prefer-const": 2, 324 | "comma-spacing": [ 325 | 2, 326 | { 327 | "before": false, 328 | "after": true 329 | } 330 | ], 331 | "no-sparse-arrays": 2, 332 | "global-require": 0, 333 | "comma-style": [ 334 | 2, 335 | "last" 336 | ], 337 | "no-new": 2, 338 | "no-mixed-spaces-and-tabs": 2, 339 | "no-else-return": 2, 340 | "jsx-quotes": 0, 341 | "spaced-comment": [ 342 | 2, 343 | "always" 344 | ], 345 | "brace-style": [ 346 | 2, 347 | "1tbs" 348 | ], 349 | "dot-notation": 2, 350 | "no-trailing-spaces": 2, 351 | "new-cap": 2, 352 | "no-new-wrappers": 2, 353 | "eqeqeq": 2, 354 | "callback-return": 0, 355 | "indent": [ 356 | 2, 357 | 4, 358 | { 359 | "SwitchCase": 0, 360 | "VariableDeclarator": 1 361 | } 362 | ], 363 | "comma-dangle": [ 364 | 2, 365 | "never" 366 | ], 367 | "prefer-arrow-callback": 0, 368 | "no-unexpected-multiline": 0, 369 | "no-unused-vars": 2, 370 | "no-nested-ternary": 2, 371 | "no-lonely-if": 2, 372 | "no-multi-str": 2, 373 | "no-undef": 2, 374 | "camelcase": 2, 375 | "no-path-concat": 2, 376 | "semi-spacing": [ 377 | 2, 378 | { 379 | "before": false, 380 | "after": true 381 | } 382 | ], 383 | "no-iterator": 2, 384 | "no-empty": 2, 385 | "valid-typeof": 2, 386 | "func-names": 0, 387 | "handle-callback-err": [ 388 | 2, 389 | "^(e$|(e|(.*(_e|E)))rr)" 390 | ], 391 | "padded-blocks": [ 392 | 2, 393 | "never" 394 | ], 395 | "no-cond-assign": 2, 396 | "no-eval": 2, 397 | "default-case": 2, 398 | "linebreak-style": [ 399 | 2, 400 | "unix" 401 | ], 402 | "no-unneeded-ternary": 2, 403 | "no-func-assign": 2, 404 | "no-class-assign": 2, 405 | "no-bitwise": 2, 406 | "operator-linebreak": [ 407 | 2, 408 | "after" 409 | ] 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib/ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - "0.12" 5 | - "4" 6 | - "5" 7 | notifications: 8 | email: false 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.2 (November 7, 2015) 2 | 3 | * Downgrade to babel 5 4 | * Lint source with ESLint 5 | 6 | ## 1.0.1 (November 7, 2015) 7 | 8 | * Add eslint and ramda as peer dependencies 9 | 10 | ## 1.0.0 (November 7, 2015) 11 | 12 | Initial release 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Mathias Schreck , Tobias Pflug 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project has been moved to [ramda/eslint-plugin-ramda](https://github.com/ramda/eslint-plugin-ramda). 2 | 3 | 4 | --------- 5 | 6 | 7 | [![NPM Version](https://img.shields.io/npm/v/eslint-plugin-ramda.svg?style=flat)](https://www.npmjs.org/package/eslint-plugin-ramda) 8 | [![Build Status](https://img.shields.io/travis/lo1tuma/eslint-plugin-ramda/master.svg?style=flat)](https://travis-ci.org/lo1tuma/eslint-plugin-ramda) 9 | [![Dependencies](http://img.shields.io/david/lo1tuma/eslint-plugin-ramda.svg?style=flat)](https://david-dm.org/lo1tuma/eslint-plugin-ramda) 10 | [![NPM Downloads](https://img.shields.io/npm/dm/eslint-plugin-ramda.svg?style=flat)](https://www.npmjs.org/package/eslint-plugin-ramda) 11 | 12 | # eslint-plugin-ramda 13 | 14 | ESLint rules for [ramda](http://ramdajs.com). 15 | 16 | ## Install and configure 17 | 18 | `npm install --save-dev eslint-plugin-ramda` 19 | 20 | Then add a reference to this plugin and selected rules in your eslint config: 21 | 22 | ```json 23 | { 24 | "plugins": [ 25 | "ramda" 26 | ], 27 | "rules": { 28 | "ramda/prefer-reject": 2 29 | } 30 | } 31 | ``` 32 | 33 | See [Configuring Eslint](http://eslint.org/docs/user-guide/configuring) on [eslint.org](http://eslint.org) for more info. 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | rules: { 5 | 'prefer-reject': require('./lib/rules/prefer-reject') 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-ramda", 3 | "version": "1.0.2", 4 | "description": "ESLint rules for ramda.", 5 | "main": "index.js", 6 | "files": [ 7 | "index.js", 8 | "lib/", 9 | "LICENSE", 10 | "README.md" 11 | ], 12 | "scripts": { 13 | "build": "babel src --out-dir lib", 14 | "clean": "rm -rf lib", 15 | "prepublish": "npm test && npm run clean && npm run build", 16 | "lint": "eslint .", 17 | "pretest": "npm run lint", 18 | "test": "mocha test --recursive --compilers js:babel-core/register" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/lo1tuma/eslint-plugin-ramda.git" 23 | }, 24 | "author": "Mathias Schreck ", 25 | "contributors": [ 26 | "Tobias Pflug " 27 | ], 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/lo1tuma/eslint-plugin-ramda/issues" 31 | }, 32 | "homepage": "https://github.com/lo1tuma/eslint-plugin-ramda#readme", 33 | "devDependencies": { 34 | "babel": "5.8.29", 35 | "babel-core": "5.8.33", 36 | "eslint": "1.9.0", 37 | "mocha": "2.3.3" 38 | }, 39 | "dependencies": { 40 | "ramda": "^0.18.0" 41 | }, 42 | "peerDependencies": { 43 | "eslint": "^1.9.0", 44 | "ramda": "^0.18.0" 45 | }, 46 | "keywords": [ 47 | "eslint", 48 | "eslintplugin", 49 | "eslint-plugin", 50 | "ramda" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /src/rules/prefer-reject.js: -------------------------------------------------------------------------------- 1 | import R from 'ramda'; 2 | 3 | const getPropertyName = R.pipe(R.prop('property'), R.either(R.prop('name'), R.prop('value'))); 4 | 5 | const isRamdaMethod = R.curry((methodName, callee) => 6 | callee.type === 'MemberExpression' && callee.object.name === 'R' && getPropertyName(callee) === methodName 7 | ); 8 | 9 | const isRamdaFilterCall = R.propSatisfies(isRamdaMethod('filter'), 'callee'); 10 | const isCallExpression = R.propEq('type', 'CallExpression'); 11 | const isRamdaFilterCallExpression = R.allPass([ isCallExpression, isRamdaFilterCall ]); 12 | 13 | export default function (context) { 14 | return { 15 | CallExpression(node) { 16 | if (isRamdaMethod('complement', node.callee) && isRamdaFilterCallExpression(node.parent)) { 17 | context.report({ 18 | node: node.parent, 19 | message: 'R.filter used with negated predicate: Use R.reject instead.' 20 | }); 21 | } 22 | } 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/lib/rules/prefer-reject.js: -------------------------------------------------------------------------------- 1 | import { RuleTester } from 'eslint'; 2 | import rule from '../../../src/rules/prefer-reject.js'; 3 | 4 | const ruleTester = new RuleTester(); 5 | 6 | ruleTester.run('prefer-reject', rule, { 7 | valid: [ 8 | 'R.filter(a);', 9 | 'filter(a);', 10 | 'R.complement(a);', 11 | 'complement(a);', 12 | 'P.filter(R.complement(a));', 13 | 'R.find(R.complement(a));', 14 | 'R.filter(f(a));', 15 | 'R.filter(P.complement(a));', 16 | 'R.filter(complement(a));' 17 | ], 18 | 19 | invalid: [ 20 | { 21 | code: 'R.filter(R.complement(a));', 22 | errors: [ 23 | { 24 | message: 'R.filter used with negated predicate: Use R.reject instead.', 25 | line: 1, 26 | column: 1, 27 | type: 'CallExpression' 28 | } 29 | ] 30 | }, 31 | { 32 | code: 'R.filter(R.complement(a), [1,2,3]);', 33 | errors: [ 34 | { 35 | message: 'R.filter used with negated predicate: Use R.reject instead.', 36 | line: 1, 37 | column: 1, 38 | type: 'CallExpression' 39 | } 40 | ] 41 | }, 42 | { 43 | code: 'R["filter"](R.complement(a));', 44 | errors: [ 45 | { 46 | message: 'R.filter used with negated predicate: Use R.reject instead.', 47 | line: 1, 48 | column: 1, 49 | type: 'CallExpression' 50 | } 51 | ] 52 | }, 53 | { 54 | code: 'R.filter(R["complement"](a));', 55 | errors: [ 56 | { 57 | message: 'R.filter used with negated predicate: Use R.reject instead.', 58 | type: 'CallExpression' 59 | } 60 | ] 61 | } 62 | ] 63 | }); 64 | --------------------------------------------------------------------------------