Repository: jlongster/prettier (js)

Issue:
Only escape strings that include both single and double quote characters
When a string includes the preferred quote character but not the alternative quote character we should avoid escaping:

Example input:
```js
var s = '["string","with","quotes"]';
```
Current output:
```js
var s = "[\"string\",\"with\",\"quotes\"]";
```

This would match the Python repl's behaviour (which prefers single quotes):
```python
>>> "none"
'none'
>>> "single'quote"
"single'quote"
>>> "double\"quote"
'double"quote'
>>> "both'\"quote"
'both\'"quote'
>>> "both\"'quote"
'both"\'quote'
```


Pull request description:
Minimize string escapes
If there you are opting in for double quote but there's a string with a double quote in it, it's better to swap to a single quote to avoid having too many `\`. Note that if there are both single and double quotes in the string, we should use the default string instead.

Fixes #139

Patch:
diff --git a/src/printer.js b/src/printer.js
index 78d2d64dd..1edaebaa6 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -2059,7 +2059,18 @@ function swapQuotes(str) {
 function nodeStr(str, options) {
   isString.assert(str);
 
-  if (options.singleQuote) {
+  const containsSingleQuote = str.indexOf("'") !== -1;
+  const containsDoubleQuote = str.indexOf('"') !== -1;
+
+  let shouldUseSingleQuote = options.singleQuote;
+  if (options.singleQuote && containsSingleQuote && !containsDoubleQuote) {
+    shouldUseSingleQuote = false;
+  }
+  if (!options.singleQuote && !containsSingleQuote && containsDoubleQuote) {
+    shouldUseSingleQuote = true;
+  }
+
+  if (shouldUseSingleQuote) {
     return swapQuotes(JSON.stringify(swapQuotes(str)));
   } else {
     return JSON.stringify(str);


Test patch:
diff --git a/tests/node_tests/child_process/__snapshots__/jsfmt.spec.js.snap b/tests/node_tests/child_process/__snapshots__/jsfmt.spec.js.snap
index 2b00c505f..630144e90 100644
--- a/tests/node_tests/child_process/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/node_tests/child_process/__snapshots__/jsfmt.spec.js.snap
@@ -164,9 +164,7 @@ var ls = child_process.spawn(\"ls\");
 var wc = child_process.spawn(\"wc\", [ \"-l\" ]);
 
 // args + options.
-child_process.spawn(\"echo\", [ \"-n\", \"\\\"Testing...\\\"\" ], {
-  env: { TEST: \"foo\" }
-});
+child_process.spawn(\"echo\", [ \"-n\", \'\"Testing...\"\' ], { env: { TEST: \"foo\" } });
 
 // options only.
 child_process.spawn(\"echo\", { env: { FOO: 2 } });
diff --git a/tests/strings/__snapshots__/jsfmt.spec.js.snap b/tests/strings/__snapshots__/jsfmt.spec.js.snap
index 288c13f83..2edc67b56 100644
--- a/tests/strings/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/strings/__snapshots__/jsfmt.spec.js.snap
@@ -26,9 +26,9 @@ exports[`test strings.js 1`] = `
 
 \"\'\";
 
-\"\\\"\";
-\"\\\"\";
-\"\\\\\\\"\";
+\'\"\';
+\'\"\';
+\'\\\\\"\';
 
 \"\'\";
 \"\'\";