function testBoxed(name, obj, primitiveValue, expectedToString) {
console.log(`--- Testing ${name} ---`);
console.log(`typeof:`, typeof obj);
console.log(`value:`, obj);
try {
const val = obj.valueOf();
console.log(`valueOf():`, val);
} catch (e) {
console.log(`FAIL: valueOf() threw`, e);
}
try {
const str = obj.toString();
console.log(`toString():`, str);
} catch (e) {
console.log(`FAIL: toString() threw`, e);
}
}
testBoxed('Boolean', new Boolean(true), true, 'true');
testBoxed('Boolean', new Boolean(false), false, 'false');
testBoxed('Number', new Number(123), 123, '123');
testBoxed('String', new String("hello"), "hello", "hello");
try {
const bi = Object(123n);
testBoxed('BigInt', bi, 123n, '123');
} catch (e) {
console.log("BigInt test skipped or failed setup:", e);
throw e;
}
try {
const sym = Symbol("foo");
const symObj = Object(sym);
testBoxed('Symbol', symObj, sym, 'Symbol(foo)');
} catch (e) {
console.log("Symbol test skipped or failed setup:", e);
throw e;
}
{
function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion failed");
}
}
}
assert(!false, "false should be falsy");
assert(!undefined, "undefined should be falsy");
assert(!null, "null should be falsy");
assert(!0, "0 should be falsy");
assert(!NaN, "NaN should be falsy");
assert(!"", "empty string should be falsy");
assert(!!true, "true should be truthy");
assert(!!{}, "non-empty object should be truthy");
assert(!![], "non-empty array should be truthy");
assert(!!42, "non-zero number should be truthy");
assert(!!"hello", "non-empty string should be truthy");
console.log("All assertions passed!");