1/* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals 17// Tagged templates 18var person = 'Mike'; 19var age = 28; 20 21function myTag(strings, personExp, ageExp) { 22 assert(strings[0] == "That "); 23 assert(strings[1] == " is a "); 24 var str0 = strings[0]; 25 var str1 = strings[1]; 26 27 var ageStr; 28 if (ageExp > 99){ 29 ageStr = 'centenarian'; 30 } else { 31 ageStr = 'youngster'; 32 } 33 34 return `${str0}${personExp}${str1}${ageStr}`; 35} 36 37var output = myTag`That ${ person } is a ${ age }`; 38assert(output === "That Mike is a youngster"); 39 40function template(strings, ...keys) { 41 return (function(...values) { 42 var dict = values[values.length - 1] || {}; 43 var result = [strings[0]]; 44 keys.forEach(function(key, i) { 45 var value = Number.isInteger(key) ? values[key] : dict[key]; 46 result.push(value, strings[i + 1]); 47 }); 48 return result.join(''); 49 }); 50} 51 52var t1Closure = template`${0}${1}${0}!`; 53assert(t1Closure('Y', 'A') === "YAY!"); 54var t2Closure = template`${0} ${'foo'}!`; 55assert(t2Closure('Hello', {foo: 'World'}) === "Hello World!"); 56 57// Raw strings 58(function () { 59 function tag(strings) { 60 assert(strings.raw[0].length === 40); 61 } 62 63 tag`string text line 1 \n string text line 2`; 64})(); 65 66assert (String.raw`Hi\n${2+3}!` === "Hi\\n5!"); 67 68(function () { 69 function empty(strings, ...params) { 70 assert(strings.length === 4); 71 assert(strings.raw.length === 4); 72 assert(params.length === 3); 73 strings.forEach ((e) => assert (e === "")); 74 strings.raw.forEach ((e) => assert (e === "")); 75 params.forEach ((e) => assert (e === 1)); 76 } 77 78 empty`${1}${1}${1}`; 79})(); 80 81(function () { 82 function f (str) { 83 return str.raw[0].length; 84 } 85 assert (eval("f`a\u2029b`") === 3); 86})(); 87 88(function () { 89 function testRaw(parts, a, b) { 90 assert(parts instanceof Array); 91 assert(parts.raw instanceof Array); 92 assert(parts.length === 3); 93 assert(parts[0] === "str"); 94 assert(parts[1] === "escaped\n"); 95 assert(parts[2] === ""); 96 assert(parts.raw.length === 3); 97 assert(parts.raw[0] === "str"); 98 assert(parts.raw[1] === "escaped\\n"); 99 assert(parts.raw[2] === ""); 100 assert(a === 123); 101 assert(b === 456); 102 return true; 103 } 104 105 assert(testRaw `str${123}escaped\n${456}` === true); 106})(); 107 108// TemplateStrings call site caching 109(function () { 110 let str = (arr) => arr; 111 function getStr() { 112 return str`foo`; 113 } 114 var chainedCall = getStr(); 115 var localCall = str`foo`; 116 assert(chainedCall === getStr() && chainedCall !== localCall); 117})(); 118 119// TemplateStrings permanent caching 120(function () { 121 let str = (arr) => arr; 122 function getStr() { 123 return str`foo`; 124 } 125 var chainedCall = getStr(); 126 var localNew = new getStr(); 127 assert(chainedCall === getStr() && chainedCall === localNew); 128})(); 129 130var templateObject; 131 132(function(p) { 133 templateObject = p; 134})`str`; 135 136var desc = Object.getOwnPropertyDescriptor(templateObject, '0'); 137assert(desc.writable === false); 138assert(desc.enumerable === true); 139assert(desc.configurable === false); 140