aboutsummaryrefslogtreecommitdiff
path: root/test/js/node/util/custom-inspect.test.js
diff options
context:
space:
mode:
authorGravatar dave caruso <me@paperdave.net> 2023-08-17 20:56:52 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-17 20:56:52 -0700
commit6fd0043f6bf766cc488a88339059e8879fa07161 (patch)
treed5289bcaf0880a3bf1e2f0b1c681aff93188fe51 /test/js/node/util/custom-inspect.test.js
parent0424fd8f6e7549ed779788006acdc97a8467e287 (diff)
downloadbun-6fd0043f6bf766cc488a88339059e8879fa07161.tar.gz
bun-6fd0043f6bf766cc488a88339059e8879fa07161.tar.zst
bun-6fd0043f6bf766cc488a88339059e8879fa07161.zip
Add `util.inspect.custom` support to `util.inspect/Bun.inspect/console.log` (#4194)
* start work on util.inspect.custom * asdf * finish util inspect custom inspect * inspect * fix tests * revert * tidy * revert * oops * test * fix issues
Diffstat (limited to 'test/js/node/util/custom-inspect.test.js')
-rw-r--r--test/js/node/util/custom-inspect.test.js155
1 files changed, 155 insertions, 0 deletions
diff --git a/test/js/node/util/custom-inspect.test.js b/test/js/node/util/custom-inspect.test.js
new file mode 100644
index 000000000..06cad262a
--- /dev/null
+++ b/test/js/node/util/custom-inspect.test.js
@@ -0,0 +1,155 @@
+// this file is compatible with jest to test node.js' util.inspect as well as bun's
+
+const util = require("util");
+
+test("util.inspect.custom exists", () => {
+ expect(util.inspect.custom).toEqual(Symbol.for("nodejs.util.inspect.custom"));
+});
+
+const customSymbol = util.inspect.custom;
+
+for (const [name, inspect] of process.versions.bun
+ ? [
+ ["util.inspect", util.inspect],
+ ["Bun.inspect", Bun.inspect],
+ ]
+ : [["util.inspect", util.inspect]]) {
+ test(name + " calls inspect.custom", () => {
+ const obj = {
+ [customSymbol]() {
+ return "42";
+ },
+ };
+
+ expect(inspect(obj)).toBe("42");
+ });
+
+ test(name + " calls inspect.custom recursivly", () => {
+ const obj = {
+ [customSymbol]() {
+ return {
+ [customSymbol]() {
+ return "42";
+ },
+ };
+ },
+ };
+
+ expect(inspect(obj)).toBe("42");
+ });
+
+ test(name + " calls inspect.custom recursivly nested", () => {
+ const obj = {
+ [customSymbol]() {
+ return {
+ prop: {
+ [customSymbol]() {
+ return "42";
+ },
+ },
+ };
+ },
+ };
+
+ expect(inspect(obj).replace(/\s/g, "")).toBe("{prop:42}");
+ });
+
+ test(name + " calls inspect.custom recursivly nested 2", () => {
+ const obj = {
+ prop: {
+ [customSymbol]() {
+ return {
+ [customSymbol]() {
+ return "42";
+ },
+ };
+ },
+ },
+ };
+
+ expect(inspect(obj).replace(/\s/g, "")).toBe("{prop:42}");
+ });
+
+ test(name + " calls inspect.custom with valid options", () => {
+ const obj = {
+ [customSymbol](depth, options, inspect) {
+ expect(this === obj).toBe(true);
+ expect(inspect).toBe(util.inspect);
+ expect(options.stylize).toBeDefined();
+ expect(depth).toBeDefined(2);
+ return "good";
+ },
+ };
+
+ expect(inspect(obj).replace(/\s/g, "")).toBe("good");
+ });
+
+ test(name + " stylize function works without color", () => {
+ const obj = {
+ [customSymbol](depth, options, inspect) {
+ expect(options.stylize).toBeDefined();
+ expect(options.stylize("foo", "whatever")).toBe("foo");
+ expect(options.stylize("hello", "string")).toBe("hello");
+ return "good";
+ },
+ };
+
+ expect(inspect(obj).replace(/\s/g, "")).toBe("good");
+ });
+
+ test(name + " stylize function works with color", () => {
+ const obj = {
+ [customSymbol](depth, options, inspect) {
+ expect(options.stylize).toBeDefined();
+ expect(options.stylize("foo", "invalid")).toBe("foo");
+ expect(options.stylize("foo", "boolean")).toBe("\u001b[33mfoo\u001b[39m");
+ expect(options.stylize("hello", "string")).toBe("\u001b[32mhello\u001b[39m");
+ return "good";
+ },
+ };
+
+ expect(inspect(obj, { colors: true }).replace(/\s/g, "")).toBe("good");
+ });
+
+ test(name + " stylize function gives correct depth", () => {
+ const obj = {
+ [customSymbol](depth, options, inspect) {
+ return [depth, options.depth];
+ },
+ };
+ expect(inspect(obj, { depth: 3 }).replace(/\s/g, "")).toBe("[3,3]");
+ });
+ test(name + " stylize function gives correct depth", () => {
+ const obj = {
+ prop: {
+ [customSymbol](depth, options, inspect) {
+ return [depth, options.depth];
+ },
+ },
+ };
+ expect(inspect(obj, { depth: 3 }).replace(/\s/g, "")).toBe("{prop:[2,3]}");
+ });
+ test(name + " non-callable does not get called", () => {
+ const obj = {
+ [customSymbol]: 512,
+ };
+ expect(inspect(obj, { depth: 3 }).replace(/\s/g, "")).toBe("{[Symbol(nodejs.util.inspect.custom)]:512}");
+ });
+
+ const exceptions = [new Error("don't crash!"), 42];
+
+ test.each(exceptions)(name + " handles exceptions %s", err => {
+ const obj = {
+ [customSymbol]() {
+ throw err;
+ },
+ };
+
+ if (Bun.inspect === inspect) {
+ // make sure this doesnt crash
+ expect(inspect(obj)).toBeString();
+ } else {
+ expect(() => inspect(obj)).toThrow();
+ }
+ });
+}