Skip to content

Commit 57a59cd

Browse files
committed
Merge pull request #502 from shmuga/require-render-return
Add require-render-return rule (fixes #482)
2 parents 271f9d2 + 08800fe commit 57a59cd

File tree

3 files changed

+130
-1
lines changed

3 files changed

+130
-1
lines changed

index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ module.exports = {
4141
'prefer-es6-class': require('./lib/rules/prefer-es6-class'),
4242
'jsx-key': require('./lib/rules/jsx-key'),
4343
'no-string-refs': require('./lib/rules/no-string-refs'),
44-
'prefer-stateless-function': require('./lib/rules/prefer-stateless-function')
44+
'prefer-stateless-function': require('./lib/rules/prefer-stateless-function'),
45+
'require-render-return': require('./lib/rules/require-render-return')
4546
},
4647
configs: {
4748
recommended: {

lib/rules/require-render-return.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* @fileoverview Enforce ES5 or ES6 class for returning value in render function.
3+
* @author Mark Orel
4+
*/
5+
'use strict';
6+
7+
var Components = require('../util/Components');
8+
9+
// ------------------------------------------------------------------------------
10+
// Rule Definition
11+
// ------------------------------------------------------------------------------
12+
13+
module.exports = Components.detect(function(context) {
14+
/**
15+
* Helper for checking if parent node is render method.
16+
* @param {ASTNode} node to check
17+
* @returns {boolean} If previous node is method and name is render returns true, otherwise false;
18+
*/
19+
function checkParent(node) {
20+
return (node.parent.type === 'Property' || node.parent.type === 'MethodDefinition')
21+
&& node.parent.key
22+
&& node.parent.key.name === 'render';
23+
}
24+
25+
/**
26+
* Helper for checking if child node exists and if it's ReturnStatement
27+
* @param {ASTNode} node to check
28+
* @returns {boolean} True if ReturnStatement exists, otherwise false
29+
*/
30+
function checkReturnStatementExistence(node) {
31+
if (!node.body && !node.body.body && !node.body.body.length) {
32+
return false;
33+
}
34+
35+
var hasReturnStatement = node.body.body.some(function(elem) {
36+
return elem.type === 'ReturnStatement';
37+
});
38+
39+
return hasReturnStatement;
40+
}
41+
42+
43+
return {
44+
FunctionExpression: function(node) {
45+
if (checkParent(node) && !checkReturnStatementExistence(node)) {
46+
context.report({
47+
node: node,
48+
message: 'Your render method should have return statement'
49+
});
50+
}
51+
}
52+
};
53+
});
54+
55+
module.exports.schema = [{}];
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @fileoverview Enforce ES5 or ES6 class for returning value in render function.
3+
* @author Mark Orel
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
var rule = require('../../../lib/rules/require-render-return');
12+
var RuleTester = require('eslint').RuleTester;
13+
14+
var parserOptions = {
15+
ecmaVersion: 6,
16+
ecmaFeatures: {
17+
jsx: true
18+
}
19+
};
20+
21+
require('babel-eslint');
22+
23+
// ------------------------------------------------------------------------------
24+
// Tests
25+
// ------------------------------------------------------------------------------
26+
27+
var ruleTester = new RuleTester();
28+
ruleTester.run('require-render-return', rule, {
29+
30+
valid: [{
31+
code: [
32+
'class Hello extends React.Component {',
33+
' render() {',
34+
' return <div>Hello {this.props.name}</div>;',
35+
' }',
36+
'}'
37+
].join('\n'),
38+
parserOptions: parserOptions
39+
}, {
40+
code: [
41+
'var Hello = React.createClass({',
42+
' displayName: \'Hello\',',
43+
' render: function() {',
44+
' return <div></div>',
45+
' }',
46+
'});'
47+
].join('\n'),
48+
parserOptions: parserOptions
49+
}],
50+
51+
invalid: [{
52+
code: [
53+
'var Hello = React.createClass({',
54+
' displayName: \'Hello\',',
55+
' render: function() {}',
56+
'});'
57+
].join('\n'),
58+
parserOptions: parserOptions,
59+
errors: [{
60+
message: 'Your render method should have return statement'
61+
}]
62+
}, {
63+
code: [
64+
'class Hello extends React.Component {',
65+
' render() {} ',
66+
'}'
67+
].join('\n'),
68+
parserOptions: parserOptions,
69+
errors: [{
70+
message: 'Your render method should have return statement'
71+
}]
72+
}
73+
]});

0 commit comments

Comments
 (0)