aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Degreat <mail@degreat.co.uk> 2023-05-11 06:57:30 +0000
committerGravatar GitHub <noreply@github.com> 2023-05-10 23:57:30 -0700
commit4b79b37a994815fb57508f3f401b5bb2469fc525 (patch)
tree93cb9d895c180152312687bb969e92bd162476bc
parentf9831e1f6f9cbc29559baa15ae87a229cb91d798 (diff)
downloadbun-4b79b37a994815fb57508f3f401b5bb2469fc525.tar.gz
bun-4b79b37a994815fb57508f3f401b5bb2469fc525.tar.zst
bun-4b79b37a994815fb57508f3f401b5bb2469fc525.zip
Implement `describe.skip` (#2836)
* Implement describe.skip * Add more tests to cover hooks
-rw-r--r--packages/bun-types/bun-test.d.ts1
-rw-r--r--src/bun.js/test/jest.zig32
-rw-r--r--test/js/bun/test/test-test.test.ts148
3 files changed, 177 insertions, 4 deletions
diff --git a/packages/bun-types/bun-test.d.ts b/packages/bun-types/bun-test.d.ts
index 181d4c79d..d9bf36124 100644
--- a/packages/bun-types/bun-test.d.ts
+++ b/packages/bun-types/bun-test.d.ts
@@ -33,6 +33,7 @@ declare module "bun:test" {
*/
export type Describe = {
(label: string, fn: () => void): void;
+ skip: (label: string, fn: () => void) => void
};
/**
* Describes a group of related tests.
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index e83bc1271..9bfc95811 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -3306,10 +3306,11 @@ pub const DescribeScope = struct {
current_test_id: TestRunner.Test.ID = 0,
value: JSValue = .zero,
done: bool = false,
+ skipped: bool = false,
skipped_counter: u32 = 0,
pub fn isAllSkipped(this: *const DescribeScope) bool {
- return @as(usize, this.skipped_counter) >= this.tests.items.len;
+ return this.skipped or @as(usize, this.skipped_counter) >= this.tests.items.len;
}
pub fn push(new: *DescribeScope) void {
@@ -3388,6 +3389,7 @@ pub const DescribeScope = struct {
.afterEach = .{ .rfn = createCallback(.afterEach), .name = "afterEach" },
.beforeAll = .{ .rfn = createCallback(.beforeAll), .name = "beforeAll" },
.beforeEach = .{ .rfn = createCallback(.beforeEach), .name = "beforeEach" },
+ .skip = skip,
},
.{
.expect = .{ .get = createExpect, .name = "expect" },
@@ -3484,6 +3486,17 @@ pub const DescribeScope = struct {
return this.execCallback(ctx, hook);
}
+ pub fn skip(
+ this: *DescribeScope,
+ ctx: js.JSContextRef,
+ _: js.JSObjectRef,
+ _: js.JSObjectRef,
+ arguments: []const js.JSValueRef,
+ exception: js.ExceptionRef,
+ ) js.JSObjectRef {
+ return this.runDescribe(ctx, null, null, arguments, exception, true);
+ }
+
pub fn describe(
this: *DescribeScope,
ctx: js.JSContextRef,
@@ -3492,6 +3505,18 @@ pub const DescribeScope = struct {
arguments: []const js.JSValueRef,
exception: js.ExceptionRef,
) js.JSObjectRef {
+ return runDescribe(this, ctx, null, null, arguments, exception, false);
+ }
+
+ fn runDescribe(
+ this: *DescribeScope,
+ ctx: js.JSContextRef,
+ _: js.JSObjectRef,
+ _: js.JSObjectRef,
+ arguments: []const js.JSValueRef,
+ exception: js.ExceptionRef,
+ skipped: bool,
+ ) js.JSObjectRef {
if (arguments.len == 0 or arguments.len > 2) {
JSError(getAllocator(ctx), "describe() requires 1-2 arguments", .{}, ctx, exception);
return js.JSValueMakeUndefined(ctx);
@@ -3518,6 +3543,7 @@ pub const DescribeScope = struct {
.label = (label.toSlice(allocator).cloneIfNeeded(allocator) catch unreachable).slice(),
.parent = active,
.file_id = this.file_id,
+ .skipped = skipped or active.skipped,
};
var new_this = DescribeScope.Class.make(ctx, scope);
@@ -3609,7 +3635,7 @@ pub const DescribeScope = struct {
this.pending_tests.unset(test_id);
if (!skipped) {
- const afterEach = this.execCallback(globalThis, .afterEach);
+ const afterEach = this.runCallback(globalThis, .afterEach);
if (!afterEach.isEmpty()) {
globalThis.bunVM().runErrorHandler(afterEach, null);
}
@@ -3753,7 +3779,7 @@ pub const TestRunnerTask = struct {
var test_: TestScope = this.describe.tests.items[test_id];
describe.current_test_id = test_id;
var globalThis = this.globalThis;
- if (test_.skipped) {
+ if (test_.skipped or describe.skipped) {
this.processTestResult(globalThis, .{ .skip = {} }, test_, test_id, describe);
this.deinit();
return false;
diff --git a/test/js/bun/test/test-test.test.ts b/test/js/bun/test/test-test.test.ts
index 4ed097f97..c739a8921 100644
--- a/test/js/bun/test/test-test.test.ts
+++ b/test/js/bun/test/test-test.test.ts
@@ -13,7 +13,7 @@ it("shouldn't crash when async test runner callback throws", async () => {
await 1;
throw "##123##";
});
-
+
afterEach(async () => {
await 1;
console.error("#[Test passed successfully]");
@@ -2612,3 +2612,149 @@ it("should return non-zero exit code for invalid syntax", async () => {
await rm(test_dir, { force: true, recursive: true });
}
});
+
+describe("skip test inner", () => {
+ it("should pass", () => {
+ expect(2 + 2).toBe(4);
+ });
+
+ describe.skip("skip", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+
+ describe("skip non-skipped inner", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+ });
+});
+
+describe.skip("skip test outer", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+
+ describe("skip non-skipped inner", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+
+ describe("skip nested non-skipped inner", () => {
+ describe("skip", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+ });
+});
+
+describe("skip test inner 2", () => {
+ it("should pass", () => {
+ expect(2 + 2).toBe(4);
+ });
+
+ describe.skip("skip", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+});
+
+describe.skip("skip beforeEach", () => {
+ beforeEach(() => {
+ throw new Error("should not run `beforeEach`");
+ });
+
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+});
+
+describe("nested beforeEach and afterEach", () => {
+ let value = 0;
+
+ beforeEach(() => {
+ value += 1;
+ });
+
+ afterEach(() => {
+ value += 1;
+ });
+
+ describe("runs beforeEach", () => {
+ it("should update value", () => {
+ expect(value).toBe(1);
+ });
+ });
+
+ describe.skip("skips", () => {
+ it("should throw", async () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+
+ describe.skip("skips async", () => {
+ it("should throw", async () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+
+ describe("runs beforeEach again", () => {
+ it("should have value as 3", () => {
+ expect(value).toBe(3);
+ });
+ });
+});
+
+describe.skip("skip afterEach", () => {
+ afterEach(() => {
+ throw new Error("should not run `afterEach`");
+ });
+
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+});
+
+describe.skip("skip beforeAll", () => {
+ beforeAll(() => {
+ throw new Error("should not run `beforeAll`");
+ });
+
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+});
+
+describe.skip("skip afterAll", () => {
+ afterAll(() => {
+ throw new Error("should not run `afterAll`");
+ });
+
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+});
+
+// no labels
+
+describe.skip(() => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+});
+
+describe(() => {
+ it("should pass", () => {
+ expect(2 + 2).toBe(4);
+ });
+
+ describe.skip("skip", () => {
+ it("should throw", () => {
+ throw new Error("This should not throw. `.skip` is broken");
+ });
+ });
+});