diff options
author | 2023-05-11 06:57:30 +0000 | |
---|---|---|
committer | 2023-05-10 23:57:30 -0700 | |
commit | 4b79b37a994815fb57508f3f401b5bb2469fc525 (patch) | |
tree | 93cb9d895c180152312687bb969e92bd162476bc | |
parent | f9831e1f6f9cbc29559baa15ae87a229cb91d798 (diff) | |
download | bun-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.ts | 1 | ||||
-rw-r--r-- | src/bun.js/test/jest.zig | 32 | ||||
-rw-r--r-- | test/js/bun/test/test-test.test.ts | 148 |
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"); + }); + }); +}); |