The Standard Library has been moved to JSR. See the blog post for details.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.import { DescribeDefinition, HookNames, ItDefinition, TestSuite, TestSuiteInternal,} from "./_test_suite.ts";export type { DescribeDefinition, ItDefinition, TestSuite };
/** The arguments for an ItFunction. */export type ItArgs<T> = | [options: ItDefinition<T>] | [ name: string, options: Omit<ItDefinition<T>, "name">, ] | [ name: string, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [fn: (this: T, t: Deno.TestContext) => void | Promise<void>] | [ name: string, options: Omit<ItDefinition<T>, "fn" | "name">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ options: Omit<ItDefinition<T>, "fn">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ options: Omit<ItDefinition<T>, "fn" | "name">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ suite: TestSuite<T>, name: string, options: Omit<ItDefinition<T>, "name" | "suite">, ] | [ suite: TestSuite<T>, name: string, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ suite: TestSuite<T>, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ suite: TestSuite<T>, name: string, options: Omit<ItDefinition<T>, "fn" | "name" | "suite">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ suite: TestSuite<T>, options: Omit<ItDefinition<T>, "fn" | "suite">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ] | [ suite: TestSuite<T>, options: Omit<ItDefinition<T>, "fn" | "name" | "suite">, fn: (this: T, t: Deno.TestContext) => void | Promise<void>, ];
/** Generates an ItDefinition from ItArgs. */function itDefinition<T>(...args: ItArgs<T>): ItDefinition<T> { let [ suiteOptionsOrNameOrFn, optionsOrNameOrFn, optionsOrFn, fn, ] = args; let suite: TestSuite<T> | undefined = undefined; let name: string; let options: | ItDefinition<T> | Omit<ItDefinition<T>, "fn"> | Omit<ItDefinition<T>, "name"> | Omit<ItDefinition<T>, "fn" | "name">; if ( typeof suiteOptionsOrNameOrFn === "object" && typeof (suiteOptionsOrNameOrFn as TestSuite<T>).symbol === "symbol" ) { suite = suiteOptionsOrNameOrFn as TestSuite<T>; } else { fn = optionsOrFn as typeof fn; optionsOrFn = optionsOrNameOrFn as typeof optionsOrFn; optionsOrNameOrFn = suiteOptionsOrNameOrFn as typeof optionsOrNameOrFn; } if (typeof optionsOrNameOrFn === "string") { name = optionsOrNameOrFn; if (typeof optionsOrFn === "function") { fn = optionsOrFn; options = {}; } else { options = optionsOrFn!; if (!fn) fn = (options as Omit<ItDefinition<T>, "name">).fn; } } else if (typeof optionsOrNameOrFn === "function") { fn = optionsOrNameOrFn; name = fn.name; options = {}; } else { options = optionsOrNameOrFn!; if (typeof optionsOrFn === "function") { fn = optionsOrFn; } else { fn = (options as ItDefinition<T>).fn; } name = (options as ItDefinition<T>).name ?? fn.name; }
return { suite, ...options, name, fn, };}
/** Registers an individual test case. */export interface it { <T>(...args: ItArgs<T>): void;
/** Registers an individual test case with only set to true. */ only<T>(...args: ItArgs<T>): void;
/** Registers an individual test case with ignore set to true. */ ignore<T>(...args: ItArgs<T>): void;}
/** Registers an individual test case. */export function it<T>(...args: ItArgs<T>): void { if (TestSuiteInternal.runningCount > 0) { throw new Error( "cannot register new test cases after already registered test cases start running", ); } const options = itDefinition(...args); const { suite } = options; const testSuite = suite ? TestSuiteInternal.suites.get(suite.symbol) : TestSuiteInternal.current;
if (!TestSuiteInternal.started) TestSuiteInternal.started = true; if (testSuite) { TestSuiteInternal.addStep(testSuite, options); } else { const { name, fn, ignore, only, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = options; TestSuiteInternal.registerTest({ name, ignore, only, permissions, sanitizeExit, sanitizeOps, sanitizeResources, async fn(t) { TestSuiteInternal.runningCount++; try { await fn.call({} as T, t); } finally { TestSuiteInternal.runningCount--; } }, }); }}
it.only = function itOnly<T>(...args: ItArgs<T>): void { const options = itDefinition(...args); return it({ ...options, only: true, });};
it.ignore = function itIgnore<T>(...args: ItArgs<T>): void { const options = itDefinition(...args); return it({ ...options, ignore: true, });};
function addHook<T>( name: HookNames, fn: (this: T) => void | Promise<void>,): void { if (!TestSuiteInternal.current) { if (TestSuiteInternal.started) { throw new Error( "cannot add global hooks after a global test is registered", ); } TestSuiteInternal.current = new TestSuiteInternal({ name: "global", [name]: fn, }); } else { TestSuiteInternal.setHook(TestSuiteInternal.current!, name, fn); }}
/** Run some shared setup before all of the tests in the suite. */export function beforeAll<T>( fn: (this: T) => void | Promise<void>,): void { addHook("beforeAll", fn);}
/** Run some shared teardown after all of the tests in the suite. */export function afterAll<T>( fn: (this: T) => void | Promise<void>,): void { addHook("afterAll", fn);}
/** Run some shared setup before each test in the suite. */export function beforeEach<T>( fn: (this: T) => void | Promise<void>,): void { addHook("beforeEach", fn);}
/** Run some shared teardown after each test in the suite. */export function afterEach<T>( fn: (this: T) => void | Promise<void>,): void { addHook("afterEach", fn);}
/** The arguments for a DescribeFunction. */export type DescribeArgs<T> = | [options: DescribeDefinition<T>] | [name: string] | [ name: string, options: Omit<DescribeDefinition<T>, "name">, ] | [name: string, fn: () => void] | [fn: () => void] | [ name: string, options: Omit<DescribeDefinition<T>, "fn" | "name">, fn: () => void, ] | [ options: Omit<DescribeDefinition<T>, "fn">, fn: () => void, ] | [ options: Omit<DescribeDefinition<T>, "fn" | "name">, fn: () => void, ] | [ suite: TestSuite<T>, name: string, ] | [ suite: TestSuite<T>, name: string, options: Omit<DescribeDefinition<T>, "name" | "suite">, ] | [ suite: TestSuite<T>, name: string, fn: () => void, ] | [ suite: TestSuite<T>, fn: () => void, ] | [ suite: TestSuite<T>, name: string, options: Omit<DescribeDefinition<T>, "fn" | "name" | "suite">, fn: () => void, ] | [ suite: TestSuite<T>, options: Omit<DescribeDefinition<T>, "fn" | "suite">, fn: () => void, ] | [ suite: TestSuite<T>, options: Omit<DescribeDefinition<T>, "fn" | "name" | "suite">, fn: () => void, ];
/** Generates a DescribeDefinition from DescribeArgs. */function describeDefinition<T>( ...args: DescribeArgs<T>): DescribeDefinition<T> { let [ suiteOptionsOrNameOrFn, optionsOrNameOrFn, optionsOrFn, fn, ] = args; let suite: TestSuite<T> | undefined = undefined; let name: string; let options: | DescribeDefinition<T> | Omit<DescribeDefinition<T>, "fn"> | Omit<DescribeDefinition<T>, "name"> | Omit<DescribeDefinition<T>, "fn" | "name">; if ( typeof suiteOptionsOrNameOrFn === "object" && typeof (suiteOptionsOrNameOrFn as TestSuite<T>).symbol === "symbol" ) { suite = suiteOptionsOrNameOrFn as TestSuite<T>; } else { fn = optionsOrFn as typeof fn; optionsOrFn = optionsOrNameOrFn as typeof optionsOrFn; optionsOrNameOrFn = suiteOptionsOrNameOrFn as typeof optionsOrNameOrFn; } if (typeof optionsOrNameOrFn === "string") { name = optionsOrNameOrFn; if (typeof optionsOrFn === "function") { fn = optionsOrFn; options = {}; } else { options = optionsOrFn ?? {}; if (!fn) fn = (options as Omit<DescribeDefinition<T>, "name">).fn; } } else if (typeof optionsOrNameOrFn === "function") { fn = optionsOrNameOrFn; name = fn.name; options = {}; } else { options = optionsOrNameOrFn ?? {}; if (typeof optionsOrFn === "function") { fn = optionsOrFn; } else { fn = (options as DescribeDefinition<T>).fn; } name = (options as DescribeDefinition<T>).name ?? fn?.name ?? ""; }
if (!suite) { suite = options.suite; } if (!suite && TestSuiteInternal.current) { const { symbol } = TestSuiteInternal.current; suite = { symbol }; }
return { ...options, suite, name, fn, };}
/** Registers a test suite. */export interface describe { <T>(...args: DescribeArgs<T>): TestSuite<T>;
/** Registers a test suite with only set to true. */ only<T>(...args: DescribeArgs<T>): TestSuite<T>;
/** Registers a test suite with ignore set to true. */ ignore<T>(...args: DescribeArgs<T>): TestSuite<T>;}
/** Registers a test suite. */export function describe<T>( ...args: DescribeArgs<T>): TestSuite<T> { if (TestSuiteInternal.runningCount > 0) { throw new Error( "cannot register new test suites after already registered test cases start running", ); } const options = describeDefinition(...args); if (!TestSuiteInternal.started) TestSuiteInternal.started = true; const { symbol } = new TestSuiteInternal(options); return { symbol };}
describe.only = function describeOnly<T>( ...args: DescribeArgs<T>): TestSuite<T> { const options = describeDefinition(...args); return describe({ ...options, only: true, });};
describe.ignore = function describeIgnore<T>( ...args: DescribeArgs<T>): TestSuite<T> { const options = describeDefinition(...args); return describe({ ...options, ignore: true, });};