Skip to content

Commit cc39fb8

Browse files
authored
Merge pull request #830 from eelyafi/jsx_indent_fixer
[semver-minor] partial jsx-indent rule autofixer
2 parents 3f393a2 + 90af71b commit cc39fb8

File tree

3 files changed

+110
-4
lines changed

3 files changed

+110
-4
lines changed

docs/rules/jsx-indent.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
This option validates a specific indentation style for JSX.
44

5+
**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.
6+
Fixer will fix whitespace and tabs indentation. It won't replace tabs with whitespaces and vice-versa.
7+
58
## Rule Details
69

710
This rule is aimed to enforce consistent indentation style. The default style is `4 spaces`.

lib/rules/jsx-indent.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ module.exports = {
3939
category: 'Stylistic Issues',
4040
recommended: false
4141
},
42-
42+
// fixer will fix whitespace and tabs indentation.
43+
// It won't replace tabs with whitespaces and vice-versa.
44+
fixable: 'whitespace',
4345
schema: [{
4446
oneOf: [{
4547
enum: ['tab']
@@ -69,6 +71,30 @@ module.exports = {
6971
}
7072
}
7173

74+
var indentChar = indentType === 'space' ? ' ' : '\t';
75+
76+
/**
77+
* Responsible for fixing the indentation issue fix
78+
* @param {ASTNode} node Node violating the indent rule
79+
* @param {Number} needed Expected indentation character count
80+
* @param {Number} gotten Indentation character count in the actual node/code
81+
* @returns {Function} function to be executed by the fixer
82+
* @private
83+
*/
84+
function getFixerFunction(node, needed, gotten) {
85+
if (needed > gotten) {
86+
var spaces = indentChar.repeat(needed - gotten);
87+
88+
return function(fixer) {
89+
return fixer.insertTextBeforeRange([node.range[0], node.range[0]], spaces);
90+
};
91+
}
92+
93+
return function(fixer) {
94+
return fixer.removeRange([node.range[0] - (gotten - needed), node.range[0]]);
95+
};
96+
}
97+
7298
/**
7399
* Reports a given indent violation and properly pluralizes the message
74100
* @param {ASTNode} node Node violating the indent rule
@@ -89,13 +115,15 @@ module.exports = {
89115
node: node,
90116
loc: loc,
91117
message: MESSAGE,
92-
data: msgContext
118+
data: msgContext,
119+
fix: getFixerFunction(node, needed, gotten)
93120
});
94121
} else {
95122
context.report({
96123
node: node,
97124
message: MESSAGE,
98-
data: msgContext
125+
data: msgContext,
126+
fix: getFixerFunction(node, needed, gotten)
99127
});
100128
}
101129
}

tests/lib/rules/jsx-indent.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ ruleTester.run('jsx-indent', rule, {
107107
' <Foo />',
108108
'</App>'
109109
].join('\n'),
110+
output: [
111+
'<App>',
112+
' <Foo />',
113+
'</App>'
114+
].join('\n'),
110115
parserOptions: parserOptions,
111116
errors: [{message: 'Expected indentation of 4 space characters but found 2.'}]
112117
}, {
@@ -115,6 +120,11 @@ ruleTester.run('jsx-indent', rule, {
115120
' <Foo />',
116121
'</App>'
117122
].join('\n'),
123+
output: [
124+
'<App>',
125+
' <Foo />',
126+
'</App>'
127+
].join('\n'),
118128
options: [2],
119129
parserOptions: parserOptions,
120130
errors: [{message: 'Expected indentation of 2 space characters but found 4.'}]
@@ -135,6 +145,13 @@ ruleTester.run('jsx-indent', rule, {
135145
' </App>;',
136146
'}'
137147
].join('\n'),
148+
output: [
149+
'function App() {',
150+
' return <App>',
151+
' <Foo />',
152+
' </App>;',
153+
'}'
154+
].join('\n'),
138155
options: [2],
139156
parserOptions: parserOptions,
140157
errors: [{message: 'Expected indentation of 2 space characters but found 9.'}]
@@ -146,6 +163,13 @@ ruleTester.run('jsx-indent', rule, {
146163
' </App>);',
147164
'}'
148165
].join('\n'),
166+
output: [
167+
'function App() {',
168+
' return (<App>',
169+
' <Foo />',
170+
' </App>);',
171+
'}'
172+
].join('\n'),
149173
options: [2],
150174
parserOptions: parserOptions,
151175
errors: [{message: 'Expected indentation of 2 space characters but found 4.'}]
@@ -212,6 +236,57 @@ ruleTester.run('jsx-indent', rule, {
212236
errors: [
213237
{message: 'Expected indentation of 3 tab characters but found 2.'}
214238
]
215-
}]
239+
}, {
240+
code: [
241+
'<App>\n',
242+
'<Foo />\n',
243+
'</App>'
244+
].join('\n'),
245+
output: [
246+
'<App>\n',
247+
'\t<Foo />\n',
248+
'</App>'
249+
].join('\n'),
250+
parserOptions: parserOptions,
251+
options: ['tab'],
252+
errors: [
253+
{message: 'Expected indentation of 1 tab character but found 0.'}
254+
]
255+
}
256+
// Tests for future work. See the comment on line 42-43 in the rule near to fixable: 'whitespace' meta property,
257+
// Right now fixer function doesn't support replacing tabs with whitespaces and vice-versa.
258+
/* , {
259+
code: [
260+
'<App>\n',
261+
' <Foo />\n',
262+
'</App>'
263+
].join('\n'),
264+
output: [
265+
'<App>\n',
266+
'\t<Foo />\n',
267+
'</App>'
268+
].join('\n'),
269+
parserOptions: parserOptions,
270+
options: ['tab'],
271+
errors: [
272+
{message: 'Expected indentation of 1 tab character but found 0.'}
273+
]
274+
}, {
275+
code: [
276+
'<App>\n',
277+
'\t<Foo />\n',
278+
'</App>'
279+
].join('\n'),
280+
output: [
281+
'<App>\n',
282+
' <Foo />\n',
283+
'</App>'
284+
].join('\n'),
285+
parserOptions: parserOptions,
286+
options: [2],
287+
errors: [
288+
{message: 'Expected indentation of 2 space characters but found 0.'}
289+
]
290+
}*/]
216291
});
217292

0 commit comments

Comments
 (0)