eslint-plugin-you-dont-need-lodash-underscore
Advanced tools
Comparing version 6.5.0 to 6.6.0
@@ -5,8 +5,22 @@ 'use strict'; | ||
function getAssignmentLeftHandSide(node) { | ||
// For VariableDeclarator nodes, the left hand side is called `id` | ||
// The `x` on `var x = 3; | ||
if (node.type === 'VariableDeclarator') { | ||
return node.id; | ||
} | ||
// For AssignmentExpression nodes, the left hand side is called `left` | ||
// The `x` on `x = 3; | ||
if (node.type === 'AssignmentExpression') { | ||
return node.left; | ||
} | ||
return null; | ||
} | ||
for (const rule in rules) { | ||
const alternative = rules[rule].alternative; | ||
const ruleName = rules[rule].ruleName || kebabCase(rule); | ||
const forbiddenImports = [`lodash/${rule}`, `lodash.${rule}`.toLowerCase()]; | ||
const forbiddenImports = { [`lodash/${rule}`]: 1, [`lodash.${rule.toLowerCase()}`]: 1 }; | ||
module.exports[ruleName] = { | ||
create (context) { | ||
create(context) { | ||
return { | ||
@@ -17,3 +31,28 @@ CallExpression(node) { | ||
if ((objectName === '_' || objectName === 'lodash' || objectName === 'underscore') && callee.property && callee.property.name === rule) { | ||
if (objectName === 'require' && node.arguments.length === 1) { | ||
const requiredModuleName = node.arguments[0].value; | ||
const { parent } = node; | ||
if (requiredModuleName === 'lodash') { | ||
const leftHandSide = getAssignmentLeftHandSide(parent); | ||
// ex: const { indexOf } = require('lodash'); | ||
// ex: ({ indexOf } = require('lodash')); | ||
if (leftHandSide && leftHandSide.type === 'ObjectPattern') { | ||
leftHandSide.properties.forEach(property => { | ||
if (property.key.name === rule) { | ||
context.report({ | ||
node, | ||
message: `{ ${rule} } = require('${requiredModuleName}') detected. Consider using the native ${alternative}` | ||
}); | ||
} | ||
}); | ||
} | ||
} else if (forbiddenImports.hasOwnProperty(requiredModuleName)) { | ||
// ex: const indexOf = require('lodash.indexof'); | ||
// ex: const indexOf = require('lodash/indexOf'); | ||
context.report({ | ||
node, | ||
message: `require('${requiredModuleName}') detected. Consider using the native ${alternative}` | ||
}); | ||
} | ||
} else if ((objectName === '_' || objectName === 'lodash' || objectName === 'underscore') && callee.property && callee.property.name === rule) { | ||
context.report({ | ||
@@ -26,3 +65,16 @@ node, | ||
ImportDeclaration(node) { | ||
if (forbiddenImports.indexOf(node.source.value) !== -1) { | ||
if (node.source.value === 'lodash') { | ||
// ex: import { indexOf } from 'lodash'; | ||
// ex: import { indexOf as x } from 'lodash'; | ||
node.specifiers.forEach(specifier => { | ||
if (specifier.type === 'ImportSpecifier' && specifier.imported.name === rule) { | ||
context.report({ | ||
node, | ||
message: `Import { ${rule} } from '${node.source.value}' detected. Consider using the native ${alternative}` | ||
}); | ||
} | ||
}); | ||
} else if (forbiddenImports.hasOwnProperty(node.source.value)) { | ||
// ex: import indexOf from 'lodash/indexOf'; | ||
// ex: import indexOf from 'lodash.indexof'; | ||
context.report({ | ||
@@ -29,0 +81,0 @@ node, |
@@ -157,2 +157,7 @@ { | ||
}, | ||
"isNil": { | ||
"ruleName": "is-nil", | ||
"compatible": true, | ||
"alternative": "value === null || value === undefined" | ||
}, | ||
"isNull": { | ||
@@ -223,2 +228,12 @@ "ruleName": "is-null", | ||
}, | ||
"padStart": { | ||
"compatible": true, | ||
"alternative": "String.prototype.padStart()", | ||
"ES6": true | ||
}, | ||
"padEnd": { | ||
"compatible": true, | ||
"alternative": "String.prototype.padEnd()", | ||
"ES6": true | ||
}, | ||
"repeat": { | ||
@@ -225,0 +240,0 @@ "compatible": true, |
{ | ||
"name": "eslint-plugin-you-dont-need-lodash-underscore", | ||
"version": "6.5.0", | ||
"version": "6.6.0", | ||
"description": "Check methods you can use natively without lodash/underscore", | ||
@@ -33,3 +33,3 @@ "repository": { | ||
"coveralls": "^2.11.9", | ||
"eslint": "^3.0.0", | ||
"eslint": "^4.18.2", | ||
"istanbul": "^0.4.4", | ||
@@ -36,0 +36,0 @@ "lodash": "^4.17.4", |
@@ -7,3 +7,3 @@ 'use strict'; | ||
assert.equal(Object.keys(allRules).length, 54, 'Don\'t miss a rule 😄'); | ||
assert.equal(Object.keys(allRules).length, 57, 'Don\'t miss a rule 😄'); | ||
@@ -23,8 +23,2 @@ const ruleTester = new RuleTester({ | ||
errors: ['Consider using the native Array.prototype.concat()'] | ||
}, { | ||
code: "import concat from 'lodash/concat';", | ||
errors: ["Import from 'lodash/concat' detected. Consider using the native Array.prototype.concat()"] | ||
}, { | ||
code: "import concat from 'lodash.concat';", | ||
errors: ["Import from 'lodash.concat' detected. Consider using the native Array.prototype.concat()"] | ||
}] | ||
@@ -40,8 +34,28 @@ }); | ||
errors: ['Consider using the native Object.keys()'] | ||
}] | ||
}); | ||
ruleTester.run(`Import lodash.isnan`, rules['is-nan'], { | ||
valid: [`{ x: require('lodash') }`], | ||
invalid: [{ | ||
code: `import isNaN from 'lodash/isNaN';`, | ||
errors: [`Import from 'lodash/isNaN' detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: "import concat from 'lodash/keys';", | ||
errors: ["Import from 'lodash/keys' detected. Consider using the native Object.keys()"] | ||
code: `import isNaN from 'lodash.isnan';`, | ||
errors: [`Import from 'lodash.isnan' detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: "import concat from 'lodash.keys';", | ||
errors: ["Import from 'lodash.keys' detected. Consider using the native Object.keys()"] | ||
code: `import { isNaN as x } from 'lodash';`, | ||
errors: [`Import { isNaN } from 'lodash' detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: `const { isNaN: x } = require('lodash');`, | ||
errors: [`{ isNaN } = require('lodash') detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: `({ isNaN: x } = require('lodash'));`, | ||
errors: [`{ isNaN } = require('lodash') detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: `require('lodash/isNaN');`, | ||
errors: [`require('lodash/isNaN') detected. Consider using the native Number.isNaN()`] | ||
}, { | ||
code: `require('lodash.isnan');`, | ||
errors: [`require('lodash.isnan') detected. Consider using the native Number.isNaN()`] | ||
}] | ||
@@ -57,8 +71,2 @@ }); | ||
errors: ['Consider using the native Array.prototype.forEach()'] | ||
}, { | ||
code: "import concat from 'lodash/forEach';", | ||
errors: ["Import from 'lodash/forEach' detected. Consider using the native Array.prototype.forEach()"] | ||
}, { | ||
code: "import concat from 'lodash.foreach';", | ||
errors: ["Import from 'lodash.foreach' detected. Consider using the native Array.prototype.forEach()"] | ||
}] | ||
@@ -74,8 +82,2 @@ }); | ||
errors: ['Consider using the native Number.isNaN()'] | ||
}, { | ||
code: "import concat from 'lodash/isNaN';", | ||
errors: ["Import from 'lodash/isNaN' detected. Consider using the native Number.isNaN()"] | ||
}, { | ||
code: "import concat from 'lodash.isnan';", | ||
errors: ["Import from 'lodash.isnan' detected. Consider using the native Number.isNaN()"] | ||
}] | ||
@@ -82,0 +84,0 @@ }); |
@@ -118,2 +118,3 @@ 'use strict'; | ||
}) | ||
describe('assign', () => { | ||
@@ -208,8 +209,8 @@ function Foo() { | ||
describe('get', () => { | ||
// add array notation | ||
const get = (obj, path, defaultValue = null) => | ||
String.prototype.split.call(path, /[,[\].]+?/) | ||
const get = (obj, path, defaultValue) => { | ||
const result = String.prototype.split.call(path, /[,[\].]+?/) | ||
.filter(Boolean) | ||
.reduce((a, c) => (Object.hasOwnProperty.call(a,c) ? a[c] : defaultValue), obj) | ||
.reduce((res, key) => (res !== null && res !== undefined) ? res[key] : res, obj); | ||
return (result === undefined || result === obj) ? defaultValue : result; | ||
} | ||
var obj = { aa: [{ b: { c: 0 }, 1: 0 }], dd: { ee: { ff: 2 } } }; | ||
@@ -219,3 +220,3 @@ | ||
var val = _.get(obj, 'aa[0].b.c', 1) | ||
assert.equal(val, get(obj, 'aa[0].b.c', 1)) | ||
assert.strictEqual(val, get(obj, 'aa[0].b.c', 1)) | ||
assert.notEqual(val, 1) | ||
@@ -225,3 +226,3 @@ }) | ||
var val = _.get(obj, 'aa[0][1]', 1) | ||
assert.equal(val, get(obj, 'aa[0][1]', 1)) | ||
assert.strictEqual(val, get(obj, 'aa[0][1]', 1)) | ||
assert.notEqual(val, 1) | ||
@@ -231,3 +232,3 @@ }) | ||
var val = _.get(obj, 'dd.ee.ff', 1) | ||
assert.equal(val, get(obj, 'dd.ee.ff', 1)) | ||
assert.strictEqual(val, get(obj, 'dd.ee.ff', 1)) | ||
assert.notEqual(val, 1) | ||
@@ -242,3 +243,3 @@ }) | ||
var val = _.get(obj, 'aa[0].b.c', 1) | ||
assert.equal(val, get(obj, 'aa[0].b.c', 1)) | ||
assert.strictEqual(val, get(obj, 'aa[0].b.c', 1)) | ||
assert.notEqual(val, 1) | ||
@@ -248,5 +249,36 @@ }) | ||
var val = _.get(obj, ['aa', [0], 'b', 'c'], 1) | ||
assert.equal(val, get(obj, ['aa', [0], 'b', 'c'], 1)) | ||
assert.strictEqual(val, get(obj, ['aa', [0], 'b', 'c'], 1)) | ||
assert.notEqual(val, 1) | ||
}) | ||
it ("should handle undefined without default", () => { | ||
var val = _.get(obj, 'dd.b') | ||
assert.strictEqual(val, get(obj, 'dd.b')) | ||
}) | ||
it ("should handle undefined with default", () => { | ||
var val = _.get(obj, 'dd.b', 1) | ||
assert.strictEqual(val, get(obj, 'dd.b', 1)) | ||
}) | ||
it ("should handle deep undefined without default", () => { | ||
var val = _.get(obj, 'dd.b.c') | ||
assert.strictEqual(val, get(obj, 'dd.b.c')) | ||
}) | ||
it ("should handle deep undefined with default", () => { | ||
var val = _.get(obj, 'dd.b.c', 1) | ||
assert.strictEqual(val, get(obj, 'dd.b.c', 1)) | ||
assert.strictEqual(val, 1); | ||
}) | ||
it ("should handle null default", () => { | ||
var val = _.get(obj, 'dd.b', null) | ||
assert.strictEqual(val, get(obj, 'dd.b', null)) | ||
assert.strictEqual(val, null); | ||
}) | ||
it ("should handle empty path", () => { | ||
var val = _.get(obj, '', 1) | ||
assert.strictEqual(val, get(obj, '', 1)) | ||
assert.notEqual(val, obj); | ||
}) | ||
it ("should handle undefined obj", () => { | ||
var val = _.get(undefined, 'aa') | ||
assert.strictEqual(val, get(undefined, 'aa')) | ||
}) | ||
}) | ||
@@ -258,3 +290,3 @@ describe('split', () => { | ||
it(`_.split("${source}", "${separator}")`, () => { | ||
assert.equal( | ||
assert.deepEqual( | ||
_.split(source, separator), | ||
@@ -265,3 +297,3 @@ source.split(separator) | ||
it(`_.split("${source}", "${separator}", ${limit})`, () => { | ||
assert.equal( | ||
assert.deepEqual( | ||
_.split(source, separator, limit), | ||
@@ -337,2 +369,90 @@ source.split(separator, limit) | ||
}) | ||
describe('random', () => { | ||
const random = (lower, upper) => { | ||
if(!upper || typeof upper === 'boolean') { | ||
upper = lower; | ||
lower = 0; | ||
} | ||
let randomic = Math.random() * upper; | ||
return randomic >= lower ? randomic : random(lower, upper); | ||
} | ||
it('_.random(0, 5)', () => { | ||
assert(random(0, 5) >= 0 && random(0, 5) <= 5); | ||
}); | ||
it('_.random(5)', () => { | ||
assert(random(5) >= 0 && random(5) <= 5); | ||
}); | ||
it('_.random(5, true)', () => { | ||
assert(random(5, true) >= 0 && random(5, true) <= 5); | ||
}); | ||
it('_.random(1.2, 5.2)', () => { | ||
assert(random(1.2, 5.2) >= 1.2 && random(1,2, 5.2) <= 5.2); | ||
}); | ||
}); | ||
describe('padStart', () => { | ||
it('_.padStart("123", 5, "0")', () => { | ||
assert.equal( | ||
_.padStart("123", 5, '0'), | ||
"123".padStart(5, '0') | ||
); | ||
}) | ||
it('_.padStart("123", 6, "_-")', () => { | ||
assert.equal( | ||
_.padStart("123", 6, '_-'), | ||
"123".padStart(6, '_-') | ||
); | ||
}) | ||
}) | ||
describe('padEnd', () => { | ||
it('_.padEnd("123", 5, "0")', () => { | ||
assert.equal( | ||
_.padEnd("123", 5, '0'), | ||
"123".padEnd(5, '0') | ||
); | ||
}) | ||
it('_.padEnd("123", 6, "_-")', () => { | ||
assert.equal( | ||
_.padEnd("123", 6, '_-'), | ||
"123".padEnd(6, '_-') | ||
); | ||
}) | ||
}) | ||
describe('upperFirst', () => { | ||
const upperFirst = (string) => { | ||
return string ? string.charAt(0).toUpperCase() + string.slice(1) : '' | ||
} | ||
it('_.upperFirst("george")', () => { | ||
assert.equal( | ||
_.upperFirst('george'), | ||
upperFirst('george') | ||
) | ||
}) | ||
it('_.upperFirst(null)', () => { | ||
assert.equal( | ||
_.upperFirst(null), | ||
upperFirst(null) | ||
) | ||
}) | ||
it('_.upperFirst("")', () => { | ||
assert.equal( | ||
_.upperFirst(''), | ||
upperFirst('') | ||
) | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
163324
14
905
2569