MIRROR: javascript for 🐜's, a tiny runtime with big ambitions
1// Template Literal Tests
2// Testing backtick (`) strings and ${} interpolation
3//
4// This test suite validates the template literal functionality including:
5// - Basic template literals with backticks
6// - Variable interpolation with ${}
7// - Expression evaluation within templates
8// - Multiple and consecutive interpolations
9// - Type conversion (numbers, booleans, objects)
10// - Multiline strings
11// - Escape sequences
12// - Complex expressions and nested calculations
13// - Integration with functions and methods
14// - Edge cases (empty, null, undefined)
15// - Practical use cases (URLs, receipts, error messages)
16
17console.log("=== Template Literal Tests ===\n");
18
19// Test 1: Basic template literal
20console.log("Test 1: Basic template literal");
21let basic = `Hello, World!`;
22console.log(" Result:", basic);
23console.log(" Type:", typeof basic);
24console.log(" Length:", basic.length);
25
26// Test 2: Single variable interpolation
27console.log("\nTest 2: Single variable interpolation");
28let name = "Alice";
29let greeting = `Hello, ${name}!`;
30console.log(" Name:", name);
31console.log(" Result:", greeting);
32
33// Test 3: Multiple variable interpolations
34console.log("\nTest 3: Multiple variable interpolations");
35let firstName = "John";
36let lastName = "Doe";
37let fullName = `${firstName} ${lastName}`;
38console.log(" First:", firstName);
39console.log(" Last:", lastName);
40console.log(" Full:", fullName);
41
42// Test 4: Numeric expressions
43console.log("\nTest 4: Numeric expressions");
44let a = 10;
45let b = 20;
46let sum = `${a} + ${b} = ${a + b}`;
47let product = `${a} * ${b} = ${a * b}`;
48let division = `${b} / ${a} = ${b / a}`;
49console.log(" Sum:", sum);
50console.log(" Product:", product);
51console.log(" Division:", division);
52
53// Test 5: Complex expressions
54console.log("\nTest 5: Complex expressions");
55let x = 5;
56let y = 3;
57let complex1 = `(${x} + ${y}) * 2 = ${(x + y) * 2}`;
58let complex2 = `Average of ${x} and ${y} is ${(x + y) / 2}`;
59console.log(" Complex 1:", complex1);
60console.log(" Complex 2:", complex2);
61
62// Test 6: Boolean interpolation
63console.log("\nTest 6: Boolean interpolation");
64let isActive = true;
65let isDisabled = false;
66let status1 = `Active: ${isActive}`;
67let status2 = `Disabled: ${isDisabled}`;
68console.log(" Status 1:", status1);
69console.log(" Status 2:", status2);
70
71// Test 7: Mixed types
72console.log("\nTest 7: Mixed types");
73let count = 42;
74let label = "items";
75let enabled = true;
76let mixed = `Status: ${enabled}, Count: ${count} ${label}`;
77console.log(" Result:", mixed);
78
79// Test 8: Empty template
80console.log("\nTest 8: Empty template");
81let empty = ``;
82console.log(" Result: '" + empty + "'");
83console.log(" Length:", empty.length);
84
85// Test 9: Template with only interpolation
86console.log("\nTest 9: Template with only interpolation");
87let value = 123;
88let onlyInterp = `${value}`;
89console.log(" Value:", value);
90console.log(" Result:", onlyInterp);
91console.log(" Type:", typeof onlyInterp);
92
93// Test 10: Consecutive interpolations
94console.log("\nTest 10: Consecutive interpolations");
95let n1 = 1;
96let n2 = 2;
97let n3 = 3;
98let consecutive = `${n1}${n2}${n3}`;
99console.log(" Result:", consecutive);
100
101// Test 11: String concatenation in interpolation
102console.log("\nTest 11: String concatenation in interpolation");
103let part1 = "Hello";
104let part2 = "World";
105let concatenated = `${part1 + " " + part2}`;
106console.log(" Part 1:", part1);
107console.log(" Part 2:", part2);
108console.log(" Result:", concatenated);
109
110// Test 12: Nested arithmetic
111console.log("\nTest 12: Nested arithmetic");
112let p = 3;
113let q = 4;
114let r = 5;
115let nested = `${p} * ${q} + ${r} = ${p * q + r}`;
116console.log(" Result:", nested);
117
118// Test 13: Comparison in template
119console.log("\nTest 13: Comparison in template");
120let age = 20;
121let canVote = `Age ${age}: Can vote = ${age >= 18}`;
122console.log(" Result:", canVote);
123
124// Test 14: Object property access
125console.log("\nTest 14: Object property access");
126let person = { name: "Bob", age: 25 };
127let personInfo = `${person.name} is ${person.age} years old`;
128console.log(" Result:", personInfo);
129
130// Test 15: Array indexing
131console.log("\nTest 15: Array indexing");
132let colors = ["red", "green", "blue"];
133let colorMsg = `First color: ${colors[0]}, Last: ${colors[2]}`;
134console.log(" Result:", colorMsg);
135
136// Test 16: Multiline template
137console.log("\nTest 16: Multiline template");
138let multiline = `Line 1
139Line 2
140Line 3`;
141console.log(" Result:", multiline);
142console.log(" Length:", multiline.length);
143
144// Test 17: Escape sequences
145console.log("\nTest 17: Escape sequences");
146let escaped = `Hello\nWorld\tTab`;
147console.log(" With escapes:", escaped);
148let withBackslash = `Path: C:\\Users\\Data`;
149console.log(" With backslash:", withBackslash);
150
151// Test 18: Template in function
152console.log("\nTest 18: Template in function");
153function greet(name, time) {
154 return `Good ${time}, ${name}!`;
155}
156let morning = greet("Alice", "morning");
157let evening = greet("Bob", "evening");
158console.log(" Morning:", morning);
159console.log(" Evening:", evening);
160
161// Test 19: Template with function call
162console.log("\nTest 19: Template with function call");
163function double(n) {
164 return n * 2;
165}
166let funcResult = `Double of 5 is ${double(5)}`;
167console.log(" Result:", funcResult);
168
169// Test 20: Combining with string methods
170console.log("\nTest 20: Combining with string methods");
171let word = "javascript";
172let upperFirst = word[0];
173let rest = word.slice(1);
174let capitalized = `${upperFirst}${rest}`;
175console.log(" Original:", word);
176console.log(" Capitalized:", capitalized);
177console.log(" Includes 'script':", capitalized.includes("script"));
178
179// Test 21: Price formatting example
180console.log("\nTest 21: Price formatting example");
181let price = 19.99;
182let quantity = 3;
183let tax = 0.08;
184let subtotal = price * quantity;
185let total = subtotal * (1 + tax);
186let receipt = `
187Item price: $${price}
188Quantity: ${quantity}
189Subtotal: $${subtotal}
190Tax (${tax * 100}%): $${subtotal * tax}
191Total: $${total}`;
192console.log(receipt);
193
194// Test 22: URL building
195console.log("\nTest 22: URL building");
196let protocol = "https";
197let domain = "example.com";
198let path = "api/users";
199let id = 123;
200let url = `${protocol}://${domain}/${path}/${id}`;
201console.log(" URL:", url);
202
203// Test 23: Error message formatting
204console.log("\nTest 23: Error message formatting");
205let errorCode = 404;
206let resource = "user";
207let errorMsg = `Error ${errorCode}: ${resource} not found`;
208console.log(" Error:", errorMsg);
209
210// Test 24: Conditional expression in template
211console.log("\nTest 24: Conditional expression in template");
212let score = 85;
213let grade = `Score: ${score} - ${score >= 90 ? "A" : score >= 80 ? "B" : "C"}`;
214console.log(" Result:", grade);
215
216// Test 25: Complex data formatting
217console.log("\nTest 25: Complex data formatting");
218let user = {
219 id: 1001,
220 name: "Charlie",
221 email: "charlie@example.com",
222 active: true
223};
224let userCard = `
225┌─────────────────────────
226│ ID: ${user.id}
227│ Name: ${user.name}
228│ Email: ${user.email}
229│ Status: ${user.active ? "Active" : "Inactive"}
230└─────────────────────────`;
231console.log(userCard);
232
233// Test 26: Edge case - very long interpolation
234console.log("\nTest 26: Edge case - very long interpolation");
235let longExpr = `Result: ${1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10}`;
236console.log(" Result:", longExpr);
237
238// Test 27: Template with null and undefined
239console.log("\nTest 27: Template with null and undefined");
240let nullVal = null;
241let undefVal = undefined;
242let nullMsg = `Null value: ${nullVal}`;
243let undefMsg = `Undefined value: ${undefVal}`;
244console.log(" Null:", nullMsg);
245console.log(" Undefined:", undefMsg);
246
247// Test 28: String with template-like syntax
248console.log("\nTest 28: String with template-like syntax");
249let innerCalc = 5 + 5;
250let template = `Template with inner calculation: ${innerCalc}`;
251console.log(" Result:", template);
252
253// Test 29: Large numbers
254console.log("\nTest 29: Large numbers");
255let big = 1000000;
256let formatted = `One million = ${big}`;
257console.log(" Result:", formatted);
258
259// Test 30: Performance test - multiple templates
260console.log("\nTest 30: Performance test");
261for (let i = 0; i < 5; i++) {
262 let msg = `Iteration ${i}: ${i * 2}`;
263 console.log(" " + msg);
264}
265
266console.log("\n=== All template literal tests completed ===");