Skip to content
This repository was archived by the owner on Sep 14, 2021. It is now read-only.

jsx-first-pro-new-line autofix implementation #2

Merged
merged 7 commits into from
Oct 4, 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
53 changes: 48 additions & 5 deletions lib/rules/jsx-first-prop-new-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,49 @@ module.exports = {
category: 'Stylistic Issues',
recommended: false
},
fixable: 'code',

schema: [{
enum: ['always', 'never', 'multiline']
}]
schema: [
{
enum: ['always', 'never', 'multiline']
},
{
oneOf: [{
enum: ['tab']
}, {
type: 'integer'
}]
}
]
},

create: function (context) {
var configuration = context.options[0];
var indentType = 'space';
var indentSize = 2;
var sourceCode = context.getSourceCode();

if (context.options.length > 1) {
if (context.options[1] === 'tab') {
indentSize = 1;
indentType = 'tab';
} else if (typeof context.options[1] === 'number') {
indentSize = context.options[1];
indentType = 'space';
}
}

function getNodeIndent(node) {
var src = sourceCode.getText(node, node.loc.start.column).split('\n')[0];
var regExp;
if (indentType === 'space') {
regExp = new RegExp('^[ ]+');
} else {
regExp = new RegExp('^[\t' + ']+');
}
var indent = regExp.exec(src);
return indent ? indent[0].length : 0;
}

function isMultilineJSX(jsxNode) {
return jsxNode.loc.start.line < jsxNode.loc.end.line;
Expand All @@ -35,7 +70,12 @@ module.exports = {
if (decl.loc.start.line === node.loc.start.line) {
context.report({
node: decl,
message: 'Property should be placed on a new line'
message: 'Property should be placed on a new line',
fix: function(fixer) {
var neededIndent = getNodeIndent(node) + indentSize;
var insert = '\n' + Array(neededIndent + 1).join(indentType === 'space' ? ' ' : '\t');
return fixer.replaceTextRange([node.name.end, decl.start], insert);
}
});
}
});
Expand All @@ -44,7 +84,10 @@ module.exports = {
if (node.loc.start.line < firstNode.loc.start.line) {
context.report({
node: firstNode,
message: 'Property should be placed on the same line as the component declaration'
message: 'Property should be placed on the same line as the component declaration',
fix: function(fixer) {
return fixer.replaceTextRange([node.name.end, firstNode.start], ' ');
}
});
return;
}
Expand Down
51 changes: 49 additions & 2 deletions tests/lib/rules/jsx-first-prop-new-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ ruleTester.run('jsx-first-prop-new-line', rule, {
invalid: [
{
code: '<Foo prop="one" />',
output: [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls add test cases for tabs too. Thanks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just added.

'<Foo',
' prop="one" />'
].join('\n'),
options: ['always'],
errors: [{message: 'Property should be placed on a new line'}],
parser: parserOptions
Expand All @@ -130,15 +134,58 @@ ruleTester.run('jsx-first-prop-new-line', rule, {
' propTwo="two"',
'/>'
].join('\n'),
output: [
'<Foo',
' propOne="one"',
' propTwo="two"',
'/>'
].join('\n'),
options: ['always'],
errors: [{message: 'Property should be placed on a new line'}],
parser: parserOptions
},
{
code: [
' <Foo propOne="one"',
' propTwo="two"',
' />'
].join('\n'),
output: [
' <Foo',
' propOne="one"',
' propTwo="two"',
' />'
].join('\n'),
options: ['always', 4],
errors: [{message: 'Property should be placed on a new line'}],
parser: parserOptions
},
{
code: [
'\t<Foo propOne="one"',
'\t\tpropTwo="two"',
'\t/>'
].join('\n'),
output: [
'\t<Foo',
'\t\tpropOne="one"',
'\t\tpropTwo="two"',
'\t/>'
].join('\n'),
options: ['always', 'tab'],
errors: [{message: 'Property should be placed on a new line'}],
parser: parserOptions
},
{
code: [
'<Foo',
' propOne="one"',
' propTwo="two"',
' propOne="one"',
' propTwo="two"',
'/>'
].join('\n'),
output: [
'<Foo propOne="one"',
' propTwo="two"',
'/>'
].join('\n'),
options: ['never'],
Expand Down