Skip to content

Commit 030ac5c

Browse files
fix(testing): stop beforeAll from swallowing test.only error (#7000)
1 parent e413b2b commit 030ac5c

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

testing/_test_suite.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
6969
protected describe: DescribeDefinition<T>;
7070
protected steps: (TestSuiteInternal<T> | ItDefinition<T>)[];
7171
protected hasOnlyStep: boolean;
72+
#registeredOptions: Deno.TestDefinition | undefined;
7273

7374
constructor(describe: DescribeDefinition<T>) {
7475
this.describe = describe;
@@ -203,7 +204,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
203204
if (sanitizeResources !== undefined) {
204205
options.sanitizeResources = sanitizeResources;
205206
}
206-
TestSuiteInternal.registerTest(options);
207+
this.#registeredOptions = TestSuiteInternal.registerTest(options);
207208
}
208209
}
209210

@@ -233,7 +234,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
233234
}
234235

235236
/** This is used internally to register tests. */
236-
static registerTest(options: Deno.TestDefinition) {
237+
static registerTest(options: Deno.TestDefinition): Deno.TestDefinition {
237238
options = { ...options };
238239
if (options.only === undefined) {
239240
delete options.only;
@@ -254,6 +255,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
254255
delete options.sanitizeResources;
255256
}
256257
Deno.test(options);
258+
return options;
257259
}
258260

259261
/** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
@@ -274,6 +276,12 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
274276
if (parentTestSuite) {
275277
TestSuiteInternal.addingOnlyStep(parentTestSuite);
276278
}
279+
280+
// If this suite was already registered with Deno.test (e.g. a global
281+
// suite created by beforeAll), retroactively mark it as only.
282+
if (suite.#registeredOptions) {
283+
suite.#registeredOptions.only = true;
284+
}
277285
}
278286

279287
/** This is used internally to add steps to a test suite. */

testing/bdd_test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ Deno.test("beforeAll(), afterAll(), beforeEach() and afterEach()", async () => {
123123
assertSpyCalls(afterEachFn, 2);
124124
});
125125

126+
Deno.test("beforeAll() with it.only() propagates only to Deno.test", () => {
127+
using test = stub(Deno, "test");
128+
try {
129+
beforeAll(() => {});
130+
131+
it({ name: "a", fn: () => {} });
132+
it.only({ name: "b", fn: () => {} });
133+
it({ name: "c", fn: () => {} });
134+
135+
assertSpyCall(test, 0);
136+
const options = test.calls[0]?.args[0] as Deno.TestDefinition;
137+
assertEquals(Object.keys(options).sort(), ["fn", "name", "only"]);
138+
assertObjectMatch(options, { name: "global", only: true });
139+
} finally {
140+
TestSuiteInternal.reset();
141+
}
142+
});
143+
126144
Deno.test("it()", async (t) => {
127145
/**
128146
* Asserts that `Deno.test` is called with the correct options for the `it` call in the callback function.
@@ -1418,7 +1436,6 @@ Deno.test("describe()", async (t) => {
14181436
await t.step("flat child only", async (t) => {
14191437
/**
14201438
* Asserts that when only is used on a child `describe` or `it` call, it will be the only test case or suite that runs within the top test suite.
1421-
* This demonstrates the issue where `Deno.test` is called without `only` even though one of its child steps are focused.
14221439
* This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures.
14231440
*/
14241441
async function assertOnly(
@@ -1434,10 +1451,11 @@ Deno.test("describe()", async (t) => {
14341451
const options = call?.args[0] as Deno.TestDefinition;
14351452
assertEquals(
14361453
Object.keys(options).sort(),
1437-
["name", "fn"].sort(),
1454+
["name", "only", "fn"].sort(),
14381455
);
14391456
assertObjectMatch(options, {
14401457
name: "example",
1458+
only: true,
14411459
});
14421460

14431461
assertSpyCalls(fns[0], 0);

0 commit comments

Comments
 (0)