Skip to content

Commit

Permalink
fix(cli/js/web/console): Improve string quoting behaviour (denoland#6457
Browse files Browse the repository at this point in the history
)
  • Loading branch information
nayeemrmn committed Jun 24, 2020
1 parent 702547d commit 3314b46
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
20 changes: 19 additions & 1 deletion cli/js/web/console.ts
Expand Up @@ -300,6 +300,24 @@ function stringify(
}
}

// We can match Node's quoting behavior exactly by swapping the double quote and
// single quote in this array. That would give preference to single quotes.
// However, we prefer double quotes as the default.
const QUOTES = ['"', "'", "`"];

/** Surround the string in quotes.
*
* The quote symbol is chosen by taking the first of the `QUOTES` array which
* does not occur in the string. If they all occur, settle with `QUOTES[0]`.
*
* Insert a backslash before any occurrence of the chosen quote symbol and
* before any backslash. */
function quoteString(string: string): string {
const quote = QUOTES.find((c) => !string.includes(c)) ?? QUOTES[0];
const escapePattern = new RegExp(`(?=[${quote}\\\\])`, "g");
return `${quote}${string.replace(escapePattern, "\\")}${quote}`;
}

// Print strings when they are inside of arrays or objects with quotes
function stringifyWithQuotes(
value: unknown,
Expand All @@ -313,7 +331,7 @@ function stringifyWithQuotes(
value.length > STR_ABBREVIATE_SIZE
? value.slice(0, STR_ABBREVIATE_SIZE) + "..."
: value;
return green(`"${trunc}"`); // Quoted strings are green
return green(quoteString(trunc)); // Quoted strings are green
default:
return stringify(value, ctx, level, maxLevel);
}
Expand Down
7 changes: 7 additions & 0 deletions cli/tests/unit/console_test.ts
Expand Up @@ -64,6 +64,13 @@ unitTest(function consoleTestStringifyComplexObjects(): void {
assertEquals(stringify({ foo: "bar" }), `{ foo: "bar" }`);
});

unitTest(function consoleTestStringifyQuotes(): void {
assertEquals(stringify(["\\"]), `[ "\\\\" ]`);
assertEquals(stringify(['\\,"']), `[ '\\\\,"' ]`);
assertEquals(stringify([`\\,",'`]), `[ \`\\\\,",'\` ]`);
assertEquals(stringify(["\\,\",',`"]), `[ "\\\\,\\",',\`" ]`);
});

unitTest(function consoleTestStringifyLongStrings(): void {
const veryLongString = "a".repeat(200);
// If we stringify an object containing the long string, it gets abbreviated.
Expand Down

0 comments on commit 3314b46

Please sign in to comment.