diff --git a/lib/rules/jsx-wrap-multilines.js b/lib/rules/jsx-wrap-multilines.js index 32d3d08113..de85d89ac3 100644 --- a/lib/rules/jsx-wrap-multilines.js +++ b/lib/rules/jsx-wrap-multilines.js @@ -94,13 +94,32 @@ module.exports = { nextToken.value === ')' && nextToken.range[0] >= node.range[1]; } - function needsNewLines(node) { + function needsOpeningNewLine(node) { const previousToken = sourceCode.getTokenBefore(node); + + if (!isParenthesised(node)) { + return false; + } + + if (previousToken.loc.end.line === node.loc.start.line) { + return true; + } + + return false; + } + + function needsClosingNewLine(node) { const nextToken = sourceCode.getTokenAfter(node); - return isParenthesised(node) && - previousToken.loc.end.line === node.loc.start.line && - node.loc.end.line === nextToken.loc.end.line; + if (!isParenthesised(node)) { + return false; + } + + if (node.loc.end.line === nextToken.loc.end.line) { + return true; + } + + return false; } function isMultilines(node) { @@ -150,8 +169,22 @@ module.exports = { } else { report(node, MISSING_PARENS, fixer => fixer.replaceText(node, `(\n${sourceCode.getText(node)}\n)`)); } - } else if (needsNewLines(node)) { - report(node, PARENS_NEW_LINES, fixer => fixer.replaceText(node, `\n${sourceCode.getText(node)}\n`)); + } else { + const needsOpening = needsOpeningNewLine(node); + const needsClosing = needsClosingNewLine(node); + if (needsOpening || needsClosing) { + report(node, PARENS_NEW_LINES, fixer => { + const text = sourceCode.getText(node); + let fixed = text; + if (needsOpening) { + fixed = `\n${fixed}`; + } + if (needsClosing) { + fixed = `${fixed}\n`; + } + return fixer.replaceText(node, fixed); + }); + } } } } diff --git a/tests/lib/rules/jsx-wrap-multilines.js b/tests/lib/rules/jsx-wrap-multilines.js index 0351df1831..f0f6e0d9a6 100644 --- a/tests/lib/rules/jsx-wrap-multilines.js +++ b/tests/lib/rules/jsx-wrap-multilines.js @@ -86,6 +86,56 @@ const RETURN_PAREN_NEW_LINE = ` }); `; +const RETURN_PAREN_NEW_LINE_OPENING = ` + var Hello = createReactClass({ + render: function() { + return ( + +
+

Hello {this.props.name}

+
); + } + }); +`; + +const RETURN_PAREN_NEW_LINE_OPENING_FIXED = ` + var Hello = createReactClass({ + render: function() { + return ( + +
+

Hello {this.props.name}

+
+); + } + }); +`; + +const RETURN_PAREN_NEW_LINE_CLOSING = ` + var Hello = createReactClass({ + render: function() { + return (
+

Hello {this.props.name}

+
+ + ); + } + }); +`; + +const RETURN_PAREN_NEW_LINE_CLOSING_FIXED = ` + var Hello = createReactClass({ + render: function() { + return ( +
+

Hello {this.props.name}

+
+ + ); + } + }); +`; + const RETURN_PAREN_NEW_LINE_FRAGMENT = ` var Hello = createReactClass({ render: function() { @@ -912,6 +962,16 @@ ruleTester.run('jsx-wrap-multilines', rule, { output: addNewLineSymbols(RETURN_PAREN), options: [{return: 'parens-new-line'}], errors: [{message: PARENS_NEW_LINES}] + }, { + code: RETURN_PAREN_NEW_LINE_OPENING, + output: RETURN_PAREN_NEW_LINE_OPENING_FIXED, + options: [{return: 'parens-new-line'}], + errors: [{message: PARENS_NEW_LINES}] + }, { + code: RETURN_PAREN_NEW_LINE_CLOSING, + output: RETURN_PAREN_NEW_LINE_CLOSING_FIXED, + options: [{return: 'parens-new-line'}], + errors: [{message: PARENS_NEW_LINES}] }, { code: RETURN_PAREN_FRAGMENT, parser: 'babel-eslint',