Repository: prettier/prettier (JavaScript)
Date: 2017-02-23 20:07:28+00:00
Task type: Bug Fix

Issue:
Extra trailing commas in template literal.
Run prettier on: https://github.com/cpojer/jest/blob/master/packages/jest-cli/src/TestNamePatternPrompt.js#L91

```js
         pipe.write(
            // eslint-disable-next-line max-len
            `\n  ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more)}`)}`,
          );
```

turns it into this:

```js
          pipe.write(
            // eslint-disable-next-line max-len
            `\n  ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more,)}`,)}`,
          );
```


Issue discussion:
Are you using the latest version? This is what I get:

```js
pipe.write(
  // eslint-disable-next-line max-len
  `\n  ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more)}`)}`
);
```

https://prettier.github.io/prettier/#%7B%22content%22%3A%22%20%20%20%20%20%20%20%20%20pipe.write(%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20eslint-disable-next-line%20max-len%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%60%5C%5Cn%20%20%24%7Bchalk.dim(%60%5C%5Cu203A%20and%20%24%7Bmore%7D%20more%20%24%7BpluralizeTest(more)%7D%60)%7D%60%2C%5Cn%20%20%20%20%20%20%20%20%20%20)%3B%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%2C%22jsxBracketSameLine%22%3Afalse%2C%22doc%22%3Afalse%7D%7D.
Yes I used 0.19 just a moment ago.
On Thu, Feb 23, 2017 at 19:14 Davy Duperron <notifications@github.com>
wrote:

> Are you using the latest version? This is what I get:
>
> pipe.write(
>   // eslint-disable-next-line max-len
>   `\n  ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more)}`)}`
> );
>
>
> https://prettier.github.io/prettier/#%7B%22content%22%3A%22%20%20%20%20%20%20%20%20%20pipe.write(%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20eslint-disable-next-line%20max-len%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%60%5C%5Cn%20%20%24%7Bchalk.dim(%60%5C%5Cu203A%20and%20%24%7Bmore%7D%20more%20%24%7BpluralizeTest(more)%7D%60)%7D%60%2C%5Cn%20%20%20%20%20%20%20%20%20%20)%3B%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%2C%22jsxBracketSameLine%22%3Afalse%2C%22doc%22%3Afalse%7D%7D
> .
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/prettier/prettier/issues/795#issuecomment-282090732>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAA0KFLkgrK-vPpvV5BtdxmmTcttH1Gcks5rfdpxgaJpZM4MKVXF>
> .
>

I can't reproduce it with the latest version, even locally (Flow or Babylon). Any idea @vjeux?
The issue is that the code that removes softline inside of template literals doesn't remove trailing commas.

repro case:

```js
./bin/prettier.js test.js --trailing-comma=all
`\n                               ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more,)}`,)}`;
```

cc @jlongster 
Shoot, that's a good point. I suppose we should try to eagerly evaluate `ifBreak`... I'll open a PR to see if it works.

Solution patch:
diff --git a/src/printer.js b/src/printer.js
index 875448b1b47e..a6f3cb4d9f10 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -1388,6 +1388,9 @@ function genericPrintNoParens(path, options, print) {
           if (d.type === "line" && !d.hard) {
             return d.soft ? "" : " ";
           }
+          else if(d.type === "if-break") {
+            return d.flatContents || "";
+          }
           return d;
         });
       }


Test patch:
diff --git a/tests/strings/__snapshots__/jsfmt.spec.js.snap b/tests/strings/__snapshots__/jsfmt.spec.js.snap
index cf292b02cdf4..44d7a05d8f84 100644
--- a/tests/strings/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/strings/__snapshots__/jsfmt.spec.js.snap
@@ -26,16 +26,60 @@ exports[`strings.js 1`] = `
 
   '\\\\uD801\\\\uDC28',
 ];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[
+  \\"abc\\",
+  \\"abc\\",
 
-foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr\`);
+  \\"'\\",
 
-const x = \`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr\`;
+  '\\"',
+  '\\"',
+  '\\\\\\\\\\"',
 
-foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {
-  const x = 5;
+  \\"'\\",
+  \\"'\\",
+  \\"\\\\\\\\'\\",
 
-  return x;
- })() + 3 + 2 + 3 + 2 + 3 } with expr\`);
+  \\"'\\\\\\"\\",
+  \\"'\\\\\\"\\",
+
+  \\"\\\\\\\\\\",
+  \\"\\\\\\\\\\",
+
+  \\"\\\\0\\",
+  \\"🐶\\",
+  '\\\\uD801\\\\uDC28'
+];
+"
+`;
+
+exports[`strings.js 2`] = `
+"[
+  \\"abc\\",
+  'abc',
+
+  '\\\\'',
+
+  '\\"',
+  '\\\\\\"',
+  '\\\\\\\\\\"',
+
+  \\"'\\",
+  \\"\\\\'\\",
+  \\"\\\\\\\\'\\",
+
+  \\"'\\\\\\"\\",
+  '\\\\'\\"',
+
+  '\\\\\\\\',
+  \\"\\\\\\\\\\",
+
+  '\\\\0',
+  '🐶',
+
+  '\\\\uD801\\\\uDC28',
+];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 [
   \\"abc\\",
@@ -59,19 +103,81 @@ foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( functi
 
   \\"\\\\0\\",
   \\"🐶\\",
-  '\\\\uD801\\\\uDC28'
+  '\\\\uD801\\\\uDC28',
 ];
+"
+`;
+
+exports[`template-literals.js 1`] = `
+"foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr\`);
+
+const x = \`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr\`;
+
+foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {
+  const x = 5;
+
+  return x;
+ })() + 3 + 2 + 3 + 2 + 3 } with expr\`);
+
+pipe.write(
+  \`\\\\n  \${chalk.dim(\`\\\\u203A and \${more} more \${more} more \${more} more \${more}\`)}\`,
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 foo(
   \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3} with expr\`
 );
+
 const x = \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() {
     return 3;
   })() + 3 + 2 + 3 + 2 + 3} with expr\`;
+
 foo(
   \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() {
       const x = 5;
+
       return x;
     })() + 3 + 2 + 3 + 2 + 3} with expr\`
 );
+
+pipe.write(
+  \`\\\\n  \${chalk.dim(\`\\\\u203A and \${more} more \${more} more \${more} more \${more}\`)}\`
+);
+"
+`;
+
+exports[`template-literals.js 2`] = `
+"foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr\`);
+
+const x = \`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr\`;
+
+foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {
+  const x = 5;
+
+  return x;
+ })() + 3 + 2 + 3 + 2 + 3 } with expr\`);
+
+pipe.write(
+  \`\\\\n  \${chalk.dim(\`\\\\u203A and \${more} more \${more} more \${more} more \${more}\`)}\`,
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+foo(
+  \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3} with expr\`,
+);
+
+const x = \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() {
+    return 3;
+  })() + 3 + 2 + 3 + 2 + 3} with expr\`;
+
+foo(
+  \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() {
+      const x = 5;
+
+      return x;
+    })() + 3 + 2 + 3 + 2 + 3} with expr\`,
+);
+
+pipe.write(
+  \`\\\\n  \${chalk.dim(\`\\\\u203A and \${more} more \${more} more \${more} more \${more}\`)}\`,
+);
 "
 `;
diff --git a/tests/strings/jsfmt.spec.js b/tests/strings/jsfmt.spec.js
index 989047bccc52..9b85c446c98e 100644
--- a/tests/strings/jsfmt.spec.js
+++ b/tests/strings/jsfmt.spec.js
@@ -1,1 +1,2 @@
 run_spec(__dirname);
+run_spec(__dirname, { trailingComma: "all" });
diff --git a/tests/strings/strings.js b/tests/strings/strings.js
index 8eea02e7535c..d31dceb2b456 100644
--- a/tests/strings/strings.js
+++ b/tests/strings/strings.js
@@ -23,13 +23,3 @@
 
   '\uD801\uDC28',
 ];
-
-foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr`);
-
-const x = `a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr`;
-
-foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {
-  const x = 5;
-
-  return x;
- })() + 3 + 2 + 3 + 2 + 3 } with expr`);
diff --git a/tests/strings/template-literals.js b/tests/strings/template-literals.js
new file mode 100644
index 000000000000..21befa4e6c35
--- /dev/null
+++ b/tests/strings/template-literals.js
@@ -0,0 +1,13 @@
+foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr`);
+
+const x = `a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr`;
+
+foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {
+  const x = 5;
+
+  return x;
+ })() + 3 + 2 + 3 + 2 + 3 } with expr`);
+
+pipe.write(
+  `\n  ${chalk.dim(`\u203A and ${more} more ${more} more ${more} more ${more}`)}`,
+);