MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1// ============================================
2// TEST: String() uses inspect instead of toString
3// ============================================
4// Bug: String(obj) uses inspect-style output instead of calling toString()
5// ============================================
6
7console.log("=== String() CONSTRUCTOR TESTS ===\n");
8
9// --- PRIMITIVES ---
10
11console.log("1. Primitives:");
12console.log(" String(42): expected '42', got '" + String(42) + "'");
13console.log(" String('hi'): expected 'hi', got '" + String("hi") + "'");
14console.log(" String(true): expected 'true', got '" + String(true) + "'");
15console.log(" String(false): expected 'false', got '" + String(false) + "'");
16console.log(" String(null): expected 'null', got '" + String(null) + "'");
17console.log(" String(undefined): expected 'undefined', got '" + String(undefined) + "'");
18console.log(" String(123n): expected '123', got '" + String(123n) + "'");
19
20// --- ARRAYS ---
21
22console.log("\n2. Array [1, 2, 3]:");
23const arr1 = [1, 2, 3];
24console.log(" expected: '1,2,3'");
25console.log(" String(): '" + String(arr1) + "'");
26console.log(" toString: '" + arr1.toString() + "'");
27
28console.log("\n3. Nested array [[1,2], [3,4]]:");
29const arr2 = [[1, 2], [3, 4]];
30console.log(" expected: '1,2,3,4'");
31console.log(" String(): '" + String(arr2) + "'");
32console.log(" toString: '" + arr2.toString() + "'");
33
34console.log("\n4. Empty array []:");
35const arr3 = [];
36console.log(" expected: ''");
37console.log(" String(): '" + String(arr3) + "'");
38
39console.log("\n5. Array with objects:");
40const arr4 = [{ a: 1 }, { b: 2 }];
41console.log(" expected: '[object Object],[object Object]'");
42console.log(" String(): '" + String(arr4) + "'");
43
44// --- FUNCTIONS ---
45
46console.log("\n6. Arrow function:");
47const fn1 = () => 1;
48console.log(" expected: '() => 1'");
49console.log(" String(): '" + String(fn1) + "'");
50console.log(" toString: '" + fn1.toString() + "'");
51
52console.log("\n7. Named function:");
53function namedFn() { return 1; }
54console.log(" expected: 'function namedFn() { return 1; }'");
55console.log(" String(): '" + String(namedFn) + "'");
56console.log(" toString: '" + namedFn.toString() + "'");
57
58console.log("\n8. Async function:");
59async function asyncFn() { return 1; }
60console.log(" expected: 'async function asyncFn() { return 1; }'");
61console.log(" String(): '" + String(asyncFn) + "'");
62console.log(" toString: '" + asyncFn.toString() + "'");
63
64// --- OBJECTS ---
65
66console.log("\n9. Plain object {}:");
67const obj1 = {};
68console.log(" expected: '[object Object]'");
69console.log(" String(): '" + String(obj1) + "'");
70
71console.log("\n10. Object with properties:");
72const obj2 = { a: 1, b: 2 };
73console.log(" expected: '[object Object]'");
74console.log(" String(): '" + String(obj2) + "'");
75
76console.log("\n11. Object with custom toString:");
77const obj3 = { toString: function() { return "custom-toString"; } };
78console.log(" expected: 'custom-toString'");
79console.log(" toString: '" + obj3.toString() + "'");
80console.log(" String(): '" + String(obj3) + "'");
81
82console.log("\n12. Object with valueOf only:");
83const obj4 = { valueOf: function() { return "custom-valueOf"; } };
84console.log(" expected: 'custom-valueOf' or '[object Object]'");
85console.log(" String(): '" + String(obj4) + "'");
86
87console.log("\n13. Object with both toString and valueOf:");
88const obj5 = {
89 toString: function() { return "from-toString"; },
90 valueOf: function() { return "from-valueOf"; }
91};
92console.log(" expected: 'from-toString' (toString has priority)");
93console.log(" String(): '" + String(obj5) + "'");
94
95// --- BUILT-IN OBJECTS ---
96
97console.log("\n14. Date:");
98const date = new Date(0);
99console.log(" expected: date string like 'Thu Jan 01 1970...'");
100console.log(" String(): '" + String(date) + "'");
101console.log(" toString: '" + date.toString() + "'");
102
103console.log("\n15. RegExp:");
104const re = /test/gi;
105console.log(" expected: '/test/gi'");
106console.log(" String(): '" + String(re) + "'");
107console.log(" toString: '" + re.toString() + "'");
108
109console.log("\n16. Error:");
110const err = new Error("oops");
111console.log(" expected: 'Error: oops'");
112console.log(" String(): '" + String(err) + "'");
113console.log(" toString: '" + err.toString() + "'");
114
115console.log("\n17. Map:");
116const map = new Map([["a", 1]]);
117console.log(" expected: '[object Map]'");
118console.log(" String(): '" + String(map) + "'");
119
120console.log("\n18. Set:");
121const set = new Set([1, 2, 3]);
122console.log(" expected: '[object Set]'");
123console.log(" String(): '" + String(set) + "'");
124
125// --- SYMBOL ---
126
127console.log("\n19. Symbol:");
128const sym = Symbol("test");
129console.log(" expected: 'Symbol(test)'");
130console.log(" String(): '" + String(sym) + "'");
131console.log(" toString: '" + sym.toString() + "'");
132
133// --- Symbol.toPrimitive ---
134
135console.log("\n20. Object with Symbol.toPrimitive:");
136const obj6 = {};
137obj6[Symbol.toPrimitive] = function(hint) { return "toPrimitive-" + hint; };
138console.log(" expected: 'toPrimitive-string'");
139console.log(" String(): '" + String(obj6) + "'");
140
141// --- CLASS INSTANCES ---
142
143console.log("\n21. Class instance with toString:");
144class MyClass {
145 toString() { return "MyClass instance"; }
146}
147const inst = new MyClass();
148console.log(" expected: 'MyClass instance'");
149console.log(" toString: '" + inst.toString() + "'");
150console.log(" String(): '" + String(inst) + "'");
151
152console.log("\n22. Class instance without toString:");
153class PlainClass {}
154const inst2 = new PlainClass();
155console.log(" expected: '[object Object]'");
156console.log(" String(): '" + String(inst2) + "'");
157
158console.log("\n=== DONE ===");