eslint-plugin-react-redux
Advanced tools
Comparing version
const isReactReduxConnect = require('../isReactReduxConnect'); | ||
const report = function (context, node) { | ||
context.report({ | ||
message: 'Connect function should have at least 2 arguments.', | ||
node, | ||
}); | ||
}; | ||
const create = function (context) { | ||
const report = function (node) { | ||
context.report({ | ||
message: 'Connect function should have at least 2 arguments.', | ||
node, | ||
}); | ||
}; | ||
module.exports = function (context) { | ||
return { | ||
@@ -15,3 +15,3 @@ CallExpression(node) { | ||
if (node.arguments.length < 2) { | ||
report(context, node); | ||
report(node); | ||
} | ||
@@ -22,1 +22,5 @@ } | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -10,10 +10,10 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
const report = function (context, node, i) { | ||
context.report({ | ||
message: `Connect function argument #${i} should be named ${argumentNames[i]}`, | ||
node, | ||
}); | ||
}; | ||
const create = function (context) { | ||
const report = function (node, i) { | ||
context.report({ | ||
message: `Connect function argument #${i + 1} should be named ${argumentNames[i]}`, | ||
node, | ||
}); | ||
}; | ||
module.exports = function (context) { | ||
return { | ||
@@ -24,3 +24,3 @@ CallExpression(node) { | ||
if (argument.raw && argument.raw !== 'null') { | ||
report(context, node, i); | ||
report(node, i); | ||
} else if ( | ||
@@ -30,3 +30,3 @@ !argument.raw | ||
&& (!argument.name || argument.name !== argumentNames[i])) { | ||
report(context, node, i); | ||
report(node, i); | ||
} | ||
@@ -38,1 +38,5 @@ }); | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -23,3 +23,3 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -56,1 +56,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -11,4 +11,6 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
const getParamsString = (params, context) => | ||
params.map(param => context.getSource(param)).join(','); | ||
const getParamsString = (params, context) => { | ||
const sourceCode = context.sourceCode ?? context.getSourceCode(); | ||
return params.map(param => sourceCode.getText(param)).join(',') | ||
} | ||
@@ -18,3 +20,4 @@ | ||
const propName = prop.key && prop.key.name; | ||
const sourceCode = context.getSource(prop.value).replace(/(\r\n|\n|\r|\t| |;)/gm, ''); | ||
const sourceCodeImpl = context.sourceCode ?? context.getSourceCode(); | ||
const sourceCode = sourceCodeImpl.getText(prop.value).replace(/(\r\n|\n|\r|\t| |;)/gm, ''); | ||
if (prop.value && prop.value.type === 'ArrowFunctionExpression') { | ||
@@ -47,4 +50,3 @@ const fncDef = prop.value; | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -90,1 +92,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -11,4 +11,3 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -54,1 +53,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -47,3 +47,3 @@ const utils = require('../utils'); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -82,1 +82,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -32,3 +32,2 @@ const utils = require('../utils'); | ||
const checkFunction = function (context, body) { | ||
@@ -41,3 +40,3 @@ const returnNode = utils.getReturnNode(body); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -67,1 +66,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -23,3 +23,3 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
return { | ||
@@ -56,1 +56,5 @@ VariableDeclaration(node) { | ||
}; | ||
module.exports = { | ||
create, | ||
}; |
@@ -65,3 +65,3 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
module.exports = function (context) { | ||
const create = function (context) { | ||
const config = context.options[0] || {}; | ||
@@ -99,1 +99,12 @@ return { | ||
}; | ||
module.exports = { | ||
create, | ||
meta: { | ||
schema: { | ||
matching: { | ||
type: 'string' | ||
} | ||
} | ||
}, | ||
}; |
@@ -59,3 +59,3 @@ 'use strict'; | ||
const nodeName = node.object.name; | ||
const usedInReactRedux = context.getAncestors() | ||
const usedInReactRedux = context.getSourceCode().getAncestors(node) | ||
.some(ancestor => belongsToReduxReact(ancestor, nodeName)); | ||
@@ -67,3 +67,3 @@ if (usedInReactRedux) { | ||
ObjectPattern(node) { | ||
const usedInReactRedux = context.getAncestors() | ||
const usedInReactRedux = context.getSourceCode().getAncestors(node) | ||
.some(ancestor => belongsToReduxReact(ancestor, null, node)); | ||
@@ -90,2 +90,2 @@ if (usedInReactRedux) { | ||
noUnusedPropTypesReact, | ||
], getPropNameFromReactRuleMessage, getPropNameFromReduxRuleMessage); | ||
], getPropNameFromReactRuleMessage, getPropNameFromReduxRuleMessage); |
@@ -10,25 +10,28 @@ const isReactReduxConnect = require('../isReactReduxConnect'); | ||
module.exports = function (context) { | ||
return { | ||
CallExpression(node) { | ||
if (isReactReduxConnect(node)) { | ||
const component = | ||
node.parent && | ||
node.parent.arguments && | ||
node.parent.arguments[0]; | ||
if (component) { | ||
const vars = context.getScope().variables; | ||
vars.forEach((definedVar) => { | ||
if (component.name === definedVar.name) { | ||
definedVar.defs.forEach((def) => { | ||
if (!(def.type === 'ImportBinding' || context.getSource(def.node).includes('require'))) { | ||
report(context, component); | ||
} | ||
}); | ||
} | ||
}); | ||
module.exports = { | ||
create(context) { | ||
const sourceCode = context.sourceCode ?? context.getSourceCode(); | ||
return { | ||
CallExpression(node) { | ||
if (isReactReduxConnect(node)) { | ||
const component = | ||
node.parent && | ||
node.parent.arguments && | ||
node.parent.arguments[0]; | ||
if (component) { | ||
const vars = sourceCode.getScope(component).variables; | ||
vars.forEach((definedVar) => { | ||
if (component.name === definedVar.name) { | ||
definedVar.defs.forEach((def) => { | ||
if (!(def.type === 'ImportBinding' || sourceCode.getText(def.node).includes('require'))) { | ||
report(context, component); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
}, | ||
}; |
@@ -19,29 +19,38 @@ function isUseSelector(node, hookNames) { | ||
module.exports = function (context) { | ||
const config = context.options[0] || {}; | ||
let hookNames = ['useSelector', 'useAppSelector']; | ||
module.exports = { | ||
meta: { | ||
schema: { | ||
matching: { | ||
type: 'string' | ||
} | ||
} | ||
}, | ||
create(context) { | ||
const config = context.options[0] || {}; | ||
let hookNames = ['useSelector', 'useAppSelector']; | ||
// Ensure hookNames is an array | ||
if (config.hook) { | ||
hookNames = Array.isArray(config.hook) ? config.hook : [config.hook]; | ||
} | ||
// Ensure hookNames is an array | ||
if (config.hook) { | ||
hookNames = Array.isArray(config.hook) ? config.hook : [config.hook]; | ||
} | ||
return { | ||
CallExpression(node) { | ||
if (!isUseSelector(node, hookNames)) return; | ||
const selector = node.arguments && node.arguments[0]; | ||
if (selector && ( | ||
selector.type === 'ArrowFunctionExpression' || | ||
selector.type === 'FunctionExpression') | ||
) { | ||
reportNoSelector(context, node); | ||
} else if ( | ||
selector && selector.type === 'Identifier' && | ||
config.matching && | ||
!selector.name.match(new RegExp(config.matching)) | ||
) { | ||
reportWrongName(context, node, selector.name, config.matching); | ||
} | ||
}, | ||
}; | ||
return { | ||
CallExpression(node) { | ||
if (!isUseSelector(node, hookNames)) return; | ||
const selector = node.arguments && node.arguments[0]; | ||
if (selector && ( | ||
selector.type === 'ArrowFunctionExpression' || | ||
selector.type === 'FunctionExpression') | ||
) { | ||
reportNoSelector(context, node); | ||
} else if ( | ||
selector && selector.type === 'Identifier' && | ||
config.matching && | ||
!selector.name.match(new RegExp(config.matching)) | ||
) { | ||
reportWrongName(context, node, selector.name, config.matching); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
{ | ||
"name": "eslint-plugin-react-redux", | ||
"version": "4.1.0", | ||
"version": "4.2.0", | ||
"description": "Enforcing best practices for react-redux", | ||
@@ -25,3 +25,2 @@ "keywords": [ | ||
"@babel/core": "^7.17.0", | ||
"@babel/eslint-parser": "^7.17.0", | ||
"@commitlint/cli": "^6.0.2", | ||
@@ -31,4 +30,3 @@ "@commitlint/config-conventional": "^6.0.2", | ||
"babel-register": "^6.26.0", | ||
"eslint": "^8.8.0", | ||
"eslint-config-airbnb": "^16.1.0", | ||
"eslint": "^8 || ^9", | ||
"eslint-config-standard": "^11.0.0-beta.0", | ||
@@ -45,7 +43,7 @@ "eslint-plugin-import": "^2.25.4", | ||
"peerDependencies": { | ||
"eslint-plugin-react": "^7.28.0", | ||
"eslint": "^7 || ^8" | ||
"eslint-plugin-react": "^7.35.0", | ||
"eslint": "^7 || ^8 || ^9.7" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
"node": ">=18.0.0" | ||
}, | ||
@@ -57,5 +55,5 @@ "license": "ISC", | ||
"dependencies": { | ||
"eslint-plugin-react": "^7.28.0", | ||
"eslint-plugin-react": "^7.35.0", | ||
"eslint-rule-composer": "^0.3.0" | ||
} | ||
} |
@@ -13,7 +13,9 @@ const plugin = require('..'); | ||
it(`should export ${ruleName}`, () => { | ||
assert.equal( | ||
plugin.rules[ruleName], | ||
// eslint-disable-next-line | ||
require(path.join('../lib/rules', ruleName)) | ||
); | ||
if (ruleName !== 'no-unused-prop-types') { | ||
assert.equal( | ||
plugin.rules[ruleName], | ||
// eslint-disable-next-line | ||
require(path.join('../lib/rules', ruleName)) | ||
); | ||
} | ||
}); | ||
@@ -41,7 +43,9 @@ }); | ||
ruleFiles.forEach((ruleName) => { | ||
if (ruleName !== 'no-unused-prop-types') { | ||
const inDeprecatedRules = Boolean(plugin.deprecatedRules[ruleName]); | ||
const inAllConfig = Boolean(plugin.configs.all.rules[`react-redux/${ruleName}`]); | ||
assert(inDeprecatedRules || inAllConfig); | ||
} | ||
}); | ||
}); | ||
}); |
const rule = require('../../../lib/rules/connect-prefer-minimum-two-arguments'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester( parserOptions ); | ||
@@ -12,0 +13,0 @@ ruleTester.run('connect-prefer-minimum-two-arguments', rule, { |
const rule = require('../../../lib/rules/connect-prefer-named-arguments'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester( parserOptions ); | ||
@@ -24,5 +25,5 @@ ruleTester.run('connect-prefer-named-arguments', rule, { | ||
{ | ||
message: 'Connect function argument #0 should be named mapStateToProps', | ||
message: 'Connect function argument #1 should be named mapStateToProps', | ||
}, { | ||
message: 'Connect function argument #1 should be named mapDispatchToProps', | ||
message: 'Connect function argument #2 should be named mapDispatchToProps', | ||
}, | ||
@@ -34,5 +35,5 @@ ], | ||
{ | ||
message: 'Connect function argument #0 should be named mapStateToProps', | ||
message: 'Connect function argument #1 should be named mapStateToProps', | ||
}, { | ||
message: 'Connect function argument #1 should be named mapDispatchToProps', | ||
message: 'Connect function argument #2 should be named mapDispatchToProps', | ||
}, | ||
@@ -44,3 +45,3 @@ ], | ||
{ | ||
message: 'Connect function argument #0 should be named mapStateToProps', | ||
message: 'Connect function argument #1 should be named mapStateToProps', | ||
}, | ||
@@ -47,0 +48,0 @@ ], |
const rule = require('../../../lib/rules/mapDispatchToProps-prefer-parameters-names'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester( parserOptions ); | ||
@@ -12,0 +13,0 @@ ruleTester.run('mapDispatchToProps-prefer-parameters-names', rule, { |
const rule = require('../../../lib/rules/mapDispatchToProps-prefer-shorthand'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const ruleTester = new RuleTester( parserOptions ); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('mapDispatchToProps-prefer-shorthand', rule, { | ||
@@ -14,0 +14,0 @@ valid: [ |
const rule = require('../../../lib/rules/mapDispatchToProps-returns-object'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester( parserOptions ); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('mapDispatchToProps-returns-object', rule, { | ||
@@ -13,0 +13,0 @@ valid: [ |
@@ -5,12 +5,15 @@ | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
parserOptions: { | ||
ecmaFeatures: { | ||
jsx: true | ||
} | ||
} | ||
}); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester( parserOptions ); | ||
@@ -31,3 +34,2 @@ ruleTester.run('mapStateToProps-no-store', rule, { | ||
'export default connect(() => {})(Alert)', | ||
'export default connect(() => {})(Alert)', | ||
'export default connect(null, null)(Alert)', | ||
@@ -34,0 +36,0 @@ 'connect((state) => ({isActive: state.isActive}), null)(App)', |
@@ -5,11 +5,12 @@ | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const errorMessage = 'constant arrays and objects should be initialized outside of mapStateToProps'; | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester(parserOptions); | ||
@@ -16,0 +17,0 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { |
const rule = require('../../../lib/rules/mapStateToProps-prefer-parameters-names'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester(parserOptions); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('mapStateToProps-prefer-parameters-names', rule, { | ||
@@ -13,0 +13,0 @@ valid: [ |
const rule = require('../../../lib/rules/mapStateToProps-prefer-selectors'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
const ruleTester = new RuleTester(parserOptions); | ||
@@ -12,0 +13,0 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { |
@@ -5,14 +5,15 @@ | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
jsx: true | ||
} | ||
}); | ||
console.log(parserOptions); | ||
const ruleTester = new RuleTester(parserOptions); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('no-unused-prop-types', rule, { | ||
@@ -19,0 +20,0 @@ valid: [ |
const rule = require('../../../lib/rules/prefer-separate-component-file'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester(parserOptions); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('prefer-separate-component-file', rule, { | ||
@@ -13,0 +13,0 @@ valid: [ |
const rule = require('../../../lib/rules/useSelector-prefer-selectors'); | ||
const RuleTester = require('eslint').RuleTester; | ||
const codeSamples = require('../../code-sanity-samples'); | ||
const formatOptions = require('../../util'); | ||
const parserOptions = { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}; | ||
const parserOptions = formatOptions({ | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
}); | ||
const ruleTester = new RuleTester(parserOptions); | ||
const ruleTester = new RuleTester({ parserOptions }); | ||
ruleTester.run('useSelector-prefer-selectors', rule, { | ||
@@ -13,0 +13,0 @@ valid: [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
92227
3.08%15
-11.76%50
2.04%2189
4.29%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated