diff options
author | 2023-05-01 02:36:08 -0400 | |
---|---|---|
committer | 2023-04-30 23:36:08 -0700 | |
commit | 59b3556faba7e8dd1b0271c4815238fe9ea3f496 (patch) | |
tree | a8150b01c5887372c2e412be3b225dacbabf6710 | |
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
-rw-r--r-- | src/bun.js/bindings/JSSink.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/JSSink.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/JSSinkLookupTable.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.cpp | 40 | ||||
-rw-r--r-- | src/bun.js/bindings/generated_classes.zig | 6 | ||||
-rw-r--r-- | src/bun.js/test/jest.classes.ts | 8 | ||||
-rw-r--r-- | src/bun.js/test/jest.zig | 146 | ||||
-rw-r--r-- | test/js/bun/test/test-test.test.ts | 159 |
8 files changed, 362 insertions, 3 deletions
diff --git a/src/bun.js/bindings/JSSink.cpp b/src/bun.js/bindings/JSSink.cpp index 050d35a88..31e648b8a 100644 --- a/src/bun.js/bindings/JSSink.cpp +++ b/src/bun.js/bindings/JSSink.cpp @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-04-27T13:34:38.170Z +// Generated by 'make generate-sink' at 2023-04-27T21:24:10.276Z // To regenerate this file, run: // // make generate-sink diff --git a/src/bun.js/bindings/JSSink.h b/src/bun.js/bindings/JSSink.h index dac35555b..29c5b2a09 100644 --- a/src/bun.js/bindings/JSSink.h +++ b/src/bun.js/bindings/JSSink.h @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-04-27T13:34:38.168Z +// Generated by 'make generate-sink' at 2023-04-27T21:24:10.274Z // #pragma once diff --git a/src/bun.js/bindings/JSSinkLookupTable.h b/src/bun.js/bindings/JSSinkLookupTable.h index dd86521c3..2f92be340 100644 --- a/src/bun.js/bindings/JSSinkLookupTable.h +++ b/src/bun.js/bindings/JSSinkLookupTable.h @@ -1,4 +1,4 @@ -// Automatically generated from src/bun.js/bindings/JSSink.cpp using /home/silver/code/bun/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! +// Automatically generated from src/bun.js/bindings/JSSink.cpp using /home/will/dev/bun-test-universe/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index 482ce8616..a167a4f0c 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -1394,6 +1394,9 @@ JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeCloseToCallback); extern "C" EncodedJSValue ExpectPrototype__toBeDefined(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeDefinedCallback); +extern "C" EncodedJSValue ExpectPrototype__toBeEven(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeEvenCallback); + extern "C" EncodedJSValue ExpectPrototype__toBeFalsy(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeFalsyCallback); @@ -1418,6 +1421,9 @@ JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeNaNCallback); extern "C" EncodedJSValue ExpectPrototype__toBeNull(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeNullCallback); +extern "C" EncodedJSValue ExpectPrototype__toBeOdd(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeOddCallback); + extern "C" EncodedJSValue ExpectPrototype__toBeTruthy(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toBeTruthyCallback); @@ -1496,6 +1502,7 @@ static const HashTableValue JSExpectPrototypeTableValues[] = { { "toBe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeCallback, 1 } }, { "toBeCloseTo"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeCloseToCallback, 1 } }, { "toBeDefined"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeDefinedCallback, 0 } }, + { "toBeEven"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeEvenCallback, 0 } }, { "toBeFalsy"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeFalsyCallback, 0 } }, { "toBeGreaterThan"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeGreaterThanCallback, 1 } }, { "toBeGreaterThanOrEqual"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeGreaterThanOrEqualCallback, 1 } }, @@ -1504,6 +1511,7 @@ static const HashTableValue JSExpectPrototypeTableValues[] = { { "toBeLessThanOrEqual"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeLessThanOrEqualCallback, 1 } }, { "toBeNaN"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeNaNCallback, 0 } }, { "toBeNull"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeNullCallback, 0 } }, + { "toBeOdd"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeOddCallback, 0 } }, { "toBeTruthy"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeTruthyCallback, 0 } }, { "toBeUndefined"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeUndefinedCallback, 0 } }, { "toContain"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toContainCallback, 1 } }, @@ -1627,6 +1635,22 @@ JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeDefinedCallback, (JSGlobalObject * return ExpectPrototype__toBeDefined(thisObject->wrapped(), lexicalGlobalObject, callFrame); } +JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeEvenCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSExpect* thisObject = jsDynamicCast<JSExpect*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + return ExpectPrototype__toBeEven(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeFalsyCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); @@ -1755,6 +1779,22 @@ JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeNullCallback, (JSGlobalObject * le return ExpectPrototype__toBeNull(thisObject->wrapped(), lexicalGlobalObject, callFrame); } +JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeOddCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSExpect* thisObject = jsDynamicCast<JSExpect*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + return ExpectPrototype__toBeOdd(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__toBeTruthyCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index c12e387fb..857fbfe3c 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -470,6 +470,8 @@ pub const JSExpect = struct { @compileLog("Expected Expect.toBeCloseTo to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeCloseTo))); if (@TypeOf(Expect.toBeDefined) != CallbackType) @compileLog("Expected Expect.toBeDefined to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeDefined))); + if (@TypeOf(Expect.toBeEven) != CallbackType) + @compileLog("Expected Expect.toBeEven to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeEven))); if (@TypeOf(Expect.toBeFalsy) != CallbackType) @compileLog("Expected Expect.toBeFalsy to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeFalsy))); if (@TypeOf(Expect.toBeGreaterThan) != CallbackType) @@ -486,6 +488,8 @@ pub const JSExpect = struct { @compileLog("Expected Expect.toBeNaN to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeNaN))); if (@TypeOf(Expect.toBeNull) != CallbackType) @compileLog("Expected Expect.toBeNull to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeNull))); + if (@TypeOf(Expect.toBeOdd) != CallbackType) + @compileLog("Expected Expect.toBeOdd to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeOdd))); if (@TypeOf(Expect.toBeTruthy) != CallbackType) @compileLog("Expected Expect.toBeTruthy to be a callback but received " ++ @typeName(@TypeOf(Expect.toBeTruthy))); if (@TypeOf(Expect.toBeUndefined) != CallbackType) @@ -586,6 +590,7 @@ pub const JSExpect = struct { @export(Expect.toBe, .{ .name = "ExpectPrototype__toBe" }); @export(Expect.toBeCloseTo, .{ .name = "ExpectPrototype__toBeCloseTo" }); @export(Expect.toBeDefined, .{ .name = "ExpectPrototype__toBeDefined" }); + @export(Expect.toBeEven, .{ .name = "ExpectPrototype__toBeEven" }); @export(Expect.toBeFalsy, .{ .name = "ExpectPrototype__toBeFalsy" }); @export(Expect.toBeGreaterThan, .{ .name = "ExpectPrototype__toBeGreaterThan" }); @export(Expect.toBeGreaterThanOrEqual, .{ .name = "ExpectPrototype__toBeGreaterThanOrEqual" }); @@ -594,6 +599,7 @@ pub const JSExpect = struct { @export(Expect.toBeLessThanOrEqual, .{ .name = "ExpectPrototype__toBeLessThanOrEqual" }); @export(Expect.toBeNaN, .{ .name = "ExpectPrototype__toBeNaN" }); @export(Expect.toBeNull, .{ .name = "ExpectPrototype__toBeNull" }); + @export(Expect.toBeOdd, .{ .name = "ExpectPrototype__toBeOdd" }); @export(Expect.toBeTruthy, .{ .name = "ExpectPrototype__toBeTruthy" }); @export(Expect.toBeUndefined, .{ .name = "ExpectPrototype__toBeUndefined" }); @export(Expect.toContain, .{ .name = "ExpectPrototype__toContain" }); 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); diff --git a/test/js/bun/test/test-test.test.ts b/test/js/bun/test/test-test.test.ts index 5154950de..4ed097f97 100644 --- a/test/js/bun/test/test-test.test.ts +++ b/test/js/bun/test/test-test.test.ts @@ -1796,6 +1796,84 @@ test("toContain()", () => { expect([]).not.toContain([]); }); +test("toBeEven()", () => { + expect(1).not.toBeEven(); + expect(2).toBeEven(); + expect(3).not.toBeEven(); + expect(3.1).not.toBeEven(); + expect(2.1).not.toBeEven(); + expect(4).toBeEven(); + expect(5).not.toBeEven(); + expect(6).toBeEven(); + expect(0).toBeEven(); + expect(-8).toBeEven(); + expect(-0).toBeEven(); + expect(NaN).not.toBeEven(); + expect([]).not.toBeEven(); + expect([1, 2]).not.toBeEven(); + expect({}).not.toBeEven(); + expect(() => {}).not.toBeEven(); + expect("").not.toBeEven(); + expect("string").not.toBeEven(); + expect(undefined).not.toBeEven(); + expect(Math.floor(Date.now() / 1000) * 2).toBeEven(); // Slight fuzz by using timestamp times 2 + expect(Math.floor(Date.now() / 1000) * 4 - 1).not.toBeEven(); + expect(4.0e1).toBeEven(); + expect(6.2e1).toBeEven(); + expect(6.3e1).not.toBeEven(); + expect(6.33e1).not.toBeEven(); + expect(3.3e-1).not.toBeEven(); //throw + expect(0.3).not.toBeEven(); //throw + expect(0.4).not.toBeEven(); + expect(1).not.toBeEven(); + expect(0).toBeEven(); + expect(2.0).toBeEven(); + expect(NaN).not.toBeEven(); + expect(2n).toBeEven(); // BigInt at this time not supported in jest-extended + expect(3n).not.toBeEven(); + expect(9007199254740990).toBeEven(); // manual typical max safe -1 // not int? + expect(9007199254740990n).toBeEven(); // manual typical max safe -1 as bigint + expect(Number.MAX_SAFE_INTEGER - 1).toBeEven(); // not int? + expect(Number.MAX_SAFE_INTEGER).not.toBeEven(); + expect(BigInt(Number.MAX_SAFE_INTEGER) - 1n).toBeEven(); + expect(BigInt(Number.MAX_SAFE_INTEGER)).not.toBeEven(); + expect(BigInt(Number.MAX_VALUE - 1)).toBeEven(); + expect(Number.MIN_SAFE_INTEGER + 1).toBeEven(); // not int? + expect(Number.MIN_SAFE_INTEGER).not.toBeEven(); + expect(BigInt(Number.MIN_SAFE_INTEGER) + 1n).toBeEven(); + expect(BigInt(Number.MIN_SAFE_INTEGER)).not.toBeEven(); + expect(4 / Number.NEGATIVE_INFINITY).toBeEven(); // as in IEEE-754: + / -inf => neg zero + expect(5 / Number.NEGATIVE_INFINITY).toBeEven(); + expect(-7 / Number.NEGATIVE_INFINITY).toBeEven(); // as in IEEE-754: - / -inf => zero + expect(-8 / Number.NEGATIVE_INFINITY).toBeEven(); + expect(new WebAssembly.Global({ value: "i32", mutable: false }, 4).value).toBeEven(); + expect(new WebAssembly.Global({ value: "i32", mutable: false }, 3).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "i32", mutable: true }, 2).value).toBeEven(); + expect(new WebAssembly.Global({ value: "i32", mutable: true }, 1).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "i64", mutable: true }, -9223372036854775808n).value).toBeEven(); + expect(new WebAssembly.Global({ value: "i64", mutable: false }, -9223372036854775808n).value).toBeEven(); + expect(new WebAssembly.Global({ value: "i64", mutable: true }, 9223372036854775807n).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "i64", mutable: false }, 9223372036854775807n).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 42.0).value).toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 42.0).value).toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 42.0).value).toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 42.0).value).toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 43.0).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 43.0).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 43.0).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 43.0).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 4.3).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 4.3).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 4.3).value).not.toBeEven(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 4.3).value).not.toBeEven(); + // did not seem to support SIMD v128 type yet (which is not in W3C specs for JS but is a valid global type) + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:false}, -170141183460469231731687303715884105728n).value).toBeEven(); + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:true}, -170141183460469231731687303715884105728n).value).toBeEven(); + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:true}, 170141183460469231731687303715884105727n).value).not.toBeEven(); + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:false}, 170141183460469231731687303715884105727n).value).not.toBeEven(); + // FUTURE: with uintv128: expect(new WebAssembly.Global({value:'v128', mutable:false}, 340282366920938463463374607431768211456n).value).toThrow(); +}); + test("toBeTruthy()", () => { expect("test").toBeTruthy(); expect(true).toBeTruthy(); @@ -1804,12 +1882,15 @@ test("toBeTruthy()", () => { expect([]).toBeTruthy(); expect(() => {}).toBeTruthy(); // expect(() => {}).not.toBeTruthy(); + expect(0.5).toBeTruthy(); + expect(new Map()).toBeTruthy(); expect("").not.toBeTruthy(); expect(0).not.toBeTruthy(); expect(-0).not.toBeTruthy(); expect(NaN).not.toBeTruthy(); expect(0n).not.toBeTruthy(); + expect(0.0e1).not.toBeTruthy(); expect(false).not.toBeTruthy(); expect(null).not.toBeTruthy(); expect(undefined).not.toBeTruthy(); @@ -2310,6 +2391,84 @@ test("toBeLessThanOrEqual()", () => { expect(1).toBeLessThanOrEqual(BigInt(Number.MAX_SAFE_INTEGER)); }); +test("toBeOdd()", () => { + expect(1).toBeOdd(); + expect(2).not.toBeOdd(); + expect(3).toBeOdd(); + expect(3.1).not.toBeOdd(); + expect(2.1).not.toBeOdd(); + expect(4).not.toBeOdd(); + expect(5).toBeOdd(); + expect(6).not.toBeOdd(); + expect(0).not.toBeOdd(); + expect(-8).not.toBeOdd(); + expect(-0).not.toBeOdd(); + expect(NaN).not.toBeOdd(); + expect([]).not.toBeOdd(); + // SHOULD FAIL: expect([]).toBeOdd(); + expect([1, 2]).not.toBeOdd(); + expect({}).not.toBeOdd(); + expect(() => {}).not.toBeOdd(); + expect("").not.toBeOdd(); + expect("string").not.toBeOdd(); + expect(undefined).not.toBeOdd(); + expect(Math.floor(Date.now() / 1000) * 2 - 1).toBeOdd(); // Slight fuzz by using timestamp times 2 + expect(Math.floor(Date.now() / 1000) * 4 - 1).toBeOdd(); + expect(4.0e1).not.toBeOdd(); + expect(6.2e1).not.toBeOdd(); + expect(6.3e1).toBeOdd(); + expect(6.33e1).not.toBeOdd(); + expect(3.2e-3).not.toBeOdd(); + expect(0.3).not.toBeOdd(); + expect(0.4).not.toBeOdd(); + expect(1).toBeOdd(); + expect(0).not.toBeOdd(); + expect(2.0).not.toBeOdd(); + expect(NaN).not.toBeOdd(); + expect(2n).not.toBeOdd(); // BigInt at this time not supported in jest-extended + expect(3n).toBeOdd(); + expect(9007199254740990).not.toBeOdd(); // manual typical max safe -1 + expect(9007199254740991).toBeOdd(); + expect(9007199254740990n).not.toBeOdd(); // manual typical max safe -1 as bigint + expect(9007199254740991n).toBeOdd(); + expect(Number.MAX_SAFE_INTEGER - 1).not.toBeOdd(); + expect(Number.MAX_SAFE_INTEGER).toBeOdd(); + expect(BigInt(Number.MAX_SAFE_INTEGER) - 1n).not.toBeOdd(); + expect(BigInt(Number.MAX_SAFE_INTEGER)).toBeOdd(); + expect(Number.MIN_SAFE_INTEGER + 1).not.toBeOdd(); + expect(Number.MIN_SAFE_INTEGER).toBeOdd(); + expect(BigInt(Number.MIN_SAFE_INTEGER) + 1n).not.toBeOdd(); + expect(BigInt(Number.MIN_SAFE_INTEGER)).toBeOdd(); + expect(4 / Number.NEGATIVE_INFINITY).not.toBeOdd(); // in IEEE-754: + / -inf => neg zero + expect(5 / Number.NEGATIVE_INFINITY).not.toBeOdd(); + expect(-7 / Number.NEGATIVE_INFINITY).not.toBeOdd(); // in IEEE-754: - / -inf => zero + expect(-8 / Number.NEGATIVE_INFINITY).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "i32", mutable: false }, 4).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "i32", mutable: false }, 3).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "i32", mutable: true }, 2).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "i32", mutable: true }, 1).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "i64", mutable: true }, -9223372036854775808n).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "i64", mutable: false }, -9223372036854775808n).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "i64", mutable: true }, 9223372036854775807n).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "i64", mutable: false }, 9223372036854775807n).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 42.0).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 42.0).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 42.0).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 42.0).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 43.0).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 43.0).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 43.0).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 43.0).value).toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: true }, 4.3).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f32", mutable: false }, 4.3).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: true }, 4.3).value).not.toBeOdd(); + expect(new WebAssembly.Global({ value: "f64", mutable: false }, 4.3).value).not.toBeOdd(); + // did not seem to support SIMD v128 type yet + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:false}, 42).value).not.toBeOdd(); + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:true}, 42).value).not.toBeOdd(); + // FUTURE: expect(new WebAssembly.Global({value:'v128', mutable:true}, 43).value).toBeOdd(); +}); + try { test("test this doesnt crash"); } catch (e) {} |