Skip to content

Commit

Permalink
fix bug in assert.equals
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Feb 5, 2025
1 parent 1c59448 commit 228ae3a
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 27 deletions.
30 changes: 17 additions & 13 deletions src/bun.js/bindings/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,19 @@ bool Bun__deepMatch(
return true;
}

// anonymous namespace to avoid name collision
namespace {
template<bool isStrict, bool enableAsymmetricMatchers>
inline bool deepEqualsWrapperImpl(JSC__JSValue a, JSC__JSValue b, JSC__JSGlobalObject* global)
{
auto& vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Vector<std::pair<JSC::JSValue, JSC::JSValue>, 16> stack;
MarkedArgumentBuffer args;
return Bun__deepEquals<isStrict, enableAsymmetricMatchers>(global, JSC::JSValue::decode(a), JSC::JSValue::decode(b), args, stack, &scope, true);
}
}

extern "C" {

bool WebCore__FetchHeaders__isEmpty(WebCore__FetchHeaders* arg0)
Expand Down Expand Up @@ -2452,33 +2465,24 @@ bool JSC__JSValue__isSameValue(JSC__JSValue JSValue0, JSC__JSValue JSValue1,
return JSC::sameValue(globalObject, left, right);
}

#define IMPL_DEEP_EQUALS_WRAPPER(strict, enableAsymmetricMatchers, globalObject, a, b) \
ASSERT_NO_PENDING_EXCEPTION(globalObject); \
JSValue v1 = JSValue::decode(a); \
JSValue v2 = JSValue::decode(b); \
ThrowScope scope = DECLARE_THROW_SCOPE(globalObject->vm()); \
Vector<std::pair<JSValue, JSValue>, 16> stack; \
MarkedArgumentBuffer args; \
return Bun__deepEquals<strict, enableAsymmetricMatchers>(globalObject, v1, v2, args, stack, &scope, true)

bool JSC__JSValue__deepEquals(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* globalObject)
{
IMPL_DEEP_EQUALS_WRAPPER(false, false, globalObject, JSValue0, JSValue1);
return deepEqualsWrapperImpl<false, false>(JSValue0, JSValue1, globalObject);
}

bool JSC__JSValue__jestDeepEquals(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* globalObject)
{
IMPL_DEEP_EQUALS_WRAPPER(false, true, globalObject, JSValue0, JSValue1);
return deepEqualsWrapperImpl<false, true>(JSValue0, JSValue1, globalObject);
}

bool JSC__JSValue__strictDeepEquals(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* globalObject)
{
IMPL_DEEP_EQUALS_WRAPPER(true, false, globalObject, JSValue0, JSValue1);
return deepEqualsWrapperImpl<true, false>(JSValue0, JSValue1, globalObject);
}

bool JSC__JSValue__jestStrictDeepEquals(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* globalObject)
{
IMPL_DEEP_EQUALS_WRAPPER(true, true, globalObject, JSValue0, JSValue1);
return deepEqualsWrapperImpl<true, true>(JSValue0, JSValue1, globalObject);
}

#undef IMPL_DEEP_EQUALS_WRAPPER
Expand Down
5 changes: 2 additions & 3 deletions src/js/node/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,8 @@ assert.equal = function equal(actual: unknown, expected: unknown, message?: stri
if (arguments.length < 2) {
throw $ERR_MISSING_ARGS("actual", "expected");
}
// eslint-disable-next-line eqeqeq
// if (actual != expected && (!NumberIsNaN(actual) || !NumberIsNaN(expected))) {
if (actual != expected && !(isNaN(actual) && isNaN(expected))) {

if (actual != expected && (!NumberIsNaN(actual) || !NumberIsNaN(expected))) {
innerFail({
actual,
expected,
Expand Down
4 changes: 4 additions & 0 deletions test/js/bun/test/jest.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ declare var describe: typeof import("bun:test").describe;
declare var test: typeof import("bun:test").test;
declare var expect: typeof import("bun:test").expect;
declare var it: typeof import("bun:test").it;
declare var beforeEach: typeof import("bun:test").beforeEach;
declare var afterEach: typeof import("bun:test").afterEach;
declare var beforeAll: typeof import("bun:test").beforeAll;
declare var afterAll: typeof import("bun:test").afterAll;
37 changes: 37 additions & 0 deletions test/js/node/assert/assert.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, it, expect } from "bun:test";
import assert from "assert";

describe("assert(expr)", () => {
// https://github.com/oven-sh/bun/issues/941
it.each([true, 1, "foo"])(`assert(%p) does not throw`, expr => {
expect(() => assert(expr)).not.toThrow();
});

it.each([false, 0, "", null, undefined])(`assert(%p) throws`, expr => {
expect(() => assert(expr)).toThrow(assert.AssertionError);
});

it("is an alias for assert.ok", () => {
expect(assert).toBe(assert.ok);
});
});

describe("assert.equal(actual, expected)", () => {
it.each([
["foo", "foo"],
[1, 1],
[1, true],
[0, ""],
[0, false],
])(`%p == %p`, (actual, expected) => {
expect(() => assert.equal(actual, expected)).not.toThrow();
});
it.each([
//
["foo", "bar"],
[1, 0],
[true, false],
])("%p != %p", (actual, expected) => {
expect(() => assert.equal(actual, expected)).toThrow(assert.AssertionError);
});
});
11 changes: 0 additions & 11 deletions test/js/node/assert/assert.test.ts

This file was deleted.

0 comments on commit 228ae3a

Please sign in to comment.