Skip to content

Commit

Permalink
Account for feedback and add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jackyho112 committed Aug 22, 2017
1 parent d2b2aac commit 401e341
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
12 changes: 7 additions & 5 deletions docs/rules/jsx-curly-brace-presence.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ If passed in the option to fix, this is how a style violation will get fixed
* `always`: wrap a JSX attribute in curly braces/JSX expression and/or a JSX child the same way but also with double quotes
* `never`: get rid of curly braces from a JSX attribute and/or a JSX child

- All fixing operations use double quotes.

For examples:

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

```jsx
<App>{"Hello world"}</App>;
<App prop={'Hello world'}>{'Hello world'}</App>;
<App prop={"Hello world"}>{'Hello world'}</App>;
```

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

```jsx
<App>Hello world</App>;
<App prop='Hello world' attr="foo" />;
<App prop="Hello world" attr="foo" />;
```

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

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

```jsx
<App prop='foo' attr="bar">Hello world</App>;
<App prop="foo" attr="bar">Hello world</App>;
```

## Edge cases
Expand Down Expand Up @@ -132,7 +134,7 @@ For example:
will warned and fixed to:

```jsx
<App prop={'Hello "foo" world'}>{"Hello 'foo' \"bar\" world"}</App>;
<App prop={"Hello \"foo\" world"}>{"Hello 'foo' \"bar\" world"}</App>;
```

* 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:
Expand Down
14 changes: 12 additions & 2 deletions lib/rules/jsx-curly-brace-presence.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ module.exports = {
return rawStringValue.includes('\\');
}

function escapeDoubleQuoteInString(value) {
return value.replace(/\\"/g, '"').replace(/"/g, '\\"');
}

/**
* Report and fix an unnecessary curly brace violation on a node
* @param {ASTNode} node - The AST node with an unnecessary JSX expression
Expand All @@ -80,7 +84,10 @@ module.exports = {
let textToReplace;
if (parentType === 'JSXAttribute') {
textToReplace = expressionType === 'TemplateLiteral' ?
`"${expression.quasis[0].value.raw}"` : expression.raw;
`"${expression.quasis[0].value.raw}"` :
`"${escapeDoubleQuoteInString(
expression.raw.substring(1, expression.raw.length - 1)
)}"`;
} else {
textToReplace = expressionType === 'TemplateLiteral' ?
expression.quasis[0].value.cooked : expression.value;
Expand All @@ -97,7 +104,10 @@ module.exports = {
message: 'Need to wrap this literal in a JSX expression.',
fix: function(fixer) {
const expression = literalNode.parent.type === 'JSXAttribute' ?
`{${literalNode.raw}}` : `{${JSON.stringify(literalNode.value)}}`;
`{"${escapeDoubleQuoteInString(
literalNode.raw.substring(1, literalNode.raw.length - 1)
)}"}` :
`{${JSON.stringify(literalNode.value)}}`;

return fixer.replaceText(literalNode, expression);
}
Expand Down
46 changes: 35 additions & 11 deletions tests/lib/rules/jsx-curly-brace-presence.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
},
{
code: '<App prop={\'foo \\u00b7 bar\'}>foo</App>',
output: '<App prop=\'foo \\u00b7 bar\'>foo</App>',
output: '<App prop=\"foo \\u00b7 bar\">foo</App>',
options: [{props: 'never'}],
errors: [{message: unnecessaryCurlyMessage}]
},
Expand Down Expand Up @@ -224,7 +224,7 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
},
{
code: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
errors: [{message: unnecessaryCurlyMessage}]
},
{
Expand All @@ -235,13 +235,25 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
},
{
code: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
options: [{props: 'never'}],
errors: [{message: unnecessaryCurlyMessage}]
},
{
code: '<MyComponent prop={\"bar \'foo\' \"}>foo</MyComponent>',
output: '<MyComponent prop=\"bar \'foo\' \">foo</MyComponent>',
options: [{props: 'never'}],
errors: [{message: unnecessaryCurlyMessage}]
},
{
code: '<MyComponent prop={\'bar \"foo\" \'}>foo</MyComponent>',
output: '<MyComponent prop=\"bar \\\"foo\\\" \">foo</MyComponent>',
options: [{props: 'never'}],
errors: [{message: unnecessaryCurlyMessage}]
},
{
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop={\'bar\'}>foo</MyComponent>',
output: '<MyComponent prop={\"bar\"}>foo</MyComponent>',
options: [{props: 'always'}],
errors: [{message: missingCurlyMessage}]
},
Expand All @@ -251,6 +263,18 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
options: [{children: 'always'}],
errors: [{message: missingCurlyMessage}]
},
{
code: '<MyComponent>foo bar \'foo\'</MyComponent>',
output: '<MyComponent>{\"foo bar \'foo\'\"}</MyComponent>',
options: [{children: 'always'}],
errors: [{message: missingCurlyMessage}]
},
{
code: '<MyComponent>foo bar \"foo\"</MyComponent>',
output: '<MyComponent>{\"foo bar \\\"foo\\\"\"}</MyComponent>',
options: [{children: 'always'}],
errors: [{message: missingCurlyMessage}]
},
{
code: '<MyComponent>foo bar <App/></MyComponent>',
output: '<MyComponent>{\"foo bar \"}<App/></MyComponent>',
Expand All @@ -265,15 +289,15 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
},
{
code: '<MyComponent prop={\'bar\'}>{\'foo\'}</MyComponent>',
output: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop=\"bar\">foo</MyComponent>',
options: ['never'],
errors: [
{message: unnecessaryCurlyMessage}, {message: unnecessaryCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop={\'bar\'}>{\"foo\"}</MyComponent>',
output: '<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>',
options: ['always'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
Expand All @@ -299,35 +323,35 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
},
{
code: '<App prop={\'foo "bar"\'}>foo</App>',
output: '<App prop=\'foo "bar"\'>foo</App>',
output: '<App prop=\"foo \\\"bar\\\"\">foo</App>',
errors: [{message: unnecessaryCurlyMessage}],
options: [{props: 'never'}]
},
{
code: '<App prop={\'foo\'} attr={\" foo \"} />',
output: '<App prop=\'foo\' attr=\" foo \" />',
output: '<App prop=\"foo\" attr=\" foo \" />',
errors: [
{message: unnecessaryCurlyMessage}, {message: unnecessaryCurlyMessage}
],
options: [{props: 'never'}]
},
{
code: '<App prop=\'foo\' attr=\"bar\" />',
output: '<App prop={\'foo\'} attr={\"bar\"} />',
output: '<App prop={\"foo\"} attr={\"bar\"} />',
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
],
options: [{props: 'always'}]
},
{
code: '<App prop=\'foo\' attr={\"bar\"} />',
output: '<App prop={\'foo\'} attr={\"bar\"} />',
output: '<App prop={\"foo\"} attr={\"bar\"} />',
errors: [{message: missingCurlyMessage}],
options: [{props: 'always'}]
},
{
code: '<App prop={\'foo\'} attr=\'bar\' />',
output: '<App prop={\'foo\'} attr={\'bar\'} />',
output: '<App prop={\'foo\'} attr={\"bar\"} />',
errors: [{message: missingCurlyMessage}],
options: [{props: 'always'}]
}
Expand Down

0 comments on commit 401e341

Please sign in to comment.