diff options
author | 2023-05-01 02:36:08 -0400 | |
---|---|---|
committer | 2023-04-30 23:36:08 -0700 | |
commit | 59b3556faba7e8dd1b0271c4815238fe9ea3f496 (patch) | |
tree | a8150b01c5887372c2e412be3b225dacbabf6710 /src/bun.js/test | |
parent | 8b53b3ed88d2233ce05802da7548f689f93fb06a (diff) | |
download | bun-59b3556faba7e8dd1b0271c4815238fe9ea3f496.tar.gz bun-59b3556faba7e8dd1b0271c4815238fe9ea3f496.tar.zst bun-59b3556faba7e8dd1b0271c4815238fe9ea3f496.zip |
Bun Test matchers even/odd. Also, .toContains fix and truthy (#2754)
* bun test matcher tests for even/odd, few more truthy tests, and fix for contains empty string
* implementation of even/odd matchers
* didn't add the codegen bindings
* linted
Diffstat (limited to 'src/bun.js/test')
-rw-r--r-- | src/bun.js/test/jest.classes.ts | 8 | ||||
-rw-r--r-- | src/bun.js/test/jest.zig | 146 |
2 files changed, 154 insertions, 0 deletions
diff --git a/src/bun.js/test/jest.classes.ts b/src/bun.js/test/jest.classes.ts index 9182c8cc6..612fc0268 100644 --- a/src/bun.js/test/jest.classes.ts +++ b/src/bun.js/test/jest.classes.ts @@ -121,6 +121,10 @@ export default [ fn: "toBeCloseTo", length: 1, }, + toBeEven: { + fn: "toBeEven", + length: 0, + }, toBeGreaterThan: { fn: "toBeGreaterThan", length: 1, @@ -137,6 +141,10 @@ export default [ fn: "toBeLessThanOrEqual", length: 1, }, + toBeOdd: { + fn: "toBeOdd", + length: 0, + }, toBeInstanceOf: { fn: "toBeInstanceOf", length: 1, diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index 04ae36aa9..e83bc1271 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -1206,6 +1206,8 @@ pub const Expect = struct { const expected_string = expected.toString(globalObject).toSlice(globalObject, default_allocator).slice(); if (strings.contains(value_string, expected_string)) { pass = true; + } else if (value_string.len == 0 and expected_string.len == 0) { // edge case two empty strings are true + pass = true; } } else { globalObject.throw("Received value must be an array type, or both received and expected values must be strings.", .{}); @@ -1769,6 +1771,79 @@ pub const Expect = struct { return .zero; } + pub fn toBeEven(this: *Expect, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + defer this.postMatch(globalObject); + + const thisValue = callFrame.this(); + + const value: JSValue = 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(); + + if (this.scope.tests.items.len <= this.test_id) { + globalObject.throw("toBeEven() must be called in a test", .{}); + return .zero; + } + + active_test_expectation_counter.actual += 1; + + const not = this.op.contains(.not); + var pass = false; + + if (value.isAnyInt()) { + const _value = value.toInt64(); + pass = @mod(_value, 2) == 0; + if (_value == -0) { // negative zero is even + pass = true; + } + } else if (value.isBigInt() or value.isBigInt32()) { + const _value = value.toInt64(); + pass = switch (_value == -0) { // negative zero is even + true => true, + else => _value & 1 == 0, + }; + } else if (value.isNumber()) { + const _value = JSValue.asNumber(value); + if (@mod(_value, 1) == 0 and @mod(_value, 2) == 0) { // if the fraction is all zeros and even + pass = true; + } else { + pass = false; + } + } else { + pass = false; + } + + 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("toBeEven", "", 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("toBeEven", "", 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 fn toBeGreaterThan(this: *Expect, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue { defer this.postMatch(globalObject); @@ -2092,6 +2167,77 @@ pub const Expect = struct { return .zero; } + pub fn toBeOdd(this: *Expect, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + defer this.postMatch(globalObject); + + const thisValue = callFrame.this(); + + const value: JSValue = 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(); + + if (this.scope.tests.items.len <= this.test_id) { + globalObject.throw("toBeOdd() must be called in a test", .{}); + return .zero; + } + + active_test_expectation_counter.actual += 1; + + const not = this.op.contains(.not); + var pass = false; + + if (value.isBigInt32()) { + pass = value.toInt32() & 1 == 1; + } else if (value.isBigInt()) { + pass = value.toInt64() & 1 == 1; + } else if (value.isInt32()) { + const _value = value.toInt32(); + pass = @mod(_value, 2) == 1; + } else if (value.isAnyInt()) { + const _value = value.toInt64(); + pass = @mod(_value, 2) == 1; + } else if (value.isNumber()) { + const _value = JSValue.asNumber(value); + if (@mod(_value, 1) == 0 and @mod(_value, 2) == 1) { // if the fraction is all zeros and odd + pass = true; + } else { + pass = false; + } + } else { + pass = false; + } + + 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("toBeOdd", "", 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("toBeOdd", "", 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 fn toThrow(this: *Expect, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSValue { defer this.postMatch(globalObject); |