diff --git a/lib/isReactReduxConnect.js b/lib/isReactReduxConnect.js index 258d71b..7372b06 100644 --- a/lib/isReactReduxConnect.js +++ b/lib/isReactReduxConnect.js @@ -1,5 +1,17 @@ -module.exports = function (node) { - return ( - node.callee.name === 'connect' - ); +module.exports = function (node, context) { + if (node.callee.type === 'Identifier' && node.callee.name === 'connect') { + const sourceCode = context.getSourceCode(); + const scope = sourceCode.getScope(node); + const variable = scope.variables.find(v => v.name === 'connect'); + if (variable && variable.defs.length > 0) { + const def = variable.defs[0]; + if ( + (def.node.type === 'ImportSpecifier' && def.parent.source.value === 'react-redux') || + (def.node.type === 'VariableDeclarator' && def.node.init && def.node.init.callee && def.node.init.callee.name === 'require' && def.node.init.arguments[0].value === 'react-redux') + ) { + return true; + } + } + } + return false; }; diff --git a/lib/rules/connect-prefer-minimum-two-arguments.js b/lib/rules/connect-prefer-minimum-two-arguments.js index 4ca47df..b85919f 100644 --- a/lib/rules/connect-prefer-minimum-two-arguments.js +++ b/lib/rules/connect-prefer-minimum-two-arguments.js @@ -10,7 +10,7 @@ const create = function (context) { return { CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { if (node.arguments.length < 2) { report(node); } diff --git a/lib/rules/connect-prefer-named-arguments.js b/lib/rules/connect-prefer-named-arguments.js index 26ea816..53d3767 100644 --- a/lib/rules/connect-prefer-named-arguments.js +++ b/lib/rules/connect-prefer-named-arguments.js @@ -17,7 +17,7 @@ const create = function (context) { return { CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { node.arguments.forEach((argument, i) => { if (argument.raw && argument.raw !== 'null') { report(node, i); diff --git a/lib/rules/mapDispatchToProps-prefer-parameters-names.js b/lib/rules/mapDispatchToProps-prefer-parameters-names.js index 10f446a..76e2809 100644 --- a/lib/rules/mapDispatchToProps-prefer-parameters-names.js +++ b/lib/rules/mapDispatchToProps-prefer-parameters-names.js @@ -40,7 +40,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapDispatchToProps = node.arguments && node.arguments[1]; if (mapDispatchToProps && ( mapDispatchToProps.type === 'ArrowFunctionExpression' || diff --git a/lib/rules/mapDispatchToProps-prefer-shorthand.js b/lib/rules/mapDispatchToProps-prefer-shorthand.js index cfbd9da..0d98d2f 100644 --- a/lib/rules/mapDispatchToProps-prefer-shorthand.js +++ b/lib/rules/mapDispatchToProps-prefer-shorthand.js @@ -71,7 +71,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapDispatchToProps = node.arguments && node.arguments[1]; if (mapDispatchToProps && ( mapDispatchToProps.type === 'ArrowFunctionExpression' || diff --git a/lib/rules/mapDispatchToProps-returns-object.js b/lib/rules/mapDispatchToProps-returns-object.js index 202775a..3c65199 100644 --- a/lib/rules/mapDispatchToProps-returns-object.js +++ b/lib/rules/mapDispatchToProps-returns-object.js @@ -34,7 +34,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapDispatchToProps = node.arguments && node.arguments[1]; if (mapDispatchToProps && ( mapDispatchToProps.type === 'ArrowFunctionExpression' || diff --git a/lib/rules/mapStateToProps-no-store.js b/lib/rules/mapStateToProps-no-store.js index c9dd284..4da636c 100644 --- a/lib/rules/mapStateToProps-no-store.js +++ b/lib/rules/mapStateToProps-no-store.js @@ -66,7 +66,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapStateToProps = node.arguments && node.arguments[0]; if (mapStateToProps && mapStateToProps.body) { const firstParamName = getFirstParamName(mapStateToProps); diff --git a/lib/rules/mapStateToProps-prefer-hoisted.js b/lib/rules/mapStateToProps-prefer-hoisted.js index ecb48cb..3814e78 100644 --- a/lib/rules/mapStateToProps-prefer-hoisted.js +++ b/lib/rules/mapStateToProps-prefer-hoisted.js @@ -52,7 +52,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapStateToProps = node.arguments && node.arguments[0]; if (mapStateToProps && mapStateToProps.body) { checkFunction(context, mapStateToProps.body); diff --git a/lib/rules/mapStateToProps-prefer-parameters-names.js b/lib/rules/mapStateToProps-prefer-parameters-names.js index cf8d78e..2b2b11d 100644 --- a/lib/rules/mapStateToProps-prefer-parameters-names.js +++ b/lib/rules/mapStateToProps-prefer-parameters-names.js @@ -40,7 +40,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapStateToProps = node.arguments && node.arguments[0]; if (mapStateToProps && ( mapStateToProps.type === 'ArrowFunctionExpression' || diff --git a/lib/rules/mapStateToProps-prefer-selectors.js b/lib/rules/mapStateToProps-prefer-selectors.js index 8943ea8..b0fc4bd 100644 --- a/lib/rules/mapStateToProps-prefer-selectors.js +++ b/lib/rules/mapStateToProps-prefer-selectors.js @@ -83,7 +83,7 @@ const create = function (context) { } }, CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const mapStateToProps = node.arguments && node.arguments[0]; if (mapStateToProps && ( mapStateToProps.type === 'ArrowFunctionExpression' || diff --git a/lib/rules/no-unused-prop-types.js b/lib/rules/no-unused-prop-types.js index d9a4c0c..0b4a1bd 100644 --- a/lib/rules/no-unused-prop-types.js +++ b/lib/rules/no-unused-prop-types.js @@ -33,7 +33,7 @@ const belongsToReduxReact = (node, objectName, destrArg) => { } } } else if (node.type === 'CallExpression') { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const check = (mapToProps) => { if (mapToProps && mapToProps.body) { const secondArgument = mapToProps.params && mapToProps.params[1]; @@ -85,4 +85,4 @@ const getPropNameFromReduxRuleMessage = message => message.replace('exclude:', ' module.exports = filterReports([ propsUsedInRedux, noUnusedPropTypesReact, -], getPropNameFromReactRuleMessage, getPropNameFromReduxRuleMessage); \ No newline at end of file +], getPropNameFromReactRuleMessage, getPropNameFromReduxRuleMessage); diff --git a/lib/rules/prefer-separate-component-file.js b/lib/rules/prefer-separate-component-file.js index 798d9e2..4e71557 100644 --- a/lib/rules/prefer-separate-component-file.js +++ b/lib/rules/prefer-separate-component-file.js @@ -12,7 +12,7 @@ module.exports = { const sourceCode = context.sourceCode ?? context.getSourceCode(); return { CallExpression(node) { - if (isReactReduxConnect(node)) { + if (isReactReduxConnect(node, context)) { const component = node.parent && node.parent.arguments && diff --git a/tests/lib/rules/connect-prefer-minimum-two-arguments.js b/tests/lib/rules/connect-prefer-minimum-two-arguments.js index 0f13d6f..1c4c797 100644 --- a/tests/lib/rules/connect-prefer-minimum-two-arguments.js +++ b/tests/lib/rules/connect-prefer-minimum-two-arguments.js @@ -13,12 +13,12 @@ const ruleTester = new RuleTester( parserOptions ); ruleTester.run('connect-prefer-minimum-two-arguments', rule, { valid: [ ...codeSamples, - 'connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(Component)', - 'connect(mapStateToProps, mapDispatchToProps)(Component)', - 'connect({prop1, prop2}, {action1, action2})(Component)', + `import { connect } from 'react-redux'; connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(Component)`, + `import { connect } from 'react-redux'; connect(mapStateToProps, mapDispatchToProps)(Component)`, + `import { connect } from 'react-redux'; connect({prop1, prop2}, {action1, action2})(Component)`, ], invalid: [{ - code: 'connect(mapStateToProps)(Component)', + code: `import { connect } from 'react-redux'; connect(mapStateToProps)(Component)`, errors: [ { message: 'Connect function should have at least 2 arguments.', diff --git a/tests/lib/rules/connect-prefer-named-arguments.js b/tests/lib/rules/connect-prefer-named-arguments.js index 9a161c1..1f154c1 100644 --- a/tests/lib/rules/connect-prefer-named-arguments.js +++ b/tests/lib/rules/connect-prefer-named-arguments.js @@ -13,13 +13,16 @@ const ruleTester = new RuleTester( parserOptions ); ruleTester.run('connect-prefer-named-arguments', rule, { valid: [ ...codeSamples, - 'export default connect(null, mapDispatchToProps)(TodoApp)', - 'connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(Component)', - 'connect(mapStateToProps, mapDispatchToProps)(Component)', - 'connect()(TodoApp)', + `import { connect } from 'react-redux'; export default connect(null, mapDispatchToProps)(TodoApp)`, + `import { connect } from 'react-redux'; connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(Component)`, + `import { connect } from 'react-redux'; connect(mapStateToProps, mapDispatchToProps)(Component)`, + `import { connect } from 'react-redux'; connect()(TodoApp)`, + 'connect(() => {}, () => {}, mergeProps, options)(Component)', + 'connect({}, {})(Component)', + 'connect(state => state)(TodoApp)', ], invalid: [{ - code: 'connect(() => {}, () => {}, mergeProps, options)(Component)', + code: `import { connect } from 'react-redux'; connect(() => {}, () => {}, mergeProps, options)(Component)`, errors: [ { message: 'Connect function argument #1 should be named mapStateToProps', @@ -28,7 +31,7 @@ ruleTester.run('connect-prefer-named-arguments', rule, { }, ], }, { - code: 'connect({}, {})(Component)', + code: `import { connect } from 'react-redux'; connect({}, {})(Component)`, errors: [ { message: 'Connect function argument #1 should be named mapStateToProps', @@ -37,7 +40,7 @@ ruleTester.run('connect-prefer-named-arguments', rule, { }, ], }, { - code: 'connect(state => state)(TodoApp)', + code: `import { connect } from 'react-redux'; connect(state => state)(TodoApp)`, errors: [ { message: 'Connect function argument #1 should be named mapStateToProps', diff --git a/tests/lib/rules/mapDispatchToProps-prefer-parameters-names.js b/tests/lib/rules/mapDispatchToProps-prefer-parameters-names.js index de72bec..77a7c71 100644 --- a/tests/lib/rules/mapDispatchToProps-prefer-parameters-names.js +++ b/tests/lib/rules/mapDispatchToProps-prefer-parameters-names.js @@ -18,11 +18,12 @@ ruleTester.run('mapDispatchToProps-prefer-parameters-names', rule, { 'const mapDispatchToProps = (dispatch) => {}', 'const mapDispatchToProps = (dispatch, ownProps, moreArgs) => {}', 'const mapDispatchToProps = {anAction: anAction}', - 'connect((state) => state, {anAction: anAction})(App)', - 'connect(null, null)(App)', - 'connect((state) => state, (dispatch, ownProps, moreArgs) => {})(App)', + `import { connect } from 'react-redux'; connect((state) => state, {anAction: anAction})(App)`, + `import { connect } from 'react-redux'; connect(null, null)(App)`, + `import { connect } from 'react-redux'; connect((state) => state, (dispatch, ownProps, moreArgs) => {})(App)`, + `import { connect } from './path/to/connect.js'; connect('something')`, + `import { connect } from './path/to/connect.js'; connect((state) => state, (anyOtherName) => {})(App)`, 'function mapDispatchToProps(dispatch, ownProps) {}', - ], invalid: [{ code: 'const mapDispatchToProps = (anyOtherName) => {}', @@ -48,7 +49,14 @@ ruleTester.run('mapDispatchToProps-prefer-parameters-names', rule, { }, ], }, { - code: 'connect((state) => state, (anyOtherName) => {})(App)', + code: `import { connect } from 'react-redux'; connect((state) => state, (anyOtherName) => {})(App)`, + errors: [ + { + message: 'mapDispatchToProps function parameter #0 should be named dispatch', + }, + ], + }, { + code: `const { connect } = require('react-redux'); connect((state) => state, (anyOtherName) => {})(App)`, errors: [ { message: 'mapDispatchToProps function parameter #0 should be named dispatch', diff --git a/tests/lib/rules/mapDispatchToProps-prefer-shorthand.js b/tests/lib/rules/mapDispatchToProps-prefer-shorthand.js index 9c7181d..3f0ae74 100644 --- a/tests/lib/rules/mapDispatchToProps-prefer-shorthand.js +++ b/tests/lib/rules/mapDispatchToProps-prefer-shorthand.js @@ -27,14 +27,15 @@ ruleTester.run('mapDispatchToProps-prefer-shorthand', rule, { 'const mapDispatchToProps = actionsMap', 'const mapDispatchToProps = {...actions}', 'const mapDispatchToProps = {anAction: anAction}', - `export default connect( + `import { connect } from 'react-redux'; + export default connect( state => ({ productsList: state.Products.productsList, }), { fetchProducts } )(Products); `, - 'connect(null, null)(App)', + `import { connect } from 'react-redux'; connect(null, null)(App)`, 'function mapDispatchToProps () {return aThing}', ], invalid: [{ diff --git a/tests/lib/rules/mapDispatchToProps-returns-object.js b/tests/lib/rules/mapDispatchToProps-returns-object.js index 0b04c6a..05c729c 100644 --- a/tests/lib/rules/mapDispatchToProps-returns-object.js +++ b/tests/lib/rules/mapDispatchToProps-returns-object.js @@ -17,7 +17,8 @@ ruleTester.run('mapDispatchToProps-returns-object', rule, { 'const mapDispatchToProps = actionsMap', 'const mapDispatchToProps = {...actions}', 'const mapDispatchToProps = {anAction: anAction}', - `export default connect( + `import { connect } from 'react-redux'; + export default connect( state => ({ productsList: state.Products.productsList, }), @@ -42,7 +43,7 @@ ruleTester.run('mapDispatchToProps-returns-object', rule, { } } }`, - 'connect(null, null)(App)', + `import { connect } from 'react-redux'; connect(null, null)(App)`, 'function mapDispatchToProps () {return aThing}', `function mapDispatchToProps(dispatch) { return { actions: bindActionCreators(actionCreators, dispatch) } @@ -63,7 +64,8 @@ ruleTester.run('mapDispatchToProps-returns-object', rule, { }, ], }, { - code: `export default connect( + code: `import { connect } from 'react-redux'; + export default connect( state => ({ productsList: state.Products.productsList, }), @@ -76,7 +78,8 @@ ruleTester.run('mapDispatchToProps-returns-object', rule, { }, ], }, { - code: `export default connect( + code: `import { connect } from 'react-redux'; + export default connect( state => ({ productsList: state.Products.productsList, }), diff --git a/tests/lib/rules/mapStateToProps-no-store.js b/tests/lib/rules/mapStateToProps-no-store.js index 1163384..e785945 100644 --- a/tests/lib/rules/mapStateToProps-no-store.js +++ b/tests/lib/rules/mapStateToProps-no-store.js @@ -29,11 +29,12 @@ ruleTester.run('mapStateToProps-no-store', rule, { }); `, 'export default function observeStore(store) {return store;}', - 'export default connect(() => {})(Alert)', - 'export default connect(null, null)(Alert)', - 'connect((state) => ({isActive: state.isActive}), null)(App)', - 'connect(null, null)(App)', - `connect( + `import { connect } from 'react-redux'; export default connect(() => {})(Alert)`, + `import { connect } from 'react-redux'; export default connect(null, null)(Alert)`, + `import { connect } from 'react-redux'; connect((state) => ({isActive: state.isActive}), null)(App)`, + `import { connect } from 'react-redux'; connect(null, null)(App)`, + `import { connect } from 'react-redux'; + connect( (state) => { return { isActive: state.isActive @@ -42,7 +43,8 @@ ruleTester.run('mapStateToProps-no-store', rule, { null )(App) `, - `connect(function(state){ + `import { connect } from 'react-redux'; + connect(function(state){ return { isActive: state.isActive } @@ -58,14 +60,15 @@ ruleTester.run('mapStateToProps-no-store', rule, { }`, 'const mapStateToProps = (state, ownProps) => {}', 'const mapStateToProps = (state) => {isActive: state.isActive}', - `const mapStateToProps = (state, ownProps) => {}; + `import { connect } from 'react-redux'; + const mapStateToProps = (state, ownProps) => {}; connect(mapStateToProps, null)(Alert);`, `const mapStateToProps = ({ header }) => ({ isLoggedIn: header.user && header.user.isLoggedIn, }); `, 'const mapStateToProps = ({header}, ownProps) => {header};', - 'connect(({header}, ownProps) => {header})(App);', - 'connect(({header}, {ownProp1}) => {header, ownProp1})(App);', + `import { connect } from 'react-redux'; connect(({header}, ownProps) => {header})(App);`, + `import { connect } from 'react-redux'; connect(({header}, {ownProp1}) => {header, ownProp1})(App);`, ], invalid: [{ code: 'const mapStateToProps = (state) => state', @@ -93,7 +96,8 @@ ruleTester.run('mapStateToProps-no-store', rule, { }, ], }, { - code: `export default connect( + code: `import { connect } from 'react-redux'; + export default connect( (state) => { return { state: state @@ -111,14 +115,15 @@ ruleTester.run('mapStateToProps-no-store', rule, { }, ], }, { - code: 'connect((state) => state, null)(App)', + code: `import { connect } from 'react-redux'; connect((state) => state, null)(App)`, errors: [ { message: 'mapStateToProps should not return complete store object', }, ], }, { - code: `const mapStateToProps = (state, ownProps) => state; + code: `import { connect } from 'react-redux'; + const mapStateToProps = (state, ownProps) => state; connect(mapStateToProps, null)(Alert);`, errors: [ { @@ -133,7 +138,7 @@ ruleTester.run('mapStateToProps-no-store', rule, { }, ], }, { - code: 'connect((state) => ({...state}), null)(App)', + code: `import { connect } from 'react-redux'; connect((state) => ({...state}), null)(App)`, errors: [ { message: 'mapStateToProps should not return complete store object', diff --git a/tests/lib/rules/mapStateToProps-prefer-hoisted.js b/tests/lib/rules/mapStateToProps-prefer-hoisted.js index b6dfcbd..48fdba4 100644 --- a/tests/lib/rules/mapStateToProps-prefer-hoisted.js +++ b/tests/lib/rules/mapStateToProps-prefer-hoisted.js @@ -50,10 +50,11 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { }; }; `, - 'export default connect(null, null)(Alert)', - 'connect((state) => ({isActive: state.isActive}), null)(App)', - 'connect(null, null)(App)', - `connect( + `import { connect } from 'react-redux'; export default connect(null, null)(Alert)`, + `import { connect } from 'react-redux'; connect((state) => ({isActive: state.isActive}), null)(App)`, + `import { connect } from 'react-redux'; connect(null, null)(App)`, + `import { connect } from 'react-redux'; + connect( (state) => { return { isActive: state.isActive @@ -62,7 +63,8 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { null )(App) `, - `connect(function(state){ + `import { connect } from 'react-redux'; + connect(function(state){ return { isActive: state.isActive } @@ -77,14 +79,15 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { }`, 'const mapStateToProps = (state, ownProps) => {}', 'const mapStateToProps = (state) => {set: [1, 2, 3, state.a]}', - `const mapStateToProps = (state, ownProps) => {}; + `import { connect } from 'react-redux'; + const mapStateToProps = (state, ownProps) => {}; connect(mapStateToProps, null)(Alert);`, `const mapStateToProps = ({ header }) => ({ isLoggedIn: header.user && header.user.isLoggedIn, }); `, 'const mapStateToProps = ({header}, ownProps) => {header};', - 'connect(({header}, ownProps) => {header})(App);', - 'connect(({header}, {ownProp1}) => {header, ownProp1})(App);', + `import { connect } from 'react-redux'; connect(({header}, ownProps) => {header})(App);`, + `import { connect } from 'react-redux'; connect(({header}, {ownProp1}) => {header, ownProp1})(App);`, `const mapStateToProps = ({header}, ownProps) => { return { props: { @@ -92,7 +95,8 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { } } };`, - `const createConnectedToolbarItem = (icon, onClick) => { + `import { connect } from 'react-redux'; + const createConnectedToolbarItem = (icon, onClick) => { const mapStateToProps = { onClick } connect( @@ -137,7 +141,8 @@ ruleTester.run('mapStateToProps-prefer-hoisted', rule, { }, ], }, { - code: `export default connect( + code: `import { connect } from 'react-redux'; + export default connect( (state) => { return { a: { diff --git a/tests/lib/rules/mapStateToProps-prefer-parameters-names.js b/tests/lib/rules/mapStateToProps-prefer-parameters-names.js index 103eb78..45ccf7f 100644 --- a/tests/lib/rules/mapStateToProps-prefer-parameters-names.js +++ b/tests/lib/rules/mapStateToProps-prefer-parameters-names.js @@ -16,11 +16,11 @@ ruleTester.run('mapStateToProps-prefer-parameters-names', rule, { 'const mapStateToProps = (state, ownProps) => {}', 'const mapStateToProps = (state) => {}', 'const mapStateToProps = (state, ownProps, moreArgs) => {}', - 'connect((state) => state, null)(App)', + `import { connect } from 'react-redux'; connect((state) => state, null)(App)`, 'function mapStateToProps(state, ownProps) {}', - 'connect({state}, null)(App)', + `import { connect } from 'react-redux'; connect({state}, null)(App)`, 'const mapStateToProps = {}', - 'connect(null, null)(App)', + `import { connect } from 'react-redux'; connect(null, null)(App)`, 'const mapStateToProps = ({prop1, prop2}, ownProps) => {}', ], invalid: [{ @@ -40,7 +40,7 @@ ruleTester.run('mapStateToProps-prefer-parameters-names', rule, { }, ], }, { - code: 'connect(function(anyOtherName) {}, null)(App)', + code: `import { connect } from 'react-redux'; connect(function(anyOtherName) {}, null)(App)`, errors: [ { message: 'mapStateToProps function parameter #0 should be named state', diff --git a/tests/lib/rules/mapStateToProps-prefer-selectors.js b/tests/lib/rules/mapStateToProps-prefer-selectors.js index f82dd2d..602f3e1 100644 --- a/tests/lib/rules/mapStateToProps-prefer-selectors.js +++ b/tests/lib/rules/mapStateToProps-prefer-selectors.js @@ -22,13 +22,13 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { 'const mapStateToProps = (state) => { doSomethingElse(); return { x: xSelector(state) }; }', 'const mapStateToProps = function(state) { return { x: xSelector(state) }; }', 'function mapStateToProps(state) { doSomethingElse(); return { x: xSelector(state) }; }', - 'connect((state) => ({ x: xSelector(state) }), {})(Comp)', + `import { connect } from 'react-redux'; connect((state) => ({ x: xSelector(state) }), {})(Comp)`, 'const mapStateToProps = () => ({ x: xSelector() })', 'const mapStateToProps = function(state) { return { x: getX() }; }', 'const mapStateToProps = function(state) { return { x: getX(state) }; }', - 'connect((state, ownProps) => ({ x: selector() }), {})(Comp)', - 'connect((state, ownProps) => ({ x: selector(state) }), {})(Comp)', - 'connect((state, ownProps) => ({ x: selector(state, ownProps) }), {})(Comp)', + `import { connect } from 'react-redux'; connect((state, ownProps) => ({ x: selector() }), {})(Comp)`, + `import { connect } from 'react-redux'; connect((state, ownProps) => ({ x: selector(state) }), {})(Comp)`, + `import { connect } from 'react-redux'; connect((state, ownProps) => ({ x: selector(state, ownProps) }), {})(Comp)`, { code: 'const mapStateToProps = (state) => ({ x: xSelector(state) })', options: [{ @@ -42,7 +42,7 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { }], }, { - code: 'connect((state) => ({ x: selector(state) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state) => ({ x: selector(state) }), {})(Comp)`, options: [{ matching: '^selector$', }], @@ -60,7 +60,7 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { }], }, { - code: 'connect(() => ({ x: selector(state) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect(() => ({ x: selector(state) }), {})(Comp)`, options: [{ validateParams: false, }], @@ -119,7 +119,7 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { }, ], }, { - code: 'connect((state) => ({ x: state.x }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state) => ({ x: state.x }), {})(Comp)`, errors: [ { message: 'mapStateToProps property "x" should use a selector function.', @@ -142,7 +142,7 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { message: 'mapStateToProps "x"\'s selector "getX" does not match "^.*Selector$".', }], }, { - code: 'connect((state) => ({ x: selectorr(state) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state) => ({ x: selectorr(state) }), {})(Comp)`, options: [{ matching: '^selector$', }], @@ -165,17 +165,17 @@ ruleTester.run('mapStateToProps-prefer-selectors', rule, { message: 'mapStateToProps "x"\'s selector "getX" parameter #0 should be "state".', }], }, { - code: 'connect((state, ownProps) => ({ x: getX(state, notOwnProps) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state, ownProps) => ({ x: getX(state, notOwnProps) }), {})(Comp)`, errors: [{ message: 'mapStateToProps "x"\'s selector "getX" parameter #1 should be "ownProps".', }], }, { - code: 'connect((state2, ownProps) => ({ x: getX(state) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state2, ownProps) => ({ x: getX(state) }), {})(Comp)`, errors: [{ message: 'mapStateToProps "x"\'s selector "getX" parameter #0 should be "state2".', }], }, { - code: 'connect((state, ownProps2) => ({ x: getX(state, ownProps) }), {})(Comp)', + code: `import { connect } from 'react-redux'; connect((state, ownProps2) => ({ x: getX(state, ownProps) }), {})(Comp)`, errors: [{ message: 'mapStateToProps "x"\'s selector "getX" parameter #1 should be "ownProps2".', }], diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 166e083..16c200f 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -33,6 +33,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, `export const mapStateToProps = (state, ownProps) => { @@ -50,6 +51,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, `export const mapStateToProps = (state, ownProps) => ({ @@ -66,6 +68,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, `export const mapDispatchToProps = (state, ownProps) => ({ @@ -82,6 +85,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, `export const mapStateToProps = (state, {myProp}) => ({ myData: getMyData(state, myProp.z), @@ -97,6 +101,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, `const selectorFoo = (state) => ({isFetching: false, name: 'Foo', isDeleting: false, deltedId: ''}); const selectorBar = (state) => ({ isFetching: false, name: 'Bar'}); @@ -132,6 +137,7 @@ ruleTester.run('no-unused-prop-types', rule, { isFetchingBar: PropTypes.bool.isRequired, }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, ], invalid: [{ @@ -149,6 +155,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, errors: [ @@ -172,6 +179,7 @@ ruleTester.run('no-unused-prop-types', rule, { notUsedProp: PropTypes.string.isRequired, }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, errors: [ @@ -194,6 +202,7 @@ ruleTester.run('no-unused-prop-types', rule, { myProp: PropTypes.string.isRequired }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, errors: [ @@ -217,6 +226,7 @@ ruleTester.run('no-unused-prop-types', rule, { notUsedProp: PropTypes.string.isRequired, }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, errors: [ @@ -241,6 +251,7 @@ ruleTester.run('no-unused-prop-types', rule, { notUsedProp: PropTypes.string.isRequired, }; + import { connect } from 'react-redux'; export default connect(mapStateToProps)(MyComponent);`, errors: [ diff --git a/tests/lib/rules/prefer-separate-component-file.js b/tests/lib/rules/prefer-separate-component-file.js index 27bc9e5..ce689de 100644 --- a/tests/lib/rules/prefer-separate-component-file.js +++ b/tests/lib/rules/prefer-separate-component-file.js @@ -12,15 +12,19 @@ const ruleTester = new RuleTester(parserOptions); ruleTester.run('prefer-separate-component-file', rule, { valid: [ ...codeSamples, - ` import Component from './component'; + `import { connect } from 'react-redux'; + import Component from './component'; + connect(mapStateToProps, mapDispatchToProps)(Component)`, + `import { connect } from 'react-redux'; + const Component = require('./component') + connect(mapStateToProps, mapDispatchToProps)(Component)`, + `import { connect } from 'react-redux'; + import {Component} from './component'; connect(mapStateToProps, mapDispatchToProps)(Component)`, - `const Component = require('./component') - connect(mapStateToProps, mapDispatchToProps)(Component)`, - `import {Component} from './component'; - connect(mapStateToProps, mapDispatchToProps)(Component)`, ], invalid: [{ - code: `const Component = () => {}; + code: `import { connect } from 'react-redux'; + const Component = () => {}; connect(mapStateToProps, null)(Component)`, errors: [ {