Skip to content

Instantly share code, notes, and snippets.

@caspervonb
Last active August 23, 2021 07:16
Show Gist options
  • Save caspervonb/62db35a0cc9532dc618b96fcda205576 to your computer and use it in GitHub Desktop.
Save caspervonb/62db35a0cc9532dc618b96fcda205576 to your computer and use it in GitHub Desktop.
namespace Deno {
  export interface TestCase {
    name: string;
    fn: () => void | Promise<void>;
    /** Ignore this test case during execution. Defaults to false. */
    ignore?: boolean;
    /** If at least one test case has `only` set to true, only run tests that have
     * `only` set to true and fail the test suite. */
    only?: boolean;
    /** Check that the number of async completed ops after the test is the same
     * as number of dispatched ops. Defaults to true.*/
    sanitizeOps?: boolean;
    /** Ensure the test case does not "leak" resources - ie. the resource table
     * after the test has exactly the same contents as before the test. Defaults
     * to true. */
    sanitizeResources?: boolean;
    /** Ensure the test case does not prematurely cause the process to exit,
     * for example via a call to `Deno.exit`. Defaults to true. */
    sanitizeExit?: boolean;
    // Concurrency is handled in https://github.com/denoland/deno/pull/11789
  }

  interface TestGroup {
    name: string,
    tests: TestDefinition[],
    /** Ignore the tests ignored within this test group during execution. Defaults to false. */
    ignore?: boolean;
    /** Optional function which is called before any of the tests are executed. */
    before?: () => void | Promise<void>,
    /** Optional function  which is called after all the tests have finished executing. */
    after?: () => void | Promise<void>,
  }

  type TestDefinition = TestCase | TestGroup;

  interface TestHarness {
    (test: TestDefinition): void;
    (name: string, fn: () => void | Promise<void>): void;
    before(fn: () => void | Promise<void>): void;
    after(fn: () => void | Promise<void>): void;
    group(name: string, fn: (test: TestHarness) => void): void;
  }

  // Deno.test is now a test harness which offers some extra properties and overloads.
  export var test: TestHarness;
}

Deno.test.before(function() {
  console.log("This is executed before any of the top level tests");
});

// Regular test cases continue to work as is.
Deno.test("test 1", function() {
  console.log("executed test 1");
});

// We can consider adding ignore as it has been frequently requested.
Deno.test("test 2", function() {
  console.log("executed test 2");
});

// And
Deno.test("test 3", function() {
  console.log("executed test 3");
});

// Groups can be registered with the `Deno.test` function by passing in a literal `TestGroup`.
Deno.test({
  name: "declarative group",
  before: function() {
    console.log("This is executed before any tests in the declarative group");
  },
  tests: [
    {
      name: "test 1",
      fn() {
        console.log("Executed test 1 in the declarative group");
      },
    },
    {
      name: "test 2",
      fn() {
        console.log("Executed test 1 in the declarative group");
      },
    },
    {
      name: "test 3",
      fn() {
        console.log("Executed test 1 in the declarative group");
      },
    },
  ],
})

// To mirror the convinience of the `test(name: string, fn: () => void | Promise<void>)` overload
// we provide one for building out groups within a closure with the same interface (the TestHarness)
// as `Deno.test` provides.
Deno.test.group("imperative group", function(test) {
  // Just like top level `Deno.test`, this test harness lets you register before callbacks.
  test.before(function() {
    console.log("This is executed before any of the tests in imperative group");
  });

  test("test 1", function() {
  });

  test("test 2", function() {
  });

  test("test 3", function() {
  });

  test.before(function() {
    console.log("This is executed after all of the tests in imperative group");
  });
});

Deno.test.after(function() {
  console.log("This is executed after all of the top level tests");
});

Playground Link: Provided

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment