1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

feat: allow first arg in test step to be a function (#17096)

This commit is contained in:
Leo Kettmeir 2023-01-24 15:41:01 +01:00 committed by GitHub
parent fc2e00152b
commit 2027d98a8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 12 deletions

View file

@ -1265,10 +1265,10 @@
*/ */
origin: desc.origin, origin: desc.origin,
/** /**
* @param nameOrTestDefinition {string | TestStepDefinition} * @param nameOrFnOrOptions {string | TestStepDefinition | ((t: TestContext) => void | Promise<void>)}
* @param fn {(t: TestContext) => void | Promise<void>} * @param maybeFn {((t: TestContext) => void | Promise<void>) | undefined}
*/ */
async step(nameOrTestDefinition, fn) { async step(nameOrFnOrOptions, maybeFn) {
if (MapPrototypeGet(testStates, desc.id).finalized) { if (MapPrototypeGet(testStates, desc.id).finalized) {
throw new Error( throw new Error(
"Cannot run test step after parent scope has finished execution. " + "Cannot run test step after parent scope has finished execution. " +
@ -1277,16 +1277,29 @@
} }
let stepDesc; let stepDesc;
if (typeof nameOrTestDefinition === "string") { if (typeof nameOrFnOrOptions === "string") {
if (!(ObjectPrototypeIsPrototypeOf(FunctionPrototype, fn))) { if (!(ObjectPrototypeIsPrototypeOf(FunctionPrototype, maybeFn))) {
throw new TypeError("Expected function for second argument."); throw new TypeError("Expected function for second argument.");
} }
stepDesc = { stepDesc = {
name: nameOrTestDefinition, name: nameOrFnOrOptions,
fn, fn: maybeFn,
}; };
} else if (typeof nameOrTestDefinition === "object") { } else if (typeof nameOrFnOrOptions === "function") {
stepDesc = nameOrTestDefinition; if (!nameOrFnOrOptions.name) {
throw new TypeError("The step function must have a name.");
}
if (maybeFn != undefined) {
throw new TypeError(
"Unexpected second argument to TestContext.step()",
);
}
stepDesc = {
name: nameOrFnOrOptions.name,
fn: nameOrFnOrOptions,
};
} else if (typeof nameOrFnOrOptions === "object") {
stepDesc = nameOrFnOrOptions;
} else { } else {
throw new TypeError( throw new TypeError(
"Expected a test definition or name and function.", "Expected a test definition or name and function.",

View file

@ -1,11 +1,17 @@
[WILDCARD] [WILDCARD]
running 5 tests from ./test/steps/passing_steps.ts running 6 tests from ./test/steps/passing_steps.ts
description ... description ...
step 1 ... step 1 ...
inner 1 ... ok ([WILDCARD]ms) inner 1 ... ok ([WILDCARD]ms)
inner 2 ... ok ([WILDCARD]ms) inner 2 ... ok ([WILDCARD]ms)
step 1 ... ok ([WILDCARD]ms) step 1 ... ok ([WILDCARD]ms)
description ... ok ([WILDCARD]ms) description ... ok ([WILDCARD]ms)
description function as first arg ...
step1 ...
inner1 ... ok ([WILDCARD]ms)
inner1 ... ok ([WILDCARD]ms)
step1 ... ok ([WILDCARD]ms)
description function as first arg ... ok ([WILDCARD]ms)
parallel steps without sanitizers ... parallel steps without sanitizers ...
step 1 ... ok ([WILDCARD]) step 1 ... ok ([WILDCARD])
step 2 ... ok ([WILDCARD]) step 2 ... ok ([WILDCARD])
@ -35,4 +41,4 @@ steps buffered then streaming reporting ...
step 2 ... ok ([WILDCARD]) step 2 ... ok ([WILDCARD])
steps buffered then streaming reporting ... ok ([WILDCARD]) steps buffered then streaming reporting ... ok ([WILDCARD])
ok | 5 passed (18 steps) | 0 failed [WILDCARD] ok | 6 passed (21 steps) | 0 failed [WILDCARD]

View file

@ -9,6 +9,15 @@ Deno.test("description", async (t) => {
if (!success) throw new Error("Expected the step to return true."); if (!success) throw new Error("Expected the step to return true.");
}); });
Deno.test("description function as first arg", async (t) => {
const success = await t.step(async function step1(t) {
await t.step(function inner1() {});
await t.step(function inner1() {});
});
if (!success) throw new Error("Expected the step to return true.");
});
Deno.test("parallel steps without sanitizers", async (t) => { Deno.test("parallel steps without sanitizers", async (t) => {
// allowed // allowed
await Promise.all([ await Promise.all([

View file

@ -114,7 +114,7 @@ Deno.test(async function invalidStepArguments(t) {
await (t as any).step(() => {}); await (t as any).step(() => {});
}, },
TypeError, TypeError,
"Expected a test definition or name and function.", "The step function must have a name.",
); );
}); });

View file

@ -668,6 +668,25 @@ declare namespace Deno {
name: string, name: string,
fn: (t: TestContext) => void | Promise<void>, fn: (t: TestContext) => void | Promise<void>,
): Promise<boolean>; ): Promise<boolean>;
/** Run a sub step of the parent test or step. Returns a promise
* that resolves to a boolean signifying if the step completed successfully.
*
* The returned promise never rejects unless the arguments are invalid.
*
* If the test was ignored the promise returns `false`.
*
* ```ts
* Deno.test(async function aParentTest(t) {
* console.log("before the step");
* await t.step(function step1(t) {
* console.log("current step:", t.name);
* });
* console.log("after the step");
* });
* ```
*/
step(fn: (t: TestContext) => void | Promise<void>): Promise<boolean>;
} }
/** @category Testing */ /** @category Testing */