Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require return value in render function. Tests and rule. #502

Merged
merged 3 commits into from
Mar 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ module.exports = {
'prefer-es6-class': require('./lib/rules/prefer-es6-class'),
'jsx-key': require('./lib/rules/jsx-key'),
'no-string-refs': require('./lib/rules/no-string-refs'),
'prefer-stateless-function': require('./lib/rules/prefer-stateless-function')
'prefer-stateless-function': require('./lib/rules/prefer-stateless-function'),
'require-render-return': require('./lib/rules/require-render-return')
},
configs: {
recommended: {
Expand Down
55 changes: 55 additions & 0 deletions lib/rules/require-render-return.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* @fileoverview Enforce ES5 or ES6 class for returning value in render function.
* @author Mark Orel
*/
'use strict';

var Components = require('../util/Components');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = Components.detect(function(context) {
/**
* Helper for checking if parent node is render method.
* @param {ASTNode} node to check
* @returns {boolean} If previous node is method and name is render returns true, otherwise false;
*/
function checkParent(node) {
return (node.parent.type === 'Property' || node.parent.type === 'MethodDefinition')
&& node.parent.key
&& node.parent.key.name === 'render';
}

/**
* Helper for checking if child node exists and if it's ReturnStatement
* @param {ASTNode} node to check
* @returns {boolean} True if ReturnStatement exists, otherwise false
*/
function checkReturnStatementExistence(node) {
if (!node.body && !node.body.body && !node.body.body.length) {
return false;
}

var hasReturnStatement = node.body.body.some(function(elem) {
return elem.type === 'ReturnStatement';
});

return hasReturnStatement;
}


return {
FunctionExpression: function(node) {
if (checkParent(node) && !checkReturnStatementExistence(node)) {
context.report({
node: node,
message: 'Your render method should have return statement'
});
}
}
};
});

module.exports.schema = [{}];
73 changes: 73 additions & 0 deletions tests/lib/rules/require-render-return.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* @fileoverview Enforce ES5 or ES6 class for returning value in render function.
* @author Mark Orel
*/
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

var rule = require('../../../lib/rules/require-render-return');
var RuleTester = require('eslint').RuleTester;

var parserOptions = {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true
}
};

require('babel-eslint');

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

var ruleTester = new RuleTester();
ruleTester.run('require-render-return', rule, {

valid: [{
code: [
'class Hello extends React.Component {',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'var Hello = React.createClass({',
' displayName: \'Hello\',',
' render: function() {',
' return <div></div>',
' }',
'});'
].join('\n'),
parserOptions: parserOptions
}],

invalid: [{
code: [
'var Hello = React.createClass({',
' displayName: \'Hello\',',
' render: function() {}',
'});'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Your render method should have return statement'
}]
}, {
code: [
'class Hello extends React.Component {',
' render() {} ',
'}'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Your render method should have return statement'
}]
}
]});