diff --git a/src/jsc/ConsoleObject.zig b/src/jsc/ConsoleObject.zig index 2489ea14ea03..8683ca2be634 100644 --- a/src/jsc/ConsoleObject.zig +++ b/src/jsc/ConsoleObject.zig @@ -1136,7 +1136,7 @@ pub const Formatter = struct { pub fn canHaveCircularReferences(tag: Tag) bool { return switch (tag) { - .Function, .Array, .Object, .Map, .Set, .Error, .Class, .Event => true, + .Function, .Array, .Object, .Map, .Set, .Error, .Class, .Event, .JSX => true, else => false, }; } @@ -3140,13 +3140,12 @@ pub const Formatter = struct { } } - if (try value.get(this.globalThis, "props")) |props| { + if (if (try value.get(this.globalThis, "props")) |props| props.getObject() else null) |props_obj| { + const props = props_obj.toJS(); const prev_quote_strings = this.quote_strings; defer this.quote_strings = prev_quote_strings; this.quote_strings = true; - // SAFETY: JSX props are always objects - const props_obj = props.getObject().?; var props_iter = try jsc.JSPropertyIterator(.{ .skip_empty_name = true, .include_value = true, diff --git a/src/test_runner/pretty_format.zig b/src/test_runner/pretty_format.zig index 2a5fcdaf5600..2f311db26860 100644 --- a/src/test_runner/pretty_format.zig +++ b/src/test_runner/pretty_format.zig @@ -326,7 +326,7 @@ pub const JestPrettyFormat = struct { } pub inline fn canHaveCircularReferences(tag: Tag) bool { - return tag == .Array or tag == .Object or tag == .Map or tag == .Set; + return tag == .Array or tag == .Object or tag == .Map or tag == .Set or tag == .JSX; } const Result = struct { @@ -1534,13 +1534,12 @@ pub const JestPrettyFormat = struct { } } - if (try value.get(this.globalThis, "props")) |props| { + if (if (try value.get(this.globalThis, "props")) |props| props.getObject() else null) |props_obj| { + const props = props_obj.toJS(); const prev_quote_strings = this.quote_strings; defer this.quote_strings = prev_quote_strings; this.quote_strings = true; - // SAFETY: JSX props are always an object. - const props_obj = props.getObject().?; var props_iter = try jsc.JSPropertyIterator(.{ .skip_empty_name = true, .include_value = true, diff --git a/test/js/bun/util/inspect.test.js b/test/js/bun/util/inspect.test.js index 32a70af30183..566670f9d75d 100644 --- a/test/js/bun/util/inspect.test.js +++ b/test/js/bun/util/inspect.test.js @@ -772,3 +772,40 @@ it("CustomEvent", () => { }" `); }); + +describe("JSX element", () => { + it("handles circular key", () => { + const elem = { + $$typeof: Symbol.for("react.element"), + type: "div", + key: null, + ref: null, + props: { children: [] }, + }; + elem.key = elem; + expect(Bun.inspect(elem)).toContain("[Circular]"); + }); + + it("handles circular children", () => { + const elem = { + $$typeof: Symbol.for("react.element"), + type: "div", + key: null, + ref: null, + props: {}, + }; + elem.props.children = elem; + expect(Bun.inspect(elem)).toContain("[Circular]"); + }); + + it("handles non-object props", () => { + const elem = { + $$typeof: Symbol.for("react.element"), + type: "div", + key: null, + ref: null, + props: 123, + }; + expect(Bun.inspect(elem)).toBe("
"); + }); +});