aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Alex Lam S.L <alexlamsl@gmail.com> 2022-12-31 13:14:23 +0200
committerGravatar GitHub <noreply@github.com> 2022-12-31 03:14:23 -0800
commit9b3db963081d5556a9fca41e5baa2670cc5cba49 (patch)
treeee2ed7c96e971ed456f7dad6dcb4abf6a7673fc8 /src
parentb86915c80819e61e6e1932d7802a4c31c73094e9 (diff)
downloadbun-9b3db963081d5556a9fca41e5baa2670cc5cba49.tar.gz
bun-9b3db963081d5556a9fca41e5baa2670cc5cba49.tar.zst
bun-9b3db963081d5556a9fca41e5baa2670cc5cba49.zip
[jest] fix and improve hooks (#1689)
- wait for async hooks to complete before running tests - add support for `done(err)` callbacks in hooks fixes #1688
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/test/jest.zig52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index 2a98d42f8..230c3a96e 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -1398,6 +1398,7 @@ pub const DescribeScope = struct {
file_id: TestRunner.File.ID,
current_test_id: TestRunner.Test.ID = 0,
value: JSValue = .zero,
+ done: bool = false,
pub fn push(new: *DescribeScope) void {
if (comptime is_bindgen) return undefined;
@@ -1486,16 +1487,61 @@ pub const DescribeScope = struct {
},
);
+ pub fn onDone(
+ ctx: js.JSContextRef,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSValue {
+ const function = callframe.callee();
+ const args = callframe.arguments(1);
+ defer ctx.bunVM().autoGarbageCollect();
+
+ if (JSC.getFunctionData(function)) |data| {
+ var scope = bun.cast(*DescribeScope, data);
+ JSC.setFunctionData(function, null);
+ if (args.len > 0) {
+ const err = args.ptr[0];
+ ctx.bunVM().runErrorHandlerWithDedupe(err, null);
+ }
+ scope.done = true;
+ }
+
+ return JSValue.jsUndefined();
+ }
+
pub fn execCallback(this: *DescribeScope, ctx: js.JSContextRef, comptime hook: LifecycleHook) JSValue {
const name = comptime @as(string, @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;
+ const pending_test = Jest.runner.?.pending_test;
+ // forbid `expect()` within hooks
+ Jest.runner.?.pending_test = null;
+ var result = if (cb.getLengthOfArray(ctx) > 0) brk: {
+ this.done = false;
+ const done_func = JSC.NewFunctionWithData(
+ ctx,
+ ZigString.static("done"),
+ 0,
+ DescribeScope.onDone,
+ false,
+ this,
+ );
+ var result = cb.call(ctx, &.{done_func});
+ var vm = VirtualMachine.get();
+ while (!this.done) {
+ vm.eventLoop().autoTick();
+ if (this.done) break;
+ vm.eventLoop().tick();
+ }
+ break :brk result;
+ } else cb.call(ctx, &.{});
+ if (result.asPromise()) |promise| {
+ VirtualMachine.get().waitForPromise(promise);
+ result = promise.result(ctx.vm());
}
+ Jest.runner.?.pending_test = pending_test;
+ if (result.isAnyError(ctx)) return result;
if (comptime hook == .beforeAll or hook == .afterAll) {
hooks[i] = JSC.JSValue.zero;