Skip to content

Commit

Permalink
Fix jsx-indent in multi-line conditional expressions (fixes #901, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Yannick Croissant committed Nov 6, 2016
1 parent dc7767b commit d88ee37
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
28 changes: 26 additions & 2 deletions lib/rules/jsx-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,20 @@ module.exports = {
);
}

/**
* Check if the node is the alternate member of a conditional expression
* @param {ASTNode} node The node to check
* @return {Boolean} true if its the case, false if not
*/
function isAlternateInConditionalExp(node) {
return (
node.parent &&
node.parent.parent &&
node.parent.parent.type === 'ConditionalExpression' &&
node.parent.parent.alternate === node.parent
);
}

/**
* Check indent for nodes list
* @param {ASTNode} node The node to check
Expand All @@ -192,7 +206,13 @@ module.exports = {
function checkNodesIndent(node, indent, excludeCommas) {
var nodeIndent = getNodeIndent(node, false, excludeCommas);
var isCorrectRightInLogicalExp = isRightInLogicalExp(node) && (nodeIndent - indent) === indentSize;
if (nodeIndent !== indent && isNodeFirstInLine(node) && !isCorrectRightInLogicalExp) {
var isCorrectAlternateInCondExp = isAlternateInConditionalExp(node) && (nodeIndent - indent) === 0;
if (
nodeIndent !== indent &&
isNodeFirstInLine(node) &&
!isCorrectRightInLogicalExp &&
!isCorrectAlternateInCondExp
) {
report(node, indent, nodeIndent);
}
}
Expand All @@ -208,7 +228,11 @@ module.exports = {
prevToken = sourceCode.getNodeByRangeIndex(prevToken.start).parent;
}
var parentElementIndent = getNodeIndent(prevToken);
var indent = prevToken.loc.start.line === node.loc.start.line || isRightInLogicalExp(node) ? 0 : indentSize;
var indent = (
prevToken.loc.start.line === node.loc.start.line ||
isRightInLogicalExp(node) ||
isAlternateInConditionalExp(node)
) ? 0 : indentSize;
checkNodesIndent(node, parentElementIndent + indent);
},
JSXClosingElement: function(node) {
Expand Down
57 changes: 57 additions & 0 deletions tests/lib/rules/jsx-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ ruleTester.run('jsx-indent', rule, {
'</div>'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'<div>',
' {this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>',
' }',
'</div>'
].join('\n'),
parserOptions: parserOptions
}],

invalid: [{
Expand Down Expand Up @@ -447,5 +464,45 @@ ruleTester.run('jsx-indent', rule, {
errors: [
{message: 'Expected indentation of 2 space characters but found 0.'}
]
}, {
code: [
'this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>'
].join('\n'),
output: [
'this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Expected indentation of 4 space characters but found 8.',
line: 3,
column: 9
}]
}, {
code: [
'<div>',
' {this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>',
' }',
'</div>'
].join('\n'),
output: [
'<div>',
' {this.props.asd.length > 0 ?',
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
' <span className="bacon-no-trigger">0</span>',
' }',
'</div>'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: 'Expected indentation of 8 space characters but found 4.',
line: 4,
column: 5
}]
}]
});

0 comments on commit d88ee37

Please sign in to comment.