Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/jsc/ConsoleObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}
Expand Down Expand Up @@ -3140,13 +3140,12 @@ pub const Formatter = struct {
}
}

if (try value.get(this.globalThis, "props")) |props| {
if (try value.get(this.globalThis, "props")) |props| props: {
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().?;
const props_obj = props.getObject() orelse break :props;
var props_iter = try jsc.JSPropertyIterator(.{
.skip_empty_name = true,
.include_value = true,
Expand Down
7 changes: 3 additions & 4 deletions src/test_runner/pretty_format.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1534,13 +1534,12 @@ pub const JestPrettyFormat = struct {
}
}

if (try value.get(this.globalThis, "props")) |props| {
if (try value.get(this.globalThis, "props")) |props| props: {
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().?;
const props_obj = props.getObject() orelse break :props;
var props_iter = try jsc.JSPropertyIterator(.{
.skip_empty_name = true,
.include_value = true,
Expand Down
50 changes: 50 additions & 0 deletions test/js/bun/util/inspect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,56 @@ it("jsx with fragment", () => {
expect(input).toBe(output);
});

it("jsx with circular reference in props", () => {
const el = {
$$typeof: Symbol.for("react.element"),
type: "div",
props: {},
};
el.props.foo = el;
expect(Bun.inspect(el)).toBe("<div foo=[Circular] />");
});

it("jsx with circular reference as props object", () => {
const el = {
$$typeof: Symbol.for("react.transitional.element"),
type: "div",
key: null,
ref: null,
props: {},
};
el.props = el;
expect(Bun.inspect(el)).toContain("[Circular]");
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

it("jsx with circular reference in key", () => {
const el = {
$$typeof: Symbol.for("react.element"),
type: "div",
};
el.key = el;
expect(Bun.inspect(el)).toBe("<div key=[Circular] />");
});

it("jsx with circular reference in children", () => {
const el = {
$$typeof: Symbol.for("react.element"),
type: "div",
props: { children: null },
};
el.props.children = el;
expect(Bun.inspect(el)).toBe("<div>\n [Circular]\n</div>");
});

it("jsx with non-object props", () => {
const el = {
$$typeof: Symbol.for("react.element"),
type: "div",
props: 123,
};
expect(Bun.inspect(el)).toBe("<div />");
});

it("inspect", () => {
expect(Bun.inspect(new TypeError("what")).includes("TypeError: what")).toBe(true);
expect(Bun.inspect("hi")).toBe('"hi"');
Expand Down
Loading