this function provides a string representation of the given object, similar to how console.log would represent it.

import { assertEquals } from "jsr:@std/assert"

assertEquals(
string_repr("a string"),
`a string`
)

assertEquals(
string_repr({ an: "object", with: ["an", "array"] }),
`{ an: "object", with: [ "an", "array" ] }`
)

assertEquals(
string_repr(new Map<any, any>([["a", 1], ["b", 2], [{ hello: "world" }, 3]])),
`Map(3) { "a" => 1, "b" => 2, { hello: "world" } => 3 }`
)

class Person {
name: string
age: number

constructor(name: string, age: number) {
this.name = name
this.age = age
}

greet() { return `Konichiwa! watashi no namae wa ${this.name}` }
}

assertEquals(
string_repr(new Person("sekiro", 2000)),
`Person { name: "sekiro", age: 2000 }`
)

const test_data = {
num: 123,
str: "text",
bool: false,
nil: null,
undef: undefined,
person: new Person("kenshiro", 99),
func: function example() {},
anon: () => {},
arr: [1, "two", { three: 3 }],
obj: { a: 1, b: { c: 2 }, self: undefined },
sym: Symbol("sym"),
bigInt: BigInt(200),
set: new Set([1, 2, 3, "kakashi", { itachi: "zabuza" }])
}
test_data.obj.self = test_data as any

assertEquals(string_repr(test_data),
`{ ` +
`num: 123, ` +
`str: "text", ` +
`bool: false, ` +
`nil: null, ` +
`undef: undefined, ` +
`person: Person { name: "kenshiro", age: 99 }, ` +
`func: [Function: example], ` +
`anon: [Function: anon], ` +
`arr: [ 1, "two", { three: 3 } ], ` +
`obj: { a: 1, b: { c: 2 }, self: [Circular] }, ` +
`sym: Symbol(sym), ` +
`bigInt: 200n, ` +
`set: Set(5) { 1, 2, 3, "kakashi", { itachi: "zabuza" } } ` +
`}`
)