Skip to content
Open
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
5 changes: 4 additions & 1 deletion src/jsc/bindings/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,10 @@ std::optional<bool> specialObjectsDequal(JSC::JSGlobalObject* globalObject, Mark
JSC::DateInstance* left = uncheckedDowncast<DateInstance>(c1);
JSC::DateInstance* right = uncheckedDowncast<DateInstance>(c2);

return left->internalNumber() == right->internalNumber();
double leftTime = left->internalNumber();
double rightTime = right->internalNumber();
// Two Invalid Dates (NaN time values) are equal, matching Node.js.
return leftTime == rightTime || (std::isnan(leftTime) && std::isnan(rightTime));
}
case RegExpObjectType: {
if (c2Type != RegExpObjectType) {
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/test_runner/pretty_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1937,7 +1937,10 @@ impl<'a> Formatter<'a> {
Err(_) => b"",
}
};
if out_buf.len() > 2 {
if out_buf == b"null" {
// JSON.stringify(new Date(NaN)) is `null` (unquoted)
out_buf = b"Invalid Date";
Comment thread
coderabbitai[bot] marked this conversation as resolved.
} else if out_buf.len() > 2 {
// trim the quotes
out_buf = &out_buf[1..out_buf.len() - 1];
}
Expand Down
2 changes: 2 additions & 0 deletions test/js/bun/bun-object/deep-equals.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe.each([true, false])("Bun.deepEquals(a, b, strict: %p)", strict => {
[new Set(), new Set()],
[Symbol.for("foo"), Symbol.for("foo")],
[NaN, NaN],
[new Date(NaN), new Date(NaN)],
])("Bun.deepEquals(%p, %p) === true, regardless of strict modee", (a, b) => {
expect(Bun.deepEquals(a, b, true)).toBe(true);
expect(Bun.deepEquals(a, b, false)).toBe(true);
Expand All @@ -24,6 +25,7 @@ describe.each([true, false])("Bun.deepEquals(a, b, strict: %p)", strict => {
[-0, +0], //
[{ a: 1 }, { a: 2 }],
["foo", "bar"],
[new Date(NaN), new Date(0)],
])("Bun.deepEquals(%p, %p) !== true, regardless of strict modee", (a, b) => {
expect(Bun.deepEquals(a, b, true)).toBe(false);
expect(Bun.deepEquals(a, b, false)).toBe(false);
Expand Down
29 changes: 29 additions & 0 deletions test/js/bun/test/expect-invalid-date-message.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Failure messages for Invalid Date must print "Invalid Date".
// JSON.stringify(new Date(NaN)) is `null` (unquoted), and the quote-trimming
// pass used to slice it down to the garbage string "ul".

import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDir } from "harness";

test("expect() failure messages render Invalid Date, not a sliced 'null'", async () => {
using dir = tempDir("expect-invalid-date", {
"invalid-date.test.ts": `
import { test, expect } from "bun:test";
test("invalid date vs valid date", () => {
expect(new Date(NaN)).toEqual(new Date(0));
});
`,
});
await using proc = Bun.spawn({
cmd: [bunExe(), "test", "invalid-date.test.ts"],
env: { ...bunEnv, NO_COLOR: "1", FORCE_COLOR: undefined },
cwd: String(dir),
stdout: "pipe",
stderr: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);

Check warning on line 24 in test/js/bun/test/expect-invalid-date-message.test.ts

View check run for this annotation

Claude / Claude Code Review

Subprocess test pipes stdout but never drains it

`stdout: "pipe"` is set on line 21 but the `Promise.all` on line 24 never drains `proc.stdout` — per the harness convention (REVIEW.md "Subprocess tests: drain pipes concurrently"), an unread pipe can fill the OS buffer and wedge the child. Since stdout isn't asserted on, either drop `stdout: "pipe"` or add `proc.stdout.text()` to the `Promise.all`.
Comment thread
robobun marked this conversation as resolved.
Outdated

expect(stderr).toContain("Expected: 1970-01-01T00:00:00.000Z");
expect(stderr).toContain("Received: Invalid Date");
expect(exitCode).toBe(1);
});
8 changes: 8 additions & 0 deletions test/js/bun/test/expect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,14 @@ describe("expect()", () => {
expect(d).toEqual(e);
expect(e).toEqual(d);

if (isBun) {
// Two Invalid Dates are equal, matching Node.js (jest disagrees).
expect(new Date(NaN)).toEqual(new Date(NaN));
expect(new Date(NaN)).toStrictEqual(new Date(NaN));
expect(new Date(NaN)).not.toEqual(new Date(0));
expect(new Date(0)).not.toEqual(new Date(NaN));
}
Comment thread
robobun marked this conversation as resolved.

class Date2 extends Date {
constructor() {
// @ts-ignore
Expand Down
2 changes: 2 additions & 0 deletions test/js/node/assert/deep-equal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ const cases: Case[] = [
// Date.
{ name: "two equal dates", a: () => new Date(0), b: () => new Date(0), strict: true, loose: true },
{ name: "two different dates", a: () => new Date(0), b: () => new Date(1), strict: false, loose: false },
{ name: "two invalid dates", a: () => new Date(NaN), b: () => new Date(NaN), strict: true, loose: true },
{ name: "an invalid and a valid date", a: () => new Date(NaN), b: () => new Date(0), strict: false, loose: false },
{
name: "a date with an extra own property",
a: () => withExtraProperty(new Date(0)),
Expand Down
Loading