Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions testing/_test_suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
protected describe: DescribeDefinition<T>;
protected steps: (TestSuiteInternal<T> | ItDefinition<T>)[];
protected hasOnlyStep: boolean;
#registeredOptions: Deno.TestDefinition | undefined;

constructor(describe: DescribeDefinition<T>) {
this.describe = describe;
Expand Down Expand Up @@ -203,7 +204,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
if (sanitizeResources !== undefined) {
options.sanitizeResources = sanitizeResources;
}
TestSuiteInternal.registerTest(options);
this.#registeredOptions = TestSuiteInternal.registerTest(options);
}
}

Expand Down Expand Up @@ -233,7 +234,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
}

/** This is used internally to register tests. */
static registerTest(options: Deno.TestDefinition) {
static registerTest(options: Deno.TestDefinition): Deno.TestDefinition {
options = { ...options };
if (options.only === undefined) {
delete options.only;
Expand All @@ -254,6 +255,7 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
delete options.sanitizeResources;
}
Deno.test(options);
return options;
}

/** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
Expand All @@ -274,6 +276,12 @@ export class TestSuiteInternal<T> implements TestSuite<T> {
if (parentTestSuite) {
TestSuiteInternal.addingOnlyStep(parentTestSuite);
}

// If this suite was already registered with Deno.test (e.g. a global
// suite created by beforeAll), retroactively mark it as only.
if (suite.#registeredOptions) {
suite.#registeredOptions.only = true;
}
}

/** This is used internally to add steps to a test suite. */
Expand Down
22 changes: 20 additions & 2 deletions testing/bdd_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,24 @@ Deno.test("beforeAll(), afterAll(), beforeEach() and afterEach()", async () => {
assertSpyCalls(afterEachFn, 2);
});

Deno.test("beforeAll() with it.only() propagates only to Deno.test", () => {
using test = stub(Deno, "test");
try {
beforeAll(() => {});

it({ name: "a", fn: () => {} });
it.only({ name: "b", fn: () => {} });
it({ name: "c", fn: () => {} });

assertSpyCall(test, 0);
const options = test.calls[0]?.args[0] as Deno.TestDefinition;
assertEquals(Object.keys(options).sort(), ["fn", "name", "only"]);
assertObjectMatch(options, { name: "global", only: true });
} finally {
TestSuiteInternal.reset();
}
});

Deno.test("it()", async (t) => {
/**
* Asserts that `Deno.test` is called with the correct options for the `it` call in the callback function.
Expand Down Expand Up @@ -1418,7 +1436,6 @@ Deno.test("describe()", async (t) => {
await t.step("flat child only", async (t) => {
/**
* 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.
* This demonstrates the issue where `Deno.test` is called without `only` even though one of its child steps are focused.
* This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures.
*/
async function assertOnly(
Expand All @@ -1434,10 +1451,11 @@ Deno.test("describe()", async (t) => {
const options = call?.args[0] as Deno.TestDefinition;
assertEquals(
Object.keys(options).sort(),
["name", "fn"].sort(),
["name", "only", "fn"].sort(),
);
assertObjectMatch(options, {
name: "example",
only: true,
});

assertSpyCalls(fns[0], 0);
Expand Down
Loading