aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.cpp62
-rw-r--r--src/bun.js/bindings/generated_classes.zig6
-rw-r--r--src/bun.js/test/expect.zig102
-rw-r--r--src/bun.js/test/jest.classes.ts8
4 files changed, 178 insertions, 0 deletions
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp
index 245010158..25aca16c4 100644
--- a/src/bun.js/bindings/ZigGeneratedClasses.cpp
+++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp
@@ -2693,9 +2693,15 @@ JSC_DECLARE_CUSTOM_GETTER(jsExpectConstructor);
extern "C" void ExpectClass__finalize(void*);
extern "C" JSC_DECLARE_HOST_FUNCTION(ExpectClass__call);
+extern "C" EncodedJSValue ExpectPrototype__fail(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__failCallback);
+
extern "C" JSC::EncodedJSValue ExpectPrototype__getNot(void* ptr, JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(ExpectPrototype__notGetterWrap);
+extern "C" EncodedJSValue ExpectPrototype___pass(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame);
+JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__passCallback);
+
extern "C" JSC::EncodedJSValue ExpectPrototype__getRejects(void* ptr, JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* lexicalGlobalObject);
JSC_DECLARE_CUSTOM_GETTER(ExpectPrototype__rejectsGetterWrap);
@@ -2879,7 +2885,9 @@ JSC_DECLARE_HOST_FUNCTION(ExpectPrototype__toThrowErrorMatchingSnapshotCallback)
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSExpectPrototype, JSExpectPrototype::Base);
static const HashTableValue JSExpectPrototypeTableValues[] = {
+ { "fail"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__failCallback, 1 } },
{ "not"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, ExpectPrototype__notGetterWrap, 0 } },
+ { "pass"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__passCallback, 1 } },
{ "rejects"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, ExpectPrototype__rejectsGetterWrap, 0 } },
{ "resolves"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, ExpectPrototype__resolvesGetterWrap, 0 } },
{ "toBe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ExpectPrototype__toBeCallback, 1 } },
@@ -2956,6 +2964,33 @@ JSC_DEFINE_CUSTOM_GETTER(jsExpectConstructor, (JSGlobalObject * lexicalGlobalObj
return JSValue::encode(globalObject->JSExpectConstructor());
}
+JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__failCallback, (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);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return ExpectPrototype__fail(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_CUSTOM_GETTER(ExpectPrototype__notGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
@@ -2968,6 +3003,33 @@ JSC_DEFINE_CUSTOM_GETTER(ExpectPrototype__notGetterWrap, (JSGlobalObject * lexic
RELEASE_AND_RETURN(throwScope, result);
}
+JSC_DEFINE_HOST_FUNCTION(ExpectPrototype__passCallback, (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);
+
+#ifdef BUN_DEBUG
+ /** View the file name of the JS file that called this function
+ * from a debugger */
+ SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm);
+ const char* fileName = sourceOrigin.string().utf8().data();
+ static const char* lastFileName = nullptr;
+ if (lastFileName != fileName) {
+ lastFileName = fileName;
+ }
+#endif
+
+ return ExpectPrototype___pass(thisObject->wrapped(), lexicalGlobalObject, callFrame);
+}
+
JSC_DEFINE_CUSTOM_GETTER(ExpectPrototype__rejectsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
auto& vm = lexicalGlobalObject->vm();
diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig
index 947be7a51..e8cc701a3 100644
--- a/src/bun.js/bindings/generated_classes.zig
+++ b/src/bun.js/bindings/generated_classes.zig
@@ -883,8 +883,12 @@ pub const JSExpect = struct {
@compileLog("Expect.finalize is not a finalizer");
}
+ if (@TypeOf(Expect.fail) != CallbackType)
+ @compileLog("Expected Expect.fail to be a callback but received " ++ @typeName(@TypeOf(Expect.fail)));
if (@TypeOf(Expect.getNot) != GetterTypeWithThisValue)
@compileLog("Expected Expect.getNot to be a getter with thisValue");
+ if (@TypeOf(Expect._pass) != CallbackType)
+ @compileLog("Expected Expect._pass to be a callback but received " ++ @typeName(@TypeOf(Expect._pass)));
if (@TypeOf(Expect.getRejects) != GetterTypeWithThisValue)
@compileLog("Expected Expect.getRejects to be a getter with thisValue");
if (@TypeOf(Expect.getResolves) != GetterTypeWithThisValue)
@@ -1037,6 +1041,7 @@ pub const JSExpect = struct {
if (@TypeOf(Expect.call) != StaticCallbackType)
@compileLog("Expected Expect.call to be a static callback");
if (!JSC.is_bindgen) {
+ @export(Expect._pass, .{ .name = "ExpectPrototype___pass" });
@export(Expect.addSnapshotSerializer, .{ .name = "ExpectClass__addSnapshotSerializer" });
@export(Expect.any, .{ .name = "ExpectClass__any" });
@export(Expect.anything, .{ .name = "ExpectClass__anything" });
@@ -1045,6 +1050,7 @@ pub const JSExpect = struct {
@export(Expect.call, .{ .name = "ExpectClass__call" });
@export(Expect.constructor, .{ .name = "ExpectClass__construct" });
@export(Expect.extend, .{ .name = "ExpectClass__extend" });
+ @export(Expect.fail, .{ .name = "ExpectPrototype__fail" });
@export(Expect.finalize, .{ .name = "ExpectClass__finalize" });
@export(Expect.getNot, .{ .name = "ExpectPrototype__getNot" });
@export(Expect.getRejects, .{ .name = "ExpectPrototype__getRejects" });
diff --git a/src/bun.js/test/expect.zig b/src/bun.js/test/expect.zig
index d6f8ebb12..07fbca03c 100644
--- a/src/bun.js/test/expect.zig
+++ b/src/bun.js/test/expect.zig
@@ -289,6 +289,108 @@ pub const Expect = struct {
return null;
}
+ // pass here has a leading underscore to avoid name collision with the pass variable in other functions
+ pub fn _pass(
+ this: *Expect,
+ globalObject: *JSC.JSGlobalObject,
+ callFrame: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ defer this.postMatch(globalObject);
+
+ const thisValue = callFrame.this();
+ const arguments_ = callFrame.arguments(1);
+ const arguments = arguments_.ptr[0..arguments_.len];
+
+ var _msg: ZigString = ZigString.Empty;
+
+ if (arguments.len > 0) {
+ const value = arguments[0];
+ value.ensureStillAlive();
+
+ if (!value.isString()) {
+ globalObject.throwInvalidArgumentType("pass", "message", "string");
+ return .zero;
+ }
+
+ value.toZigString(&_msg, globalObject);
+ } else {
+ _msg = ZigString.fromBytes("passes by .pass() assertion");
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const not = this.flags.not;
+ var pass = true;
+
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ var msg = _msg.toSlice(default_allocator);
+ defer msg.deinit();
+
+ if (not) {
+ const signature = comptime getSignature("pass", "", true);
+ const fmt = signature ++ "\n\n{s}\n";
+ if (Output.enable_ansi_colors) {
+ globalObject.throw(Output.prettyFmt(fmt, true), .{msg.slice()});
+ return .zero;
+ }
+ globalObject.throw(Output.prettyFmt(fmt, false), .{msg.slice()});
+ return .zero;
+ }
+
+ // should never reach here
+ return .zero;
+ }
+
+ pub fn fail(
+ this: *Expect,
+ globalObject: *JSC.JSGlobalObject,
+ callFrame: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ defer this.postMatch(globalObject);
+
+ const thisValue = callFrame.this();
+ const arguments_ = callFrame.arguments(1);
+ const arguments = arguments_.ptr[0..arguments_.len];
+
+ var _msg: ZigString = ZigString.Empty;
+
+ if (arguments.len > 0) {
+ const value = arguments[0];
+ value.ensureStillAlive();
+
+ if (!value.isString()) {
+ globalObject.throwInvalidArgumentType("fail", "message", "string");
+ return .zero;
+ }
+
+ value.toZigString(&_msg, globalObject);
+ } else {
+ _msg = ZigString.fromBytes("fails by .fail() assertion");
+ }
+
+ active_test_expectation_counter.actual += 1;
+
+ const not = this.flags.not;
+ var pass = false;
+
+ if (not) pass = !pass;
+ if (pass) return thisValue;
+
+ var msg = _msg.toSlice(default_allocator);
+ defer msg.deinit();
+
+ const signature = comptime getSignature("fail", "", true);
+ const fmt = signature ++ "\n\n{s}\n";
+ if (Output.enable_ansi_colors) {
+ globalObject.throw(Output.prettyFmt(fmt, true), .{msg.slice()});
+ return .zero;
+ }
+ globalObject.throw(Output.prettyFmt(fmt, false), .{msg.slice()});
+ return .zero;
+ }
+
/// Object.is()
pub fn toBe(
this: *Expect,
diff --git a/src/bun.js/test/jest.classes.ts b/src/bun.js/test/jest.classes.ts
index e5bf567a9..c337ab4ec 100644
--- a/src/bun.js/test/jest.classes.ts
+++ b/src/bun.js/test/jest.classes.ts
@@ -108,6 +108,14 @@ export default [
},
},
proto: {
+ pass: {
+ fn: "_pass",
+ length: 1,
+ },
+ fail: {
+ fn: "fail",
+ length: 1,
+ },
toBe: {
fn: "toBe",
length: 1,