From 42d15ea8537d9773559da9bf8d17eaab9caa62f0 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 19 Feb 2024 10:36:08 -0800 Subject: [PATCH] Fixes #8964 (#8978) * Fixes #8964 * Fix test.each when used with test.only --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/bun.js/test/jest.zig | 52 +++++++++++++++++----------- test/regression/issue/08964.test.ts | 53 +++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 test/regression/issue/08964.test.ts diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index 747e50e22f..8f76f87245 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -1553,8 +1553,11 @@ inline fn createScope( else (description.toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch unreachable).slice(); - if (tag == .only) { + var tag_to_use = tag; + + if (tag_to_use == .only or parent.tag == .only) { Jest.runner.?.setOnly(); + tag_to_use = .only; } else if (is_test and Jest.runner.?.only and parent.tag != .only) { return .zero; } @@ -1563,7 +1566,6 @@ inline fn createScope( (tag == .todo and (function == .zero or !Jest.runner.?.run_todo)) or (tag != .only and Jest.runner.?.only and parent.tag != .only); - var tag_to_use = tag; if (is_test) { if (!is_skip) { if (Jest.runner.?.filter_regex) |regex| { @@ -1616,7 +1618,7 @@ inline fn createScope( .label = label, .parent = parent, .file_id = parent.file_id, - .tag = tag, + .tag = tag_to_use, }; return scope.run(globalThis, function, &.{}); @@ -1857,7 +1859,15 @@ fn eachBind( (description.toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch unreachable).slice(); const formattedLabel = formatLabel(globalThis, label, function_args, test_idx) catch return .zero; - var is_skip = false; + const tag = parent.tag; + + if (tag == .only) { + Jest.runner.?.setOnly(); + } + + var is_skip = tag == .skip or + (tag == .todo and (function == .zero or !Jest.runner.?.run_todo)) or + (tag != .only and Jest.runner.?.only and parent.tag != .only); if (Jest.runner.?.filter_regex) |regex| { var buffer: bun.MutableString = Jest.runner.?.filter_buffer; @@ -1872,21 +1882,25 @@ fn eachBind( parent.skip_count += 1; function.unprotect(); } else if (each_data.is_test) { - function.protect(); - parent.tests.append(allocator, TestScope{ - .label = formattedLabel, - .parent = parent, - .tag = parent.tag, - .func = function, - .func_arg = function_args, - .func_has_callback = has_callback_function, - .timeout_millis = timeout_ms, - }) catch unreachable; + if (Jest.runner.?.only and tag != .only) { + return .zero; + } else { + function.protect(); + parent.tests.append(allocator, TestScope{ + .label = formattedLabel, + .parent = parent, + .tag = tag, + .func = function, + .func_arg = function_args, + .func_has_callback = has_callback_function, + .timeout_millis = timeout_ms, + }) catch unreachable; - if (test_elapsed_timer == null) create_timer: { - const timer = allocator.create(std.time.Timer) catch unreachable; - timer.* = std.time.Timer.start() catch break :create_timer; - test_elapsed_timer = timer; + if (test_elapsed_timer == null) create_timer: { + const timer = allocator.create(std.time.Timer) catch unreachable; + timer.* = std.time.Timer.start() catch break :create_timer; + test_elapsed_timer = timer; + } } } else { var scope = allocator.create(DescribeScope) catch unreachable; @@ -1894,7 +1908,7 @@ fn eachBind( .label = formattedLabel, .parent = parent, .file_id = parent.file_id, - .tag = .pass, + .tag = tag, }; const ret = scope.run(globalThis, function, function_args); diff --git a/test/regression/issue/08964.test.ts b/test/regression/issue/08964.test.ts new file mode 100644 index 0000000000..1e05a31415 --- /dev/null +++ b/test/regression/issue/08964.test.ts @@ -0,0 +1,53 @@ +// This test passes by simply running it. It is a regression test for issue #8964 +import { describe, test, afterAll } from "bun:test"; + +var expected: number[] = []; +var runs: number[] = []; +var count = 0; +function makeTest(yes = false) { + const thisCount = count++; + if (yes) expected.push(thisCount); + test("test " + thisCount, () => { + runs.push(thisCount); + }); +} + +describe("Outer", () => { + describe.only("Inner", () => { + describe("Inside Only", () => { + makeTest(true); + }); + makeTest(true); + + expected.push(997, 998, 999); + test.each([997, 998, 999])("test %i", i => { + runs.push(i); + }); + }); + + test.each([2997, 2998, 2999])("test %i", i => { + runs.push(i); + }); + + describe("Inner #2", () => { + makeTest(); + describe("Inside Inner #2", () => { + makeTest(); + describe.only("Inside Inner #2 Only", () => { + makeTest(true); + }); + }); + }); + makeTest(); +}); + +afterAll(() => { + if (runs.length !== expected.length) { + console.error(new Error("Test count mismatch")); + process.exit(1); + } + if (runs.sort().join(",") !== expected.sort().join(",")) { + console.error(new Error("Test order mismatch")); + process.exit(1); + } +});