From 689666f17c5165e4034ee660d6dfb3ae0a8eddcb Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Mon, 20 Jun 2022 21:31:08 -0700 Subject: [bun wiptest] Implement `beforeEach`, `afterEach`, `beforeAll`, `afterAll` --- src/javascript/jsc/test/jest.zig | 130 +++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 19 deletions(-) (limited to 'src/javascript') diff --git a/src/javascript/jsc/test/jest.zig b/src/javascript/jsc/test/jest.zig index 8eefa8de8..52bed96db 100644 --- a/src/javascript/jsc/test/jest.zig +++ b/src/javascript/jsc/test/jest.zig @@ -635,12 +635,7 @@ pub const TestScope = struct { } if (js.JSValueIsString(ctx, args[0])) { - var label_ = ZigString.init(""); - JSC.JSValue.fromRef(arguments[0]).toZigString(&label_, ctx.ptr()); - label = if (label_.is16Bit()) - (strings.toUTF8AllocWithType(getAllocator(ctx), @TypeOf(label_.utf16Slice()), label_.utf16Slice()) catch unreachable) - else - label_.full(); + label = (JSC.JSValue.fromRef(arguments[0]).toSlice(ctx, getAllocator(ctx)).cloneIfNeeded() catch unreachable).slice(); args = args[1..]; } @@ -732,16 +727,23 @@ pub const TestScope = struct { pub const DescribeScope = struct { label: string = "", parent: ?*DescribeScope = null, - beforeAll: std.ArrayListUnmanaged(js.JSValueRef) = .{}, - beforeEach: std.ArrayListUnmanaged(js.JSValueRef) = .{}, - afterEach: std.ArrayListUnmanaged(js.JSValueRef) = .{}, - afterAll: std.ArrayListUnmanaged(js.JSValueRef) = .{}, + beforeAll: std.ArrayListUnmanaged(JSC.JSValue) = .{}, + beforeEach: std.ArrayListUnmanaged(JSC.JSValue) = .{}, + afterEach: std.ArrayListUnmanaged(JSC.JSValue) = .{}, + afterAll: std.ArrayListUnmanaged(JSC.JSValue) = .{}, test_id_start: TestRunner.Test.ID = 0, test_id_len: TestRunner.Test.ID = 0, tests: std.ArrayListUnmanaged(TestScope) = .{}, file_id: TestRunner.File.ID, current_test_id: TestRunner.Test.ID = 0, + pub const LifecycleHook = enum { + beforeAll, + beforeEach, + afterEach, + afterAll, + }; + pub const TestEntry = struct { label: string, callback: js.JSValueRef, @@ -751,6 +753,38 @@ pub const DescribeScope = struct { pub threadlocal var active: *DescribeScope = undefined; + const CallbackFn = fn ( + this: *DescribeScope, + ctx: js.JSContextRef, + _: js.JSObjectRef, + _: js.JSObjectRef, + arguments: []const js.JSValueRef, + exception: js.ExceptionRef, + ) js.JSObjectRef; + fn createCallback(comptime hook: LifecycleHook) CallbackFn { + return struct { + const this_hook = hook; + pub fn run( + this: *DescribeScope, + ctx: js.JSContextRef, + _: js.JSObjectRef, + _: js.JSObjectRef, + arguments: []const js.JSValueRef, + exception: js.ExceptionRef, + ) js.JSObjectRef { + if (arguments.len == 0 or !JSC.JSValue.c(arguments[0]).isObject() or !JSC.JSValue.c(arguments[0]).isCallable(ctx.vm())) { + JSC.throwInvalidArguments("Expected callback", .{}, ctx, exception); + return null; + } + + JSC.JSValue.c(arguments[0]).protect(); + const name = comptime std.mem.span(@tagName(this_hook)); + @field(this, name).append(getAllocator(ctx), JSC.JSValue.c(arguments[0])) catch unreachable; + return JSC.JSValue.jsBoolean(true).asObjectRef(); + } + }.run; + } + pub const Class = NewClass( DescribeScope, .{ @@ -759,9 +793,10 @@ pub const DescribeScope = struct { }, .{ .call = describe, - .afterAll = .{ .rfn = callAfterAll, .name = "afterAll" }, - .beforeAll = .{ .rfn = callAfterAll, .name = "beforeAll" }, - .beforeEach = .{ .rfn = callAfterAll, .name = "beforeEach" }, + .afterAll = .{ .rfn = createCallback(.afterAll), .name = "afterAll" }, + .afterEach = .{ .rfn = createCallback(.afterEach), .name = "afterEach" }, + .beforeAll = .{ .rfn = createCallback(.beforeAll), .name = "beforeAll" }, + .beforeEach = .{ .rfn = createCallback(.beforeEach), .name = "beforeEach" }, }, .{ .expect = .{ .get = createExpect, .name = "expect" }, @@ -773,6 +808,37 @@ pub const DescribeScope = struct { }, ); + pub fn execCallback(this: *DescribeScope, ctx: js.JSContextRef, comptime hook: LifecycleHook) JSValue { + const name = comptime std.mem.span(@tagName(hook)); + var hooks: []JSC.JSValue = @field(this, name).items; + for (hooks) |cb, i| { + if (cb.isEmpty()) continue; + + const err = cb.call(ctx, &.{}); + if (err.isAnyError(ctx)) { + return err; + } + + if (comptime hook == .beforeAll or hook == .afterAll) { + hooks[i] = JSC.JSValue.zero; + } + } + + return JSValue.zero; + } + pub fn runCallback(this: *DescribeScope, ctx: js.JSContextRef, comptime hook: LifecycleHook) JSValue { + var parent = this.parent; + while (parent) |scope| { + const ret = scope.execCallback(ctx, hook); + if (!ret.isEmpty()) { + return ret; + } + parent = scope.parent; + } + + return this.execCallback(ctx, hook); + } + pub fn describe( this: *DescribeScope, ctx: js.JSContextRef, @@ -852,7 +918,7 @@ pub const DescribeScope = struct { // Step 1. Initialize the test block const file = this.file_id; - + const allocator = getAllocator(ctx); var tests: []TestScope = this.tests.items; const end = @truncate(TestRunner.Test.ID, tests.len); @@ -868,17 +934,34 @@ pub const DescribeScope = struct { var i: TestRunner.Test.ID = 0; + const beforeAll = this.runCallback(ctx, .beforeAll); + if (!beforeAll.isEmpty()) { + while (i < end) { + Jest.runner.?.reportFailure(i + this.test_id_start, source.path.text, tests[i].label, 0, this); + i += 1; + } + this.tests.deinit(allocator); + return; + } + while (i < end) { // the test array could resize in the middle of this loop this.current_test_id = i; var test_ = tests[i]; - const result = TestScope.run(&test_); - tests[i] = test_; - // invalidate it - this.current_test_id = std.math.maxInt(TestRunner.Test.ID); + const beforeEach = this.runCallback(ctx, .beforeEach); const test_id = i + this.test_id_start; + if (!beforeEach.isEmpty()) { + Jest.runner.?.reportFailure(test_id, source.path.text, tests[i].label, 0, this); + ctx.bunVM().defaultErrorHandler(beforeEach, null); + i += 1; + continue; + } + + const result = TestScope.run(&test_); + tests[i] = test_; + switch (result) { .pass => |count| Jest.runner.?.reportPass(test_id, source.path.text, tests[i].label, count, this), .fail => |count| Jest.runner.?.reportFailure(test_id, source.path.text, tests[i].label, count, this), @@ -887,7 +970,16 @@ pub const DescribeScope = struct { i += 1; } - this.tests.deinit(getAllocator(ctx)); + + // invalidate it + this.current_test_id = std.math.maxInt(TestRunner.Test.ID); + + const afterAll = this.execCallback(ctx, .afterAll); + if (!afterAll.isEmpty()) { + ctx.bunVM().defaultErrorHandler(afterAll, null); + } + + this.tests.deinit(allocator); } const ScopeStack = ObjectPool(std.ArrayListUnmanaged(*DescribeScope), null, true, 16); -- cgit v1.2.3 d/inquirer'>jarred/inquirer Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/JSDOMExceptionHandling.cpp (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2023-10-12TweaksGravatar Colin McDonnell 1-2/+2
2023-10-12Fix structGravatar Colin McDonnell 1-1/+1
2023-10-12Clean up, implement warn_on_unrecognized_flagGravatar Colin McDonnell 4-26/+40
2023-10-12WIPGravatar Colin McDonnell 4-77/+14
2023-10-12WIPGravatar Colin McDonnell 5-347/+353
2023-10-12WIPGravatar Colin McDonnell 5-209/+446
2023-10-12WIPGravatar Colin McDonnell 2-24/+106
2023-10-12Improve helptextGravatar Colin McDonnell 1-55/+83
2023-10-12WIPGravatar Colin McDonnell 3-49/+147
2023-10-12WIPGravatar Colin McDonnell 2-0/+19
2023-10-12fix install testGravatar Dylan Conway 2-6/+8
2023-10-12fix editing package json when adding github dependency (#6432)Gravatar Dylan Conway 5-14/+146
2023-10-12Update installation.mdGravatar Colin McDonnell 1-8/+14
2023-10-12Update installation.mdGravatar Colin McDonnell 1-3/+3
2023-10-12fix(install): re-evaluate overrides when removedbun-v1.0.6Gravatar dave caruso 3-3/+45
2023-10-12chore: add missing ending quote (#6436)Gravatar Luna 1-1/+1
2023-10-12feat(install): support npm overrides/yarn resolutions, one level deep only (#...Gravatar dave caruso 7-31/+640
2023-10-11fix #6416 (#6430)Gravatar Dylan Conway 2-1/+132
2023-10-11Bump WebKitGravatar Jarred Sumner 9-29/+29
2023-10-11Bump!Gravatar Jarred Sumner 1-1/+1
2023-10-11Update JSCUSocketsLoopIntegration.cppGravatar Dylan Conway 1-2/+2
2023-10-11Update installation.mdGravatar Colin McDonnell 1-10/+7