diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index d55ac231eb..485b3d4905 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -250,6 +250,19 @@ declare namespace Deno { } export interface TestContext { + /** + * The current test name. + */ + name: string; + /** + * File Uri of the current test code. + */ + origin: string; + /** + * Parent test context. + */ + parent?: TestContext; + /** 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. @@ -270,6 +283,9 @@ declare namespace Deno { export interface TestStepDefinition { fn: (t: TestContext) => void | Promise; + /** + * The current test name. + */ name: string; ignore?: boolean; /** Check that the number of async completed ops after the test step is the same @@ -287,6 +303,9 @@ declare namespace Deno { export interface TestDefinition { fn: (t: TestContext) => void | Promise; + /** + * The current test name. + */ name: string; ignore?: boolean; /** If at least one test has `only` set to true, only run tests that have diff --git a/cli/tests/unit/testing_test.ts b/cli/tests/unit/testing_test.ts index 87b862a7db..90575aeb28 100644 --- a/cli/tests/unit/testing_test.ts +++ b/cli/tests/unit/testing_test.ts @@ -1,5 +1,5 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -import { assertRejects, assertThrows } from "./test_util.ts"; +import { assertEquals, assertRejects, assertThrows } from "./test_util.ts"; Deno.test(function testWrongOverloads() { assertThrows( @@ -117,3 +117,33 @@ Deno.test(async function invalidStepArguments(t) { "Expected a test definition or name and function.", ); }); + +Deno.test(async function nameOnTextContext(t1) { + await assertEquals(t1.name, "nameOnTextContext"); + await t1.step("step", async (t2) => { + await assertEquals(t2.name, "step"); + await t2.step("nested step", async (t3) => { + await assertEquals(t3.name, "nested step"); + }); + }); +}); + +Deno.test(async function originOnTextContext(t1) { + await assertEquals(t1.origin, Deno.mainModule); + await t1.step("step", async (t2) => { + await assertEquals(t2.origin, Deno.mainModule); + await t2.step("nested step", async (t3) => { + await assertEquals(t3.origin, Deno.mainModule); + }); + }); +}); + +Deno.test(async function parentOnTextContext(t1) { + await assertEquals(t1.parent, undefined); + await t1.step("step", async (t2) => { + await assertEquals(t1, t2.parent); + await t2.step("nested step", async (t3) => { + await assertEquals(t2, t3.parent); + }); + }); +}); diff --git a/runtime/js/40_testing.js b/runtime/js/40_testing.js index abbef2ae44..0b75daa240 100644 --- a/runtime/js/40_testing.js +++ b/runtime/js/40_testing.js @@ -792,6 +792,7 @@ const step = new TestStep({ name: test.name, parent: undefined, + parentContext: undefined, rootTestDescription: description, sanitizeOps: test.sanitizeOps, sanitizeResources: test.sanitizeResources, @@ -1064,8 +1065,9 @@ * }} TestStepDefinition * * @typedef {{ - * name: string; + * name: string, * parent: TestStep | undefined, + * parentContext: TestContext | undefined, * rootTestDescription: { origin: string; name: string }; * sanitizeOps: boolean, * sanitizeResources: boolean, @@ -1099,6 +1101,10 @@ return this.#params.parent; } + get parentContext() { + return this.#params.parentContext; + } + get rootTestDescription() { return this.#params.rootTestDescription; } @@ -1268,6 +1274,18 @@ function createTestContext(parentStep) { return { [SymbolToStringTag]: "TestContext", + /** + * The current test name. + */ + name: parentStep.name, + /** + * Parent test context. + */ + parent: parentStep.parentContext ?? undefined, + /** + * File Uri of the test code. + */ + origin: parentStep.rootTestDescription.origin, /** * @param nameOrTestDefinition {string | TestStepDefinition} * @param fn {(t: TestContext) => void | Promise} @@ -1284,6 +1302,7 @@ const subStep = new TestStep({ name: definition.name, parent: parentStep, + parentContext: this, rootTestDescription: parentStep.rootTestDescription, sanitizeOps: getOrDefault( definition.sanitizeOps,