Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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.stdout.text(), proc.stderr.text(), proc.exited]);

expect(stderr).toContain("Expected: 1970-01-01T00:00:00.000Z");
expect(stderr).toContain("Received: Invalid Date");
expect(exitCode).toBe(1);
});
10 changes: 10 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,16 @@ 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(NaN)).not.toStrictEqual(new Date(0));
expect(new Date(0)).not.toEqual(new Date(NaN));
expect(new Date(0)).not.toStrictEqual(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