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

Commit

Permalink
jsx-first-pro-new-line autofix implementation (#2)
Browse files Browse the repository at this point in the history
Fixes #1
  • Loading branch information
snowypowers authored and shioju committed Oct 4, 2016
1 parent a1b8d45 commit 0771c11
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 7 deletions.
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: [
'<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

0 comments on commit 0771c11

Please sign in to comment.