aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-types/bun-test.d.ts9
-rw-r--r--src/bun.js/test/jest.zig65
-rw-r--r--test/bun.js/bun-test/matchers.test.ts11
3 files changed, 84 insertions, 1 deletions
diff --git a/packages/bun-types/bun-test.d.ts b/packages/bun-types/bun-test.d.ts
index c620050ec..56d847b74 100644
--- a/packages/bun-types/bun-test.d.ts
+++ b/packages/bun-types/bun-test.d.ts
@@ -341,6 +341,15 @@ declare module "bun:test" {
* expect(undefined).toBeDefined(); // fail
*/
toBeDefined(): void;
+ /**
+ * Asserts that the expected value is an instance of value
+ *
+ * @example
+ * expect([]).toBeInstanceOf(Array);
+ * expect(null).toBeInstanceOf(Array); // fail
+ */
+ toBeInstanceOf(value: Function): void;
+
/**
* Asserts that a value is `undefined`.
*
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index 5571294c7..2cb86c4f7 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -2080,6 +2080,70 @@ pub const Expect = struct {
return .zero;
}
+ pub fn toBeInstanceOf(this: *Expect, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue {
+ defer this.postMatch(globalObject);
+
+ const thisValue = callFrame.this();
+ const _arguments = callFrame.arguments(1);
+ const arguments: []const JSValue = _arguments.ptr[0.._arguments.len];
+
+ if (arguments.len < 1) {
+ globalObject.throwInvalidArguments("toBeInstanceOf() requires 1 argument", .{});
+ return .zero;
+ }
+
+ if (this.scope.tests.items.len <= this.test_id) {
+ globalObject.throw("toBeInstanceOf() must be called in a test", .{});
+ return .zero;
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const expected_value = arguments[0];
+ if (!expected_value.jsType().isFunction()) {
+ var fmt = JSC.ZigConsoleClient.Formatter{ .globalThis = globalObject, .quote_strings = true };
+ globalObject.throw("Expected value must be a function: {any}", .{expected_value.toFmt(globalObject, &fmt)});
+ return .zero;
+ }
+ expected_value.ensureStillAlive();
+
+ const value = Expect.capturedValueGetCached(thisValue) orelse {
+ globalObject.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{});
+ return .zero;
+ };
+ value.ensureStillAlive();
+
+ const not = this.op.contains(.not);
+ var pass = value.isInstanceOf(globalObject, expected_value);
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ // handle failure
+ var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalObject, .quote_strings = true };
+ const value_fmt = value.toFmt(globalObject, &formatter);
+ if (not) {
+ const received_line = "Received: <red>{any}<r>\n";
+ const fmt = comptime getSignature("toBeInstanceOf", "", true) ++ "\n\n" ++ received_line;
+ if (Output.enable_ansi_colors) {
+ globalObject.throw(Output.prettyFmt(fmt, true), .{value_fmt});
+ return .zero;
+ }
+
+ globalObject.throw(Output.prettyFmt(fmt, false), .{value_fmt});
+ return .zero;
+ }
+
+ const received_line = "Received: <red>{any}<r>\n";
+ const fmt = comptime getSignature("toBeInstanceOf", "", false) ++ "\n\n" ++ received_line;
+ if (Output.enable_ansi_colors) {
+ globalObject.throw(Output.prettyFmt(fmt, true), .{value_fmt});
+ return .zero;
+ }
+
+ globalObject.throw(Output.prettyFmt(fmt, false), .{value_fmt});
+ return .zero;
+ }
+
pub const toHaveBeenCalledTimes = notImplementedJSCFn;
pub const toHaveBeenCalledWith = notImplementedJSCFn;
pub const toHaveBeenLastCalledWith = notImplementedJSCFn;
@@ -2089,7 +2153,6 @@ pub const Expect = struct {
pub const toHaveLastReturnedWith = notImplementedJSCFn;
pub const toHaveNthReturnedWith = notImplementedJSCFn;
pub const toBeCloseTo = notImplementedJSCFn;
- pub const toBeInstanceOf = notImplementedJSCFn;
pub const toContainEqual = notImplementedJSCFn;
pub const toMatch = notImplementedJSCFn;
pub const toMatchObject = notImplementedJSCFn;
diff --git a/test/bun.js/bun-test/matchers.test.ts b/test/bun.js/bun-test/matchers.test.ts
new file mode 100644
index 000000000..8322c55a6
--- /dev/null
+++ b/test/bun.js/bun-test/matchers.test.ts
@@ -0,0 +1,11 @@
+import { describe, expect, test } from "bun:test";
+
+describe("different kinds of matchers", () => {
+ test("toBeInstanceOf", () => {
+ expect({}).toBeInstanceOf(Object);
+ expect(new String("test")).toBeInstanceOf(String);
+ expect(() => {}).toBeInstanceOf(Function);
+ class A {}
+ expect(new A()).toBeInstanceOf(A);
+ });
+}); \ No newline at end of file