| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| |
| function echo(str) { |
| WScript.Echo(str); |
| } |
| |
| function printArr(arr, name) { |
| for(var i in arr) { |
| echo(`${name}[${i}]=${arr[i]}`); |
| } |
| } |
| |
| function tag(callSiteObj, sub) { |
| printArr(callSiteObj, "callsiteObj"); |
| printArr(callSiteObj.raw, "callsiteObj.raw"); |
| echo(sub); |
| } |
| |
| function simpleTag(callSiteObj, sub1, sub2, sub3, sub4) { |
| var str = ''; |
| |
| for(var i in callSiteObj) { |
| if(i == 'raw') { |
| continue; |
| } |
| str += callSiteObj[i]; |
| if(i==0 && sub1) { |
| str += sub1; |
| } else if(i==1 && sub2) { |
| str += sub2; |
| } else if(i==2 && sub3) { |
| str += sub3; |
| } else if(i==3 && sub4) { |
| str += sub4; |
| } |
| } |
| |
| return str; |
| } |
| |
| function simpleRawTag(callSiteObj, sub1, sub2, sub3, sub4) { |
| var str = ''; |
| |
| for(var i in callSiteObj.raw) { |
| str += callSiteObj.raw[i]; |
| if(i==0 && sub1) { |
| str += sub1; |
| } else if(i==1 && sub2) { |
| str += sub2; |
| } else if(i==2 && sub3) { |
| str += sub3; |
| } else if(i==3 && sub4) { |
| str += sub4; |
| } |
| } |
| |
| return str; |
| } |
| |
| echo("Tag function takes less formal arguments than string template produces:"); |
| tag`str1 ${'str2'} str3 ${'str4'} str5`; |
| tag`str1 ${'str2'} str3 ${'str4'} str5 ${'str6'} str7`; |
| |
| echo("\nSimple tag function which assembles arguments:"); |
| echo(simpleTag`str1 ${'str2'} str3 ${'str4'} str5 ${'str6'} str7 ${'str8'} str9`); |
| |
| echo("\nSimple tag function which assembles raw arguments:"); |
| echo(simpleRawTag`str1 ${'str2'} str3 ${'str4'} str5 ${'str6'} str7 ${'str8'} str9`); |
| |
| function timesThirty(arg) { |
| return arg * 30; |
| } |
| echo("\nSubstitution which calls a function:"); |
| echo(`thirty = ${timesThirty(1)}. sixty = ${timesThirty(2)}.`); |
| |
| echo("\nFunction which returns a template literal:"); |
| function add(i, j) { |
| return `${i + j}`; |
| } |
| |
| echo(add(5,3)); |
| echo(add(500, 100)); |
| echo(add(`${add('hello'," world ")}`,1)); |
| |
| echo("\nSubstitution calls a built-in operator:"); |
| echo(`typeof 1 == ${typeof 1}.`); |
| |
| echo("\nNested templates with substitutions:"); |
| function getString() { return `funcreturn`; } |
| echo(`this is a nested ${`(nested template ${getString()}!)`} string template... ${getString()}s!`); |
| |
| echo(""); |
| |
| // Make sure we don't get spurious assignment tracking when incrementing a tagged template |
| try { |
| Function('function x(){}--++ x`${x--}`;')(); |
| } |
| catch(e) { |
| } |
| |
| function getCallSite(siteObj) { |
| return siteObj; |
| } |
| |
| function verifyCallSite(siteObj, cookedVals, rawVals) { |
| var success = true; |
| echo("Verifying siteObj against a known set of cooked and raw values..."); |
| |
| for(var i = 0; i < siteObj.length; i++) { |
| if(siteObj[i] !== cookedVals[i]) { |
| echo(`FAILED! (expected = ${cookedVals[i]})`); |
| success = false; |
| } |
| } |
| for(var i = 0; i < siteObj.raw.length; i++) { |
| if(siteObj.raw[i] !== rawVals[i]) { |
| echo(`FAILED! (expected = ${rawVals[i]})`); |
| success = false; |
| } |
| } |
| |
| if(success) { |
| echo(`PASSED |
| `); |
| } else { |
| echo(`FAILED |
| `); |
| } |
| } |
| |
| verifyCallSite(getCallSite`somestring`, ["somestring"], ["somestring"]); |
| verifyCallSite(getCallSite`\\`, ["\\"], ["\\\\"]); |
| verifyCallSite(getCallSite``, [""], [""]); |
| verifyCallSite(getCallSite`\u00b1`, ["\u00b1"], ["\\u00b1"]); |
| verifyCallSite(getCallSite`\ua48c`, ["\ua48c"], ["\\ua48c"]); |
| verifyCallSite(getCallSite`\u0023`, ["\u0023"], ["\\u0023"]); |
| verifyCallSite(getCallSite`\xF8`, ["\xF8"], ["\\xF8"]); |
| verifyCallSite(getCallSite`\h`, ["\h"], ["\\h"]); |
| verifyCallSite(getCallSite`\"`, ["\""], ["\\\""]); |
| verifyCallSite(getCallSite`\n`, ["\n"], ["\\n"]); |
| verifyCallSite(getCallSite`\r`, ["\r"], ["\\r"]); |
| verifyCallSite(getCallSite`\r\n`, ["\r\n"], ["\\r\\n"]); |
| verifyCallSite(getCallSite`\r\n\r\n`, ["\r\n\r\n"], ["\\r\\n\\r\\n"]); |
| verifyCallSite(getCallSite`\n\n\n\n\n\n\n\n\n\n`, ["\n\n\n\n\n\n\n\n\n\n"], ["\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"]); |
| verifyCallSite(getCallSite`$`, ["$"], ["$"]); |
| verifyCallSite(getCallSite`\"bunch of escape chars \v\t\n\b\a\"`, |
| ["\"bunch of escape chars \v\t\n\b\a\""], |
| ["\\\"bunch of escape chars \\v\\t\\n\\b\\a\\\""]); |
| verifyCallSite(getCallSite`rest of escape chars \b\t\f\r`, |
| ["rest of escape chars \b\t\f\r"], |
| ["rest of escape chars \\b\\t\\f\\r"]); |
| |
| verifyCallSite(getCallSite`\ |
| `, [""], ["\\\n"]); |
| verifyCallSite(getCallSite` |
| `, ["\n"], ["\n"]); |
| verifyCallSite(getCallSite` |
| `, ["\n"], ["\n"]); |
| verifyCallSite(getCallSite`\ |
| `, [""], ["\\\n"]); |
| verifyCallSite(getCallSite` |
| |
| `, ["\n\n"], ["\n\n"]); |
| verifyCallSite(getCallSite`
`, ["\u2028"], ["\u2028"]); |
| verifyCallSite(getCallSite`
`, ["\u2029"], ["\u2029"]); |
| verifyCallSite(getCallSite`$ $ $ {} } { }} {{`, ["$ $ $ {} } { }} {{"], ["$ $ $ {} } { }} {{"]); |
| |
| // String.raw must handle embedded null characters |
| function nullCharTest() { |
| function escapeNullCharacters(s) { |
| return (s+'').replace('\0', '\\0'); |
| } |
| |
| var s = String.raw`string literal pre ${'string expression pre \0 string expression post'} string literal post`; |
| return escapeNullCharacters(s); |
| } |
| echo(nullCharTest()); |