aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/test/jest.zig
diff options
context:
space:
mode:
authorGravatar Tiramify (A.K. Daniel) <94789999+TiranexDev@users.noreply.github.com> 2023-06-20 07:39:44 +0200
committerGravatar GitHub <noreply@github.com> 2023-06-19 22:39:44 -0700
commite9e0e051569d3858cfc18b21a6aa6d1b7184f7e7 (patch)
tree3e31f68eb27b1b60c174c8970f11523d378ea43e /src/bun.js/test/jest.zig
parent7d94a49ef403750886c2e9ebfc5a7752b8ccb882 (diff)
downloadbun-e9e0e051569d3858cfc18b21a6aa6d1b7184f7e7.tar.gz
bun-e9e0e051569d3858cfc18b21a6aa6d1b7184f7e7.tar.zst
bun-e9e0e051569d3858cfc18b21a6aa6d1b7184f7e7.zip
feat(bun/test): Impl. "toBeArray", "toBeArrayOfSize" & "toBeTypeOf" (#3316)
* Implement toBeArray, toBeArrayOfSize, toBeTypeOf * fix typos/variable names * Add testcases for regex and dates * little fix * i didn't paste that...
Diffstat (limited to 'src/bun.js/test/jest.zig')
-rw-r--r--src/bun.js/test/jest.zig181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index 62be3fbae..ad60a9c5e 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -3006,6 +3006,94 @@ pub const Expect = struct {
return .zero;
}
+ pub fn toBeArray(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
+ defer this.postMatch(globalThis);
+
+ const thisValue = callFrame.this();
+ const value = Expect.capturedValueGetCached(thisValue) orelse {
+ globalThis.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{});
+ return .zero;
+ };
+ value.ensureStillAlive();
+
+ if (this.scope.tests.items.len <= this.test_id) {
+ globalThis.throw("toBeArray() must be called in a test", .{});
+ return .zero;
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const not = this.op.contains(.not);
+ const pass = value.jsType().isArray() != not;
+
+ if (pass) return thisValue;
+
+ var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalThis, .quote_strings = true };
+ const received = value.toFmt(globalThis, &formatter);
+
+ if (not) {
+ const fmt = comptime getSignature("toBeArray", "", true) ++ "\n\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{received});
+ return .zero;
+ }
+
+ const fmt = comptime getSignature("toBeArray", "", false) ++ "\n\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{received});
+ return .zero;
+ }
+
+ pub fn toBeArrayOfSize(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
+ defer this.postMatch(globalThis);
+
+ const thisValue = callFrame.this();
+ const _arguments = callFrame.arguments(1);
+ const arguments = _arguments.ptr[0.._arguments.len];
+
+ if (arguments.len < 1) {
+ globalThis.throwInvalidArguments("toBeArrayOfSize() requires 1 argument", .{});
+ return .zero;
+ }
+
+ const value = Expect.capturedValueGetCached(thisValue) orelse {
+ globalThis.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{});
+ return .zero;
+ };
+
+ if (this.scope.tests.items.len <= this.test_id) {
+ globalThis.throw("toBeArrayOfSize() must be called in a test", .{});
+ return .zero;
+ }
+
+ const size = arguments[0];
+ size.ensureStillAlive();
+
+ if (!size.isAnyInt()) {
+ globalThis.throw("toBeArrayOfSize() requires the first argument to be a number", .{});
+ return .zero;
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const not = this.op.contains(.not);
+ var pass = value.jsType().isArray() and @intCast(i32, value.getLength(globalThis)) == size.toInt32();
+
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalThis, .quote_strings = true };
+ const received = value.toFmt(globalThis, &formatter);
+
+ if (not) {
+ const fmt = comptime getSignature("toBeArrayOfSize", "", true) ++ "\n\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{received});
+ return .zero;
+ }
+
+ const fmt = comptime getSignature("toBeArrayOfSize", "", false) ++ "\n\n" ++ "Received: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{received});
+ return .zero;
+ }
+
pub fn toBeBoolean(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
defer this.postMatch(globalThis);
@@ -3312,6 +3400,99 @@ pub const Expect = struct {
return .zero;
}
+ pub fn toBeTypeOf(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
+ defer this.postMatch(globalThis);
+
+ const thisValue = callFrame.this();
+ const _arguments = callFrame.arguments(1);
+ const arguments = _arguments.ptr[0.._arguments.len];
+
+ if (arguments.len < 1) {
+ globalThis.throwInvalidArguments("toBeTypeOf() requires 1 argument", .{});
+ return .zero;
+ }
+
+ if (this.scope.tests.items.len <= this.test_id) {
+ globalThis.throw("toBeTypeOf() must be called in a test", .{});
+ return .zero;
+ }
+
+ const value = Expect.capturedValueGetCached(thisValue) orelse {
+ globalThis.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{});
+ return .zero;
+ };
+ value.ensureStillAlive();
+
+ const expected = arguments[0];
+ expected.ensureStillAlive();
+
+ const expectedAsStr = expected.toString(globalThis).toSlice(globalThis, default_allocator).slice();
+ active_test_expectation_counter.actual += 1;
+
+ if (!expected.isString()) {
+ globalThis.throwInvalidArguments("toBeTypeOf() requires a string argument", .{});
+ return .zero;
+ }
+
+ if (!std.mem.eql(u8, expectedAsStr, "function") and
+ !std.mem.eql(u8, expectedAsStr, "object") and
+ !std.mem.eql(u8, expectedAsStr, "bigint") and
+ !std.mem.eql(u8, expectedAsStr, "boolean") and
+ !std.mem.eql(u8, expectedAsStr, "number") and
+ !std.mem.eql(u8, expectedAsStr, "string") and
+ !std.mem.eql(u8, expectedAsStr, "symbol") and
+ !std.mem.eql(u8, expectedAsStr, "undefined"))
+ {
+ globalThis.throwInvalidArguments("toBeTypeOf() requires a valid type string argument ('function', 'object', 'bigint', 'boolean', 'number', 'string', 'symbol', 'undefined')", .{});
+ return .zero;
+ }
+
+ const not = this.op.contains(.not);
+ var pass = false;
+ var whatIsTheType: []const u8 = "";
+
+ // Checking for function/class should be done before everything else, or it will fail.
+ if (value.isCallable(globalThis.vm())) {
+ whatIsTheType = "function";
+ } else if (value.isObject() or value.jsType().isArray() or value.isNull()) {
+ whatIsTheType = "object";
+ } else if (value.isBigInt()) {
+ whatIsTheType = "bigint";
+ } else if (value.isBoolean()) {
+ whatIsTheType = "boolean";
+ } else if (value.isNumber()) {
+ whatIsTheType = "number";
+ } else if (value.jsType().isString()) {
+ whatIsTheType = "string";
+ } else if (value.isSymbol()) {
+ whatIsTheType = "symbol";
+ } else if (value.isUndefined()) {
+ whatIsTheType = "undefined";
+ } else {
+ globalThis.throw("Internal consistency error: unknown JSValue type", .{});
+ return .zero;
+ }
+
+ pass = std.mem.eql(u8, expectedAsStr, whatIsTheType);
+
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ var formatter = JSC.ZigConsoleClient.Formatter{ .globalThis = globalThis, .quote_strings = true };
+ const received = value.toFmt(globalThis, &formatter);
+ const expected_str = expected.toFmt(globalThis, &formatter);
+
+ if (not) {
+ const fmt = comptime getSignature("toBeTypeOf", "", true) ++ "\n\n" ++ "Expected type: not <green>{any}<r>\n" ++ "Received type: <red>\"{s}\"<r>\nReceived value: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{ expected_str, whatIsTheType, received });
+ return .zero;
+ }
+
+ const fmt = comptime getSignature("toBeTypeOf", "", false) ++ "\n\n" ++ "Expected type: <green>{any}<r>\n" ++ "Received type: <red>\"{s}\"<r>\nReceived value: <red>{any}<r>\n";
+ globalThis.throwPretty(fmt, .{ expected_str, whatIsTheType, received });
+ return .zero;
+ }
+
pub fn toBeWithin(this: *Expect, globalThis: *JSGlobalObject, callFrame: *CallFrame) callconv(.C) JSValue {
defer this.postMatch(globalThis);