Source code
Revision control
Copy as Markdown
Other Tools
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// This test case is weird in the sense the actual work happens at the eval
// at the end. If template strings are not enabled, the test cases would throw
// a syntax error and we'd have failure reported. To avoid that, the entire
// test case is commented out and is part of a function. We use toString to
// get the string version, obtain the actual lines to run, and then use eval to
// do the actual evaluation.
function syntaxError (script) {
try {
Function(script);
} catch (e) {
if (e.name === "SyntaxError") {
return;
}
}
throw new Error('Expected syntax error: ' + script);
}
// TEST BEGIN
// combinations of substitutions
assertEq("abcdef", `ab${"cd"}ef`);
assertEq("ab9ef", `ab${4+5}ef`);
assertEq("cdef", `${"cd"}ef`);
assertEq("abcd", `ab${"cd"}`);
assertEq("cd", `${"cd"}`);
assertEq("", `${""}`);
assertEq("4", `${4}`);
// multiple substitutions
assertEq("abcdef", `ab${"cd"}e${"f"}`);
assertEq("abcdef", `ab${"cd"}${"e"}f`);
assertEq("abcdef", `a${"b"}${"cd"}e${"f"}`);
assertEq("abcdef", `${"ab"}${"cd"}${"ef"}`);
// inception
assertEq("abcdef", `a${`b${"cd"}e${"f"}`}`);
syntaxError("`${}`");
syntaxError("`${`");
syntaxError("`${\\n}`");
syntaxError("`${yield 0}`");
// Extra whitespace inside a template substitution is ignored.
assertEq(`${
0
}`, "0");
assertEq(`${ // Comments work in template substitutions.
// Even comments that look like code:
// 0}`, "FAIL"); /* NOTE: This whole line is a comment.
0}`, "0");
// Template substitutions are expressions, not statements.
syntaxError("`${0;}`");
assertEq(`${{}}`, "[object Object]");
assertEq(`${
function f() {
return "ok";
}()
}`, "ok");
// Template substitutions can have side effects.
var x = 0;
assertEq(`= ${x += 1}`, "= 1");
assertEq(x, 1);
// The production for a template substitution is Expression, not
// AssignmentExpression.
x = 0;
assertEq(`${++x, "o"}k`, "ok");
assertEq(x, 1);
// --> is not a comment inside a template.
assertEq(`
--> this is text
`, "\n--> this is text\n");
// reentrancy
function f(n) {
if (n === 0)
return "";
return `${n}${f(n - 1)}`;
}
assertEq(f(9), "987654321");
// Template string substitutions in generator functions can yield.
function* g() {
return `${yield 1} ${yield 2}`;
}
var it = g();
var next = it.next();
assertEq(next.done, false);
assertEq(next.value, 1);
next = it.next("hello");
assertEq(next.done, false);
assertEq(next.value, 2);
next = it.next("world");
assertEq(next.done, true);
assertEq(next.value, "hello world");
// undefined
assertEq(`${void 0}`, "undefined");
assertEq(`${Object.doesNotHaveThisProperty}`, "undefined");
// toString behavior
assertEq("<toString>", `${{valueOf: () => "<valueOf>", toString: () => "<toString>"}}`);
assertEq("Hi 42", Function("try {`${{toString: () => { throw 42;}}}`} catch(e) {return \"Hi \" + e;}")());
reportCompare(0, 0, "ok");