From 9f1f8dc418c5784d1c812a5eb789debbad0f1395 Mon Sep 17 00:00:00 2001 From: AlCalzone Date: Sun, 28 Aug 2022 16:20:45 +0200 Subject: [PATCH] feat: support `suite.skip` and `suite.only` (#518) --- README.md | 9 +++++ build/tests/integration/index.d.ts | 13 ++++++-- build/tests/integration/index.js | 29 ++++++++++------ src/tests/integration/index.ts | 53 +++++++++++++++++++++++------- 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a20856a0..9c4fa034 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,15 @@ tests.integration(path.join(__dirname, ".."), { }); }); }); + + // While developing the tests, you can run only a single suite using `suite.only`... + suite.only("Only this will run", (getHarness) => { + // ... + }); + // ...or prevent a suite from running using `suite.skip`: + suite.skip("This will never run", (getHarness) => { + // ... + }); }, }); ``` diff --git a/build/tests/integration/index.d.ts b/build/tests/integration/index.d.ts index 9347feec..b8898980 100644 --- a/build/tests/integration/index.d.ts +++ b/build/tests/integration/index.d.ts @@ -10,14 +10,23 @@ export interface TestAdapterOptions { /** Allows you to define additional tests */ defineAdditionalTests?: (args: TestContext) => void; } +export interface TestSuiteFn { + (name: string, fn: (getHarness: () => TestHarness) => void): void; +} +export interface TestSuite extends TestSuiteFn { + /** Only runs the tests inside this `suite` for the current file */ + only: TestSuiteFn; + /** Skips running the tests inside this `suite` for the current file */ + skip: TestSuiteFn; +} export interface TestContext { /** * Defines a test suite. At the start of each suite, the adapter will be started with a fresh environment. * To define tests in each suite, use describe and it as usual. * - * Each suite has its own test harness, which gets passed as an argument. + * Each suite has its own test harness, which can be retrieved using the function that is passed to the suite callback. */ - suite: (name: string, fn: (getHarness: () => TestHarness) => void) => void; + suite: TestSuite; describe: Mocha.SuiteFunction; it: Mocha.TestFunction; } diff --git a/build/tests/integration/index.js b/build/tests/integration/index.js index 410c367c..0033877b 100644 --- a/build/tests/integration/index.js +++ b/build/tests/integration/index.js @@ -175,17 +175,26 @@ function testAdapter(adapterDir, options = {}) { describe("User-defined tests", () => { // patch the global it() function so nobody can bypass the checks global.it = patchedIt; + // a test suite is a special describe which sets up and tears down the test environment before and after ALL tests + const suiteBody = (fn) => { + isInSuite = true; + before(resetDbAndStartHarness); + fn(() => harness); + after(shutdownTests); + isInSuite = false; + }; + const suite = ((name, fn) => { + describe(name, () => suiteBody(fn)); + }); + // Support .skip and .only + suite.skip = (name, fn) => { + describe.skip(name, () => suiteBody(fn)); + }; + suite.only = (name, fn) => { + describe.only(name, () => suiteBody(fn)); + }; const args = { - // a test suite is a special describe which sets up and tears down the test environment before and after ALL tests - suite: (name, fn) => { - describe(name, () => { - isInSuite = true; - before(resetDbAndStartHarness); - fn(() => harness); - after(shutdownTests); - isInSuite = false; - }); - }, + suite, describe, it: patchedIt, }; diff --git a/src/tests/integration/index.ts b/src/tests/integration/index.ts index 33fe6220..7519bb8b 100644 --- a/src/tests/integration/index.ts +++ b/src/tests/integration/index.ts @@ -18,6 +18,17 @@ export interface TestAdapterOptions { defineAdditionalTests?: (args: TestContext) => void; } +export interface TestSuiteFn { + (name: string, fn: (getHarness: () => TestHarness) => void): void; +} + +export interface TestSuite extends TestSuiteFn { + /** Only runs the tests inside this `suite` for the current file */ + only: TestSuiteFn; + /** Skips running the tests inside this `suite` for the current file */ + skip: TestSuiteFn; +} + export interface TestContext { /** * Defines a test suite. At the start of each suite, the adapter will be started with a fresh environment. @@ -25,7 +36,7 @@ export interface TestContext { * * Each suite has its own test harness, which can be retrieved using the function that is passed to the suite callback. */ - suite: (name: string, fn: (getHarness: () => TestHarness) => void) => void; + suite: TestSuite; describe: Mocha.SuiteFunction; it: Mocha.TestFunction; @@ -230,19 +241,37 @@ export function testAdapter( // patch the global it() function so nobody can bypass the checks global.it = patchedIt; - const args: TestContext = { - // a test suite is a special describe which sets up and tears down the test environment before and after ALL tests - suite: (name, fn) => { - describe(name, () => { - isInSuite = true; - before(resetDbAndStartHarness); + // a test suite is a special describe which sets up and tears down the test environment before and after ALL tests + const suiteBody = ( + fn: (getHarness: () => TestHarness) => void, + ): void => { + isInSuite = true; + before(resetDbAndStartHarness); - fn(() => harness); + fn(() => harness); - after(shutdownTests); - isInSuite = false; - }); - }, + after(shutdownTests); + isInSuite = false; + }; + + const suite = (( + name: string, + fn: (getHarness: () => TestHarness) => void, + ): void => { + describe(name, () => suiteBody(fn)); + }) as TestSuite; + + // Support .skip and .only + suite.skip = (name, fn) => { + describe.skip(name, () => suiteBody(fn)); + }; + + suite.only = (name, fn) => { + describe.only(name, () => suiteBody(fn)); + }; + + const args: TestContext = { + suite, describe, it: patchedIt, };