Skip to content

Commit 0cf9fc9

Browse files
committed
Add auto-fixer for rule self-closing-comp. Update documentation and update tests.
1 parent 99bdb42 commit 0cf9fc9

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Finally, enable all of the rules that you would like to use. Use [our preset](#
103103
* [react/require-extension](docs/rules/require-extension.md): Restrict file extensions that may be required
104104
* [react/require-optimization](docs/rules/require-optimization.md): Enforce React components to have a shouldComponentUpdate method
105105
* [react/require-render-return](docs/rules/require-render-return.md): Enforce ES5 or ES6 class for returning value in render function
106-
* [react/self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
106+
* [react/self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children (fixable)
107107
* [react/sort-comp](docs/rules/sort-comp.md): Enforce component methods order
108108
* [react/sort-prop-types](docs/rules/sort-prop-types.md): Enforce propTypes declarations alphabetical sorting
109109

docs/rules/self-closing-comp.md

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

33
Components without children can be self-closed to avoid unnecessary extra closing tag.
44

5+
**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.
6+
57
## Rule Details
68

79
The following patterns are considered warnings:

lib/rules/self-closing-comp.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = {
1515
category: 'Stylistic Issues',
1616
recommended: false
1717
},
18+
fixable: 'code',
1819

1920
schema: [{
2021
type: 'object',
@@ -75,7 +76,17 @@ module.exports = {
7576
}
7677
context.report({
7778
node: node,
78-
message: 'Empty components are self-closing'
79+
message: 'Empty components are self-closing',
80+
fix: function(fixer) {
81+
// Represents the last character of the JSXOpeningElement, the '>' character
82+
var openingElementEnding = node.end - 1;
83+
// Represents the last character of the JSXClosingElement, the '>' character
84+
var closingElementEnding = node.parent.closingElement.end;
85+
86+
// Replace />.*<\/.*>/ with '/>'
87+
var range = [openingElementEnding, closingElementEnding];
88+
return fixer.replaceTextRange(range, '/>');
89+
}
7990
});
8091
}
8192
};

tests/lib/rules/self-closing-comp.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,73 +107,84 @@ ruleTester.run('self-closing-comp', rule, {
107107
invalid: [
108108
{
109109
code: 'var contentContainer = <div className="content"></div>;',
110+
output: 'var contentContainer = <div className="content"/>;',
110111
parserOptions: parserOptions,
111112
errors: [{
112113
message: 'Empty components are self-closing'
113114
}]
114115
}, {
115116
code: 'var contentContainer = <div className="content"></div>;',
117+
output: 'var contentContainer = <div className="content"/>;',
116118
options: [],
117119
parserOptions: parserOptions,
118120
errors: [{
119121
message: 'Empty components are self-closing'
120122
}]
121123
}, {
122124
code: 'var HelloJohn = <Hello name="John"></Hello>;',
125+
output: 'var HelloJohn = <Hello name="John"/>;',
123126
parserOptions: parserOptions,
124127
errors: [{
125128
message: 'Empty components are self-closing'
126129
}]
127130
}, {
128131
code: 'var HelloJohn = <Hello name="John">\n</Hello>;',
132+
output: 'var HelloJohn = <Hello name="John"/>;',
129133
parserOptions: parserOptions,
130134
errors: [{
131135
message: 'Empty components are self-closing'
132136
}]
133137
}, {
134138
code: 'var HelloJohn = <Hello name="John"> </Hello>;',
139+
output: 'var HelloJohn = <Hello name="John"/>;',
135140
parserOptions: parserOptions,
136141
errors: [{
137142
message: 'Empty components are self-closing'
138143
}]
139144
},
140145
{
141146
code: 'var HelloJohn = <Hello name="John"></Hello>;',
147+
output: 'var HelloJohn = <Hello name="John"/>;',
142148
options: [],
143149
parserOptions: parserOptions,
144150
errors: [{
145151
message: 'Empty components are self-closing'
146152
}]
147153
}, {
148154
code: 'var HelloJohn = <Hello name="John">\n</Hello>;',
155+
output: 'var HelloJohn = <Hello name="John"/>;',
149156
options: [],
150157
parserOptions: parserOptions,
151158
errors: [{
152159
message: 'Empty components are self-closing'
153160
}]
154161
}, {
155162
code: 'var HelloJohn = <Hello name="John"> </Hello>;',
163+
output: 'var HelloJohn = <Hello name="John"/>;',
156164
options: [],
157165
parserOptions: parserOptions,
158166
errors: [{
159167
message: 'Empty components are self-closing'
160168
}]
161169
}, {
162170
code: 'var contentContainer = <div className="content"></div>;',
171+
output: 'var contentContainer = <div className="content"/>;',
163172
options: [{html: true}],
164173
parserOptions: parserOptions,
165174
errors: [{
166175
message: 'Empty components are self-closing'
167176
}]
168177
}, {
169178
code: 'var contentContainer = <div className="content">\n</div>;',
179+
output: 'var contentContainer = <div className="content"/>;',
170180
options: [{html: true}],
171181
parserOptions: parserOptions,
172182
errors: [{
173183
message: 'Empty components are self-closing'
174184
}]
175185
}, {
176186
code: 'var contentContainer = <div className="content"> </div>;',
187+
output: 'var contentContainer = <div className="content"/>;',
177188
options: [{html: true}],
178189
parserOptions: parserOptions,
179190
errors: [{

0 commit comments

Comments
 (0)