Skip to content

Commit 3610e9d

Browse files
committed
Make wrap-multilines more granular
This adds an option for enabling/disabling wrap-multilines in the context of the enclosing expression. In facebook/react, we only care about jsx expressions in return statements: facebook/react#4007 (comment)
1 parent 92f33bc commit 3610e9d

File tree

3 files changed

+160
-85
lines changed

3 files changed

+160
-85
lines changed

docs/rules/wrap-multilines.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Prevent missing parentheses around multilines JSX (wrap-multilines)
1+
# Prevent missing parentheses around multiline JSX (wrap-multilines)
22

3-
Wrapping multilines JSX in parentheses can improve readability and/or convenience.
3+
Wrapping multiline JSX in parentheses can improve readability and/or convenience. It optionally takes a second parameter in the form of an object, containing places to apply the rule. By default, `"declaration"`, `"assignment"`, and `"return"` syntax is checked, but these can be explicitly disabled. Any syntax type missing in the object will follow the default behavior (become enabled).
44

55
## Rule Details
66

@@ -30,4 +30,15 @@ var Hello = React.createClass({
3030
);
3131
}
3232
});
33+
34+
// When [1, {declaration: false}]
35+
var hello;
36+
hello = <div>
37+
<p>Hello</p>
38+
</div>
39+
40+
// When [1, {declaration: true, assignment: false, return: true}]
41+
var world = <div>
42+
<p>World</p>
43+
</div>
3344
```

lib/rules/wrap-multilines.js

+36-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44
*/
55
'use strict';
66

7+
// ------------------------------------------------------------------------------
8+
// Constants
9+
// ------------------------------------------------------------------------------
10+
11+
var DEFAULTS = {
12+
declaration: true,
13+
assignment: true,
14+
return: true
15+
};
16+
717
// ------------------------------------------------------------------------------
818
// Rule Definition
919
// ------------------------------------------------------------------------------
@@ -33,23 +43,46 @@ module.exports = function(context) {
3343
}
3444
}
3545

46+
function isEnabled(type) {
47+
var userOptions = context.options[0] || {};
48+
if (({}).hasOwnProperty.call(userOptions, type)) {
49+
return userOptions[type];
50+
}
51+
return DEFAULTS[type];
52+
}
53+
3654
// --------------------------------------------------------------------------
3755
// Public
3856
// --------------------------------------------------------------------------
3957

4058
return {
4159

4260
VariableDeclarator: function(node) {
43-
check(node.init);
61+
if (isEnabled('declaration')) {
62+
check(node.init);
63+
}
4464
},
4565

4666
AssignmentExpression: function(node) {
47-
check(node.right);
67+
if (isEnabled('assignment')) {
68+
check(node.right);
69+
}
4870
},
4971

5072
ReturnStatement: function(node) {
51-
check(node.argument);
73+
if (isEnabled('return')) {
74+
check(node.argument);
75+
}
5276
}
5377
};
5478

5579
};
80+
81+
module.exports.schema = [{
82+
type: 'object',
83+
properties: {
84+
declaration: {type: 'boolean'},
85+
assignment: {type: 'boolean'},
86+
return: {type: 'boolean'}
87+
}
88+
}];

tests/lib/rules/wrap-multilines.js

+111-80
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,67 @@
1111
var eslint = require('eslint').linter;
1212
var ESLintTester = require('eslint-tester');
1313

14+
// ------------------------------------------------------------------------------
15+
// Code Snippets
16+
// ------------------------------------------------------------------------------
17+
18+
var RETURN_SINGLE_LINE = '\
19+
var Hello = React.createClass({\
20+
render: function() {\
21+
return <p>Hello {this.props.name}</p>;\
22+
}\
23+
});';
24+
25+
var RETURN_PAREN = '\
26+
var Hello = React.createClass({\
27+
render: function() {\
28+
return (\n\
29+
<div>\n\
30+
<p>Hello {this.props.name}</p>\n\
31+
</div>\n\
32+
);\
33+
}\
34+
});';
35+
36+
var RETURN_NO_PAREN = '\
37+
var Hello = React.createClass({\
38+
render: function() {\
39+
return <div>\n\
40+
<p>Hello {this.props.name}</p>\n\
41+
</div>;\
42+
}\
43+
});';
44+
45+
var DECLARATION_SINGLE_LINE = 'var hello = <p>Hello</p>;';
46+
47+
var DECLARATION_PAREN = '\
48+
var hello = (\n\
49+
<div>\n\
50+
<p>Hello</p>\n\
51+
</div>\n\
52+
);';
53+
54+
var DECLARATION_NO_PAREN = '\
55+
var hello = <div>\n\
56+
<p>Hello</p>\n\
57+
</div>;';
58+
59+
var ASSIGNMENT_SINGLE_LINE = 'var hello; hello = <p>Hello</p>;';
60+
61+
var ASSIGNMENT_PAREN = '\
62+
var hello;\
63+
hello = (\n\
64+
<div>\n\
65+
<p>Hello</p>\n\
66+
</div>\n\
67+
);';
68+
69+
var ASSIGNMENT_NO_PAREN = '\
70+
var hello;\
71+
hello = <div>\n\
72+
<p>Hello</p>\n\
73+
</div>;';
74+
1475
// ------------------------------------------------------------------------------
1576
// Tests
1677
// ------------------------------------------------------------------------------
@@ -20,97 +81,67 @@ eslintTester.addRuleTest('lib/rules/wrap-multilines', {
2081

2182
valid: [
2283
{
23-
code: '\
24-
var Hello = React.createClass({\
25-
render: function() {\
26-
return <p>Hello {this.props.name}</p>;\
27-
}\
28-
});',
29-
ecmaFeatures: {
30-
jsx: true
31-
}
84+
code: RETURN_SINGLE_LINE,
85+
ecmaFeatures: {jsx: true}
86+
}, {
87+
code: RETURN_PAREN,
88+
ecmaFeatures: {jsx: true}
89+
}, {
90+
code: RETURN_NO_PAREN,
91+
args: [1, {return: false}],
92+
ecmaFeatures: {jsx: true}
93+
}, {
94+
code: DECLARATION_SINGLE_LINE,
95+
ecmaFeatures: {jsx: true}
3296
}, {
33-
code: '\
34-
var Hello = React.createClass({\
35-
render: function() {\
36-
return (\n\
37-
<div>\n\
38-
<p>Hello {this.props.name}</p>\n\
39-
</div>\n\
40-
);\
41-
}\
42-
});',
43-
ecmaFeatures: {
44-
jsx: true
45-
}
97+
code: DECLARATION_PAREN,
98+
ecmaFeatures: {jsx: true}
4699
}, {
47-
code: 'var hello = <p>Hello</p>;',
48-
ecmaFeatures: {
49-
jsx: true
50-
}
100+
code: DECLARATION_NO_PAREN,
101+
args: [1, {declaration: false}],
102+
ecmaFeatures: {jsx: true}
51103
}, {
52-
code: '\
53-
var hello = (\n\
54-
<div>\n\
55-
<p>Hello</p>\n\
56-
</div>\n\
57-
);',
58-
ecmaFeatures: {
59-
jsx: true
60-
}
104+
code: ASSIGNMENT_SINGLE_LINE,
105+
args: [1, {declaration: false}],
106+
ecmaFeatures: {jsx: true}
61107
}, {
62-
code: '\
63-
var hello;\
64-
hello = (\n\
65-
<div>\n\
66-
<p>Hello</p>\n\
67-
</div>\n\
68-
);',
69-
ecmaFeatures: {
70-
jsx: true
71-
}
108+
code: ASSIGNMENT_PAREN,
109+
ecmaFeatures: {jsx: true}
110+
}, {
111+
code: ASSIGNMENT_NO_PAREN,
112+
args: [1, {assignment: false}],
113+
ecmaFeatures: {jsx: true}
72114
}
73115
],
74116

75117
invalid: [
76118
{
77-
code: '\
78-
var Hello = React.createClass({\
79-
render: function() {\
80-
return <div>\n\
81-
<p>Hello {this.props.name}</p>\n\
82-
</div>;\
83-
}\
84-
});',
85-
ecmaFeatures: {
86-
jsx: true
87-
},
88-
errors: [{
89-
message: 'Missing parentheses around multilines JSX'
90-
}]
119+
code: RETURN_NO_PAREN,
120+
ecmaFeatures: {jsx: true},
121+
errors: [{message: 'Missing parentheses around multilines JSX'}]
122+
}, {
123+
code: RETURN_NO_PAREN,
124+
ecmaFeatures: {jsx: true},
125+
args: [1, {return: true}],
126+
errors: [{message: 'Missing parentheses around multilines JSX'}]
127+
}, {
128+
code: DECLARATION_NO_PAREN,
129+
ecmaFeatures: {jsx: true},
130+
errors: [{message: 'Missing parentheses around multilines JSX'}]
131+
}, {
132+
code: DECLARATION_NO_PAREN,
133+
ecmaFeatures: {jsx: true},
134+
args: [1, {declaration: true}],
135+
errors: [{message: 'Missing parentheses around multilines JSX'}]
91136
}, {
92-
code: '\
93-
var hello = <div>\n\
94-
<p>Hello</p>\n\
95-
</div>;',
96-
ecmaFeatures: {
97-
jsx: true
98-
},
99-
errors: [{
100-
message: 'Missing parentheses around multilines JSX'
101-
}]
137+
code: ASSIGNMENT_NO_PAREN,
138+
ecmaFeatures: {jsx: true},
139+
errors: [{message: 'Missing parentheses around multilines JSX'}]
102140
}, {
103-
code: '\
104-
var hello;\
105-
hello = <div>\n\
106-
<p>Hello</p>\n\
107-
</div>;',
108-
ecmaFeatures: {
109-
jsx: true
110-
},
111-
errors: [{
112-
message: 'Missing parentheses around multilines JSX'
113-
}]
141+
code: ASSIGNMENT_NO_PAREN,
142+
ecmaFeatures: {jsx: true},
143+
args: [1, {assignment: true}],
144+
errors: [{message: 'Missing parentheses around multilines JSX'}]
114145
}
115146
]
116147
});

0 commit comments

Comments
 (0)