Skip to content

Commit 401e341

Browse files
committed
Account for feedback and add more tests
1 parent d2b2aac commit 401e341

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

docs/rules/jsx-curly-brace-presence.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ If passed in the option to fix, this is how a style violation will get fixed
4141
* `always`: wrap a JSX attribute in curly braces/JSX expression and/or a JSX child the same way but also with double quotes
4242
* `never`: get rid of curly braces from a JSX attribute and/or a JSX child
4343

44+
- All fixing operations use double quotes.
45+
4446
For examples:
4547

4648
When `{ props: "always", children: "always" }` is set, the following patterns will be given warnings.
@@ -54,7 +56,7 @@ They can be fixed to:
5456

5557
```jsx
5658
<App>{"Hello world"}</App>;
57-
<App prop={'Hello world'}>{'Hello world'}</App>;
59+
<App prop={"Hello world"}>{'Hello world'}</App>;
5860
```
5961

6062
When `{ props: "never", children: "never" }` is set, the following patterns will be given warnings.
@@ -68,7 +70,7 @@ They can be fixed to:
6870

6971
```jsx
7072
<App>Hello world</App>;
71-
<App prop='Hello world' attr="foo" />;
73+
<App prop="Hello world" attr="foo" />;
7274
```
7375

7476
### Alternative syntax
@@ -89,7 +91,7 @@ When `'always'` is set, the following patterns will be given warnings.
8991
They can be fixed to:
9092
```jsx
9193
<App>{"Hello world"}</App>;
92-
<App prop={'Hello world'} attr={"foo"}>{"Hello world"}</App>;
94+
<App prop={"Hello world"} attr={"foo"}>{"Hello world"}</App>;
9395
```
9496

9597
When `'never'` is set, the following pattern will be given warnings.
@@ -101,7 +103,7 @@ When `'never'` is set, the following pattern will be given warnings.
101103
It can fixed to:
102104

103105
```jsx
104-
<App prop='foo' attr="bar">Hello world</App>;
106+
<App prop="foo" attr="bar">Hello world</App>;
105107
```
106108

107109
## Edge cases
@@ -132,7 +134,7 @@ For example:
132134
will warned and fixed to:
133135

134136
```jsx
135-
<App prop={'Hello "foo" world'}>{"Hello 'foo' \"bar\" world"}</App>;
137+
<App prop={"Hello \"foo\" world"}>{"Hello 'foo' \"bar\" world"}</App>;
136138
```
137139

138140
* If the rule is set to get rid of unnecessary curly braces and the strings have escaped characters, it will not warn or fix for JSX children because JSX expressions are necessary in this case. For instance:

lib/rules/jsx-curly-brace-presence.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ module.exports = {
6363
return rawStringValue.includes('\\');
6464
}
6565

66+
function escapeDoubleQuoteInString(value) {
67+
return value.replace(/\\"/g, '"').replace(/"/g, '\\"');
68+
}
69+
6670
/**
6771
* Report and fix an unnecessary curly brace violation on a node
6872
* @param {ASTNode} node - The AST node with an unnecessary JSX expression
@@ -80,7 +84,10 @@ module.exports = {
8084
let textToReplace;
8185
if (parentType === 'JSXAttribute') {
8286
textToReplace = expressionType === 'TemplateLiteral' ?
83-
`"${expression.quasis[0].value.raw}"` : expression.raw;
87+
`"${expression.quasis[0].value.raw}"` :
88+
`"${escapeDoubleQuoteInString(
89+
expression.raw.substring(1, expression.raw.length - 1)
90+
)}"`;
8491
} else {
8592
textToReplace = expressionType === 'TemplateLiteral' ?
8693
expression.quasis[0].value.cooked : expression.value;
@@ -97,7 +104,10 @@ module.exports = {
97104
message: 'Need to wrap this literal in a JSX expression.',
98105
fix: function(fixer) {
99106
const expression = literalNode.parent.type === 'JSXAttribute' ?
100-
`{${literalNode.raw}}` : `{${JSON.stringify(literalNode.value)}}`;
107+
`{"${escapeDoubleQuoteInString(
108+
literalNode.raw.substring(1, literalNode.raw.length - 1)
109+
)}"}` :
110+
`{${JSON.stringify(literalNode.value)}}`;
101111

102112
return fixer.replaceText(literalNode, expression);
103113
}

tests/lib/rules/jsx-curly-brace-presence.js

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
177177
},
178178
{
179179
code: '<App prop={\'foo \\u00b7 bar\'}>foo</App>',
180-
output: '<App prop=\'foo \\u00b7 bar\'>foo</App>',
180+
output: '<App prop=\"foo \\u00b7 bar\">foo</App>',
181181
options: [{props: 'never'}],
182182
errors: [{message: unnecessaryCurlyMessage}]
183183
},
@@ -224,7 +224,7 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
224224
},
225225
{
226226
code: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
227-
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
227+
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
228228
errors: [{message: unnecessaryCurlyMessage}]
229229
},
230230
{
@@ -235,13 +235,25 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
235235
},
236236
{
237237
code: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
238-
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
238+
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
239+
options: [{props: 'never'}],
240+
errors: [{message: unnecessaryCurlyMessage}]
241+
},
242+
{
243+
code: '<MyComponent prop={\"bar \'foo\' \"}>foo</MyComponent>',
244+
output: '<MyComponent prop=\"bar \'foo\' \">foo</MyComponent>',
245+
options: [{props: 'never'}],
246+
errors: [{message: unnecessaryCurlyMessage}]
247+
},
248+
{
249+
code: '<MyComponent prop={\'bar \"foo\" \'}>foo</MyComponent>',
250+
output: '<MyComponent prop=\"bar \\\"foo\\\" \">foo</MyComponent>',
239251
options: [{props: 'never'}],
240252
errors: [{message: unnecessaryCurlyMessage}]
241253
},
242254
{
243255
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
244-
output: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
256+
output: '<MyComponent prop={\"bar\"}>foo</MyComponent>',
245257
options: [{props: 'always'}],
246258
errors: [{message: missingCurlyMessage}]
247259
},
@@ -251,6 +263,18 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
251263
options: [{children: 'always'}],
252264
errors: [{message: missingCurlyMessage}]
253265
},
266+
{
267+
code: '<MyComponent>foo bar \'foo\'</MyComponent>',
268+
output: '<MyComponent>{\"foo bar \'foo\'\"}</MyComponent>',
269+
options: [{children: 'always'}],
270+
errors: [{message: missingCurlyMessage}]
271+
},
272+
{
273+
code: '<MyComponent>foo bar \"foo\"</MyComponent>',
274+
output: '<MyComponent>{\"foo bar \\\"foo\\\"\"}</MyComponent>',
275+
options: [{children: 'always'}],
276+
errors: [{message: missingCurlyMessage}]
277+
},
254278
{
255279
code: '<MyComponent>foo bar <App/></MyComponent>',
256280
output: '<MyComponent>{\"foo bar \"}<App/></MyComponent>',
@@ -265,15 +289,15 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
265289
},
266290
{
267291
code: '<MyComponent prop={\'bar\'}>{\'foo\'}</MyComponent>',
268-
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
292+
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
269293
options: ['never'],
270294
errors: [
271295
{message: unnecessaryCurlyMessage}, {message: unnecessaryCurlyMessage}
272296
]
273297
},
274298
{
275299
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
276-
output: '<MyComponent prop={\'bar\'}>{\"foo\"}</MyComponent>',
300+
output: '<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>',
277301
options: ['always'],
278302
errors: [
279303
{message: missingCurlyMessage}, {message: missingCurlyMessage}
@@ -299,35 +323,35 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
299323
},
300324
{
301325
code: '<App prop={\'foo "bar"\'}>foo</App>',
302-
output: '<App prop=\'foo "bar"\'>foo</App>',
326+
output: '<App prop=\"foo \\\"bar\\\"\">foo</App>',
303327
errors: [{message: unnecessaryCurlyMessage}],
304328
options: [{props: 'never'}]
305329
},
306330
{
307331
code: '<App prop={\'foo\'} attr={\" foo \"} />',
308-
output: '<App prop=\'foo\' attr=\" foo \" />',
332+
output: '<App prop=\"foo\" attr=\" foo \" />',
309333
errors: [
310334
{message: unnecessaryCurlyMessage}, {message: unnecessaryCurlyMessage}
311335
],
312336
options: [{props: 'never'}]
313337
},
314338
{
315339
code: '<App prop=\'foo\' attr=\"bar\" />',
316-
output: '<App prop={\'foo\'} attr={\"bar\"} />',
340+
output: '<App prop={\"foo\"} attr={\"bar\"} />',
317341
errors: [
318342
{message: missingCurlyMessage}, {message: missingCurlyMessage}
319343
],
320344
options: [{props: 'always'}]
321345
},
322346
{
323347
code: '<App prop=\'foo\' attr={\"bar\"} />',
324-
output: '<App prop={\'foo\'} attr={\"bar\"} />',
348+
output: '<App prop={\"foo\"} attr={\"bar\"} />',
325349
errors: [{message: missingCurlyMessage}],
326350
options: [{props: 'always'}]
327351
},
328352
{
329353
code: '<App prop={\'foo\'} attr=\'bar\' />',
330-
output: '<App prop={\'foo\'} attr={\'bar\'} />',
354+
output: '<App prop={\'foo\'} attr={\"bar\"} />',
331355
errors: [{message: missingCurlyMessage}],
332356
options: [{props: 'always'}]
333357
}

0 commit comments

Comments
 (0)