Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
14 changes: 8 additions & 6 deletions src/bun.js/test/expect/toContainAnyKeys.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ pub fn toContainAnyKeys(

const count = try expected.getLength(globalThis);

var i: u32 = 0;
if (value.isObject()) {
var i: u32 = 0;

while (i < count) : (i += 1) {
const key = try expected.getIndex(globalThis, i);
while (i < count) : (i += 1) {
const key = try expected.getIndex(globalThis, i);

if (try value.hasOwnPropertyValue(globalThis, key)) {
pass = true;
break;
if (try value.hasOwnPropertyValue(globalThis, key)) {
pass = true;
break;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/bun.js/test/expect/toContainKeys.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ pub fn toContainKeys(
var pass = brk: {
const count = try expected.getLength(globalThis);

// jest-extended checks for truthiness before calling hasOwnProperty
// jest-extended checks for truthiness before calling hasOwnProperty, and we cannot call hasOwnPropertyValue with non-objects
// https://github.com/jest-community/jest-extended/blob/711fdcc54d68c2b2c1992c7cfbdf0d0bd6be0f4d/src/matchers/toContainKeys.js#L1-L6
if (!value.toBoolean()) break :brk count == 0;
if (!value.isObject()) break :brk count == 0;

var i: u32 = 0;

Expand Down
51 changes: 47 additions & 4 deletions test/js/bun/test/expect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2556,36 +2556,79 @@ describe("expect()", () => {
}).toThrow(isBun ? "Expected value must be an object\nReceived: undefined" : "undefined is not an object");
});

test("toContainAllKeys", () => {
test.only("toContainAllKeys", () => {
expect({ a: "hello", b: "world" }).toContainAllKeys(["a", "b"]);
expect({ a: "hello", b: "world" }).toContainAllKeys(["b", "a"]);
expect({ 1: "hello", b: "world" }).toContainAllKeys(["1", "b"]);
expect({ a: "hello", b: "world" }).not.toContainAllKeys(["c"]);
expect({ a: "hello", b: "world" }).not.toContainAllKeys(["a"]);
expect({ "": "hello", b: "world" }).toContainAllKeys(["", "b"]);

expect([1, 2, 3]).toContainAllKeys(["0", "1", "2"]);
expect([1, 2, 3]).not.toContainAllKeys(["0", "1", "2", "3"]);
});

test("toContainAnyKeys", () => {
test.only("toContainAnyKeys", () => {
expect({ a: "hello", b: "world" }).toContainAnyKeys(["a"]);
expect({ a: "hello", b: "world" }).toContainAnyKeys(["a", "c"]);
expect({ 1: "test", 2: "test2" }).toContainAnyKeys([1]);
expect({ a: "hello", b: "world" }).toContainAnyKeys(["b"]);
expect({ a: "hello", b: "world" }).toContainAnyKeys(["b", "c"]);
expect({ a: "hello", b: "world" }).not.toContainAnyKeys(["c"]);
});

test("toContainKeys", () => {
// Non-object values should not crash
expect(null).not.toContainAnyKeys(["a", "b"]);
expect(undefined).not.toContainAnyKeys(["a", "b"]);
expect(42).not.toContainAnyKeys(["a", "b"]);
expect("string").not.toContainAnyKeys(["a", "b"]);
expect(true).not.toContainAnyKeys(["a", "b"]);
expect(false).not.toContainAnyKeys(["a", "b"]);
expect(Symbol("test")).not.toContainAnyKeys(["a", "b"]);
expect(BigInt(123)).not.toContainAnyKeys(["a", "b"]);

// Arrays should work with numeric string keys
expect([1, 2, 3]).toContainAnyKeys(["0", "1"]);
expect([1, 2, 3]).not.toContainAnyKeys(["a", "b"]);

// Functions are objects
const fn = () => {};
fn.customProp = "test";
expect(fn).toContainAnyKeys(["customProp"]);
expect(fn).not.toContainAnyKeys(["otherProp"]);

// Object.create(null)
const objWithoutProto = Object.create(null);
objWithoutProto.a = 1;
expect(objWithoutProto).toContainAnyKeys(["a", "b"]);
expect(objWithoutProto).not.toContainAnyKeys(["b", "c"]);
});

test.only("toContainKeys", () => {
expect({ a: "foo", b: "bar", c: "baz" }).toContainKeys(["a", "b"]);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
expect({ a: "foo", b: "bar", c: "baz" }).toContainKeys(["a", "b", "c"]);
expect({ a: "foo", 1: "test" }).toContainKeys(["a", 1]);
expect({ a: "foo", b: "bar", c: "baz" }).not.toContainKeys(["a", "b", "e"]);
expect({ a: "foo", b: "bar", c: "baz" }).not.toContainKeys(["z"]);

// Non-object values
expect(undefined).not.toContainKeys(["id"]);
expect(null).not.toContainKeys(["id"]);
expect("").toContainKeys([]);
expect("").not.toContainKeys(["id"]);
expect(false).toContainKeys([]);
expect(false).not.toContainKeys(["id"]);
expect(42).toContainKeys([]);
expect(42).not.toContainKeys(["id"]);
expect(true).toContainKeys([]);
expect(true).not.toContainKeys(["id"]);
expect(Symbol("test")).toContainKeys([]);
expect(Symbol("test")).not.toContainKeys(["id"]);
expect(BigInt(123)).toContainKeys([]);
expect(BigInt(123)).not.toContainKeys(["id"]);

// Arrays with numeric string keys
expect([1, 2, 3]).toContainKeys(["0", "1"]);
expect([1, 2, 3]).not.toContainKeys(["0", "1", "3"]);

expect(() => {
expect(undefined).toContainKeys(["id"]);
Expand Down