1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 16:42:21 -05:00

feat(test): Add Deno.test.ignore and Deno.test.only (#20365)

Closes https://github.com/denoland/deno/issues/17106
This commit is contained in:
Bartek Iwańczuk 2023-09-06 14:17:33 +02:00 committed by GitHub
parent 9befa566ec
commit 147c845c95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 538 additions and 311 deletions

View file

@ -600,11 +600,11 @@ let currentBenchUserExplicitStart = null;
/** @type {number | null} */ /** @type {number | null} */
let currentBenchUserExplicitEnd = null; let currentBenchUserExplicitEnd = null;
// Main test function provided by Deno. function testInner(
function test(
nameOrFnOrOptions, nameOrFnOrOptions,
optionsOrFn, optionsOrFn,
maybeFn, maybeFn,
overrides = {},
) { ) {
if (typeof ops.op_register_test != "function") { if (typeof ops.op_register_test != "function") {
return; return;
@ -690,6 +690,8 @@ function test(
testDesc = { ...defaults, ...nameOrFnOrOptions, fn, name }; testDesc = { ...defaults, ...nameOrFnOrOptions, fn, name };
} }
testDesc = { ...testDesc, ...overrides };
// Delete this prop in case the user passed it. It's used to detect steps. // Delete this prop in case the user passed it. It's used to detect steps.
delete testDesc.parent; delete testDesc.parent;
const jsError = core.destructureError(new Error()); const jsError = core.destructureError(new Error());
@ -721,6 +723,27 @@ function test(
}); });
} }
// Main test function provided by Deno.
function test(
nameOrFnOrOptions,
optionsOrFn,
maybeFn,
) {
return testInner(nameOrFnOrOptions, optionsOrFn, maybeFn);
}
test.ignore = function (nameOrFnOrOptions, optionsOrFn, maybeFn) {
return testInner(nameOrFnOrOptions, optionsOrFn, maybeFn, { ignore: true });
};
test.only = function (
nameOrFnOrOptions,
optionsOrFn,
maybeFn,
) {
return testInner(nameOrFnOrOptions, optionsOrFn, maybeFn, { only: true });
};
let registeredWarmupBench = false; let registeredWarmupBench = false;
// Main bench function provided by Deno. // Main bench function provided by Deno.

View file

@ -379,54 +379,63 @@ impl Visit for TestStepCollector<'_> {
fn visit_var_decl(&mut self, node: &ast::VarDecl) { fn visit_var_decl(&mut self, node: &ast::VarDecl) {
if let Some(test_context) = &self.maybe_test_context { if let Some(test_context) = &self.maybe_test_context {
for decl in &node.decls { for decl in &node.decls {
if let Some(init) = &decl.init { let Some(init) = &decl.init else {
match init.as_ref() { continue;
// Identify destructured assignments of `step` from test context };
ast::Expr::Ident(ident) => {
if ident.sym == *test_context { match init.as_ref() {
if let ast::Pat::Object(object_pat) = &decl.name { // Identify destructured assignments of `step` from test context
for prop in &object_pat.props { ast::Expr::Ident(ident) => {
match prop { if ident.sym != *test_context {
ast::ObjectPatProp::Assign(prop) => { continue;
if prop.key.sym.eq("step") { }
self.vars.insert(prop.key.sym.to_string()); let ast::Pat::Object(object_pat) = &decl.name else {
} continue;
} };
ast::ObjectPatProp::KeyValue(prop) => {
if let ast::PropName::Ident(key_ident) = &prop.key { for prop in &object_pat.props {
if key_ident.sym.eq("step") { match prop {
if let ast::Pat::Ident(value_ident) = ast::ObjectPatProp::Assign(prop) => {
&prop.value.as_ref() if prop.key.sym.eq("step") {
{ self.vars.insert(prop.key.sym.to_string());
self.vars.insert(value_ident.id.sym.to_string());
}
}
}
}
_ => (),
}
} }
} }
} ast::ObjectPatProp::KeyValue(prop) => {
} if let ast::PropName::Ident(key_ident) = &prop.key {
// Identify variable assignments where the init is test context if key_ident.sym.eq("step") {
// `.step` if let ast::Pat::Ident(value_ident) = &prop.value.as_ref()
ast::Expr::Member(member_expr) => { {
if let ast::Expr::Ident(obj_ident) = member_expr.obj.as_ref() { self.vars.insert(value_ident.id.sym.to_string());
if obj_ident.sym == *test_context {
if let ast::MemberProp::Ident(prop_ident) = &member_expr.prop
{
if prop_ident.sym.eq("step") {
if let ast::Pat::Ident(binding_ident) = &decl.name {
self.vars.insert(binding_ident.id.sym.to_string());
} }
} }
} }
} }
_ => (),
} }
} }
_ => (),
} }
// Identify variable assignments where the init is test context
// `.step`
ast::Expr::Member(member_expr) => {
let ast::Expr::Ident(obj_ident) = member_expr.obj.as_ref() else {
continue;
};
if obj_ident.sym != *test_context {
continue;
}
let ast::MemberProp::Ident(prop_ident) = &member_expr.prop else {
continue;
};
if prop_ident.sym.eq("step") {
if let ast::Pat::Ident(binding_ident) = &decl.name {
self.vars.insert(binding_ident.id.sym.to_string());
}
}
}
_ => (),
} }
} }
} }
@ -463,95 +472,151 @@ impl TestCollector {
impl Visit for TestCollector { impl Visit for TestCollector {
fn visit_call_expr(&mut self, node: &ast::CallExpr) { fn visit_call_expr(&mut self, node: &ast::CallExpr) {
if let ast::Callee::Expr(callee_expr) = &node.callee { fn visit_if_deno_test(
match callee_expr.as_ref() { collector: &mut TestCollector,
ast::Expr::Ident(ident) => { node: &ast::CallExpr,
if self.vars.contains(&ident.sym.to_string()) { range: &deno_ast::SourceRange,
visit_call_expr( ns_prop_ident: &ast::Ident,
node, member_expr: &ast::MemberExpr,
Some(&self.fns), ) {
source_range_to_lsp_range(&ident.range(), &self.text_info), if ns_prop_ident.sym.to_string() == "test" {
None, let ast::Expr::Ident(ident) = member_expr.obj.as_ref() else {
&self.text_info, return;
&mut self.test_module, };
);
} if ident.sym.to_string() != "Deno" {
return;
} }
ast::Expr::Member(member_expr) => {
if let ast::MemberProp::Ident(ns_prop_ident) = &member_expr.prop { visit_call_expr(
if ns_prop_ident.sym.to_string() == "test" { node,
if let ast::Expr::Ident(ident) = member_expr.obj.as_ref() { Some(&collector.fns),
if ident.sym.to_string() == "Deno" { source_range_to_lsp_range(range, &collector.text_info),
visit_call_expr( None,
node, &collector.text_info,
Some(&self.fns), &mut collector.test_module,
source_range_to_lsp_range( );
&ns_prop_ident.range(),
&self.text_info,
),
None,
&self.text_info,
&mut self.test_module,
);
}
}
}
}
}
_ => (),
} }
} }
let ast::Callee::Expr(callee_expr) = &node.callee else {
return;
};
match callee_expr.as_ref() {
ast::Expr::Ident(ident) => {
if self.vars.contains(&ident.sym.to_string()) {
visit_call_expr(
node,
Some(&self.fns),
source_range_to_lsp_range(&ident.range(), &self.text_info),
None,
&self.text_info,
&mut self.test_module,
);
}
}
ast::Expr::Member(member_expr) => {
let ast::MemberProp::Ident(ns_prop_ident) = &member_expr.prop else {
return;
};
let ns_prop_ident_name = ns_prop_ident.sym.to_string();
visit_if_deno_test(
self,
node,
&ns_prop_ident.range(),
ns_prop_ident,
member_expr,
);
if ns_prop_ident_name == "ignore" || ns_prop_ident_name == "only" {
let ast::Expr::Member(child_member_expr) = member_expr.obj.as_ref()
else {
return;
};
let ast::MemberProp::Ident(child_ns_prop_ident) =
&child_member_expr.prop
else {
return;
};
visit_if_deno_test(
self,
node,
&ns_prop_ident.range(),
child_ns_prop_ident,
child_member_expr,
);
}
}
_ => (),
}
} }
fn visit_var_decl(&mut self, node: &ast::VarDecl) { fn visit_var_decl(&mut self, node: &ast::VarDecl) {
for decl in &node.decls { for decl in &node.decls {
if let Some(init) = &decl.init { let Some(init) = &decl.init else { continue };
match init.as_ref() {
// Identify destructured assignments of `test` from `Deno` match init.as_ref() {
ast::Expr::Ident(ident) => { // Identify destructured assignments of `test` from `Deno`
if ident.sym.to_string() == "Deno" { ast::Expr::Ident(ident) => {
if let ast::Pat::Object(object_pat) = &decl.name { if ident.sym.to_string() != "Deno" {
for prop in &object_pat.props { continue;
match prop { }
ast::ObjectPatProp::Assign(prop) => {
let name = prop.key.sym.to_string(); let ast::Pat::Object(object_pat) = &decl.name else {
if name == "test" { continue;
self.vars.insert(name); };
}
} for prop in &object_pat.props {
ast::ObjectPatProp::KeyValue(prop) => { match prop {
if let ast::PropName::Ident(key_ident) = &prop.key { ast::ObjectPatProp::Assign(prop) => {
if key_ident.sym.to_string() == "test" { let name = prop.key.sym.to_string();
if let ast::Pat::Ident(value_ident) = if name == "test" {
&prop.value.as_ref() self.vars.insert(name);
{ }
self.vars.insert(value_ident.id.sym.to_string()); }
} ast::ObjectPatProp::KeyValue(prop) => {
} let ast::PropName::Ident(key_ident) = &prop.key else {
} continue;
} };
_ => (),
if key_ident.sym.to_string() == "test" {
if let ast::Pat::Ident(value_ident) = &prop.value.as_ref() {
self.vars.insert(value_ident.id.sym.to_string());
} }
} }
} }
_ => (),
} }
} }
// Identify variable assignments where the init is `Deno.test`
ast::Expr::Member(member_expr) => {
if let ast::Expr::Ident(obj_ident) = member_expr.obj.as_ref() {
if obj_ident.sym.to_string() == "Deno" {
if let ast::MemberProp::Ident(prop_ident) = &member_expr.prop {
if prop_ident.sym.to_string() == "test" {
if let ast::Pat::Ident(binding_ident) = &decl.name {
self.vars.insert(binding_ident.id.sym.to_string());
}
}
}
}
}
}
_ => (),
} }
// Identify variable assignments where the init is `Deno.test`
ast::Expr::Member(member_expr) => {
let ast::Expr::Ident(obj_ident) = member_expr.obj.as_ref() else {
continue;
};
if obj_ident.sym.to_string() != "Deno" {
continue;
};
let ast::MemberProp::Ident(prop_ident) = &member_expr.prop else {
continue;
};
if prop_ident.sym.to_string() != "test" {
continue;
}
if let ast::Pat::Ident(binding_ident) = &decl.name {
self.vars.insert(binding_ident.id.sym.to_string());
}
}
_ => (),
} }
} }
} }
@ -934,6 +999,8 @@ pub mod tests {
let test_module = collect( let test_module = collect(
r#" r#"
Deno.test(async function someFunction() {}); Deno.test(async function someFunction() {});
Deno.test.ignore(function foo() {});
Deno.test.only(function bar() {});
"#, "#,
); );
@ -942,20 +1009,41 @@ pub mod tests {
&TestModule { &TestModule {
specifier: test_module.specifier.clone(), specifier: test_module.specifier.clone(),
script_version: test_module.script_version.clone(), script_version: test_module.script_version.clone(),
defs: vec![( defs: vec![
"e0f6a73647b763f82176c98a019e54200b799a32007f9859fb782aaa9e308568" (
.to_string(), "87f28e06f5ddadd90a74a93b84df2e31b9edced8301b0ad4c8fbab8d806ec99d".to_string(),
TestDefinition { TestDefinition {
id: id: "87f28e06f5ddadd90a74a93b84df2e31b9edced8301b0ad4c8fbab8d806ec99d".to_string(),
"e0f6a73647b763f82176c98a019e54200b799a32007f9859fb782aaa9e308568" name: "foo".to_string(),
.to_string(), range: Some(new_range(2, 16, 2, 22)),
name: "someFunction".to_string(), is_dynamic: false,
range: Some(new_range(1, 11, 1, 15)), parent_id: None,
is_dynamic: false, step_ids: Default::default(),
parent_id: None, },
step_ids: Default::default(), ),
} (
),] "e0f6a73647b763f82176c98a019e54200b799a32007f9859fb782aaa9e308568".to_string(),
TestDefinition {
id: "e0f6a73647b763f82176c98a019e54200b799a32007f9859fb782aaa9e308568".to_string(),
name: "someFunction".to_string(),
range: Some(new_range(1, 11, 1, 15)),
is_dynamic: false,
parent_id: None,
step_ids: Default::default(),
}
),
(
"e1bd61cdaf5e64863d3d85baffe3e43bd57cdb8dc0b5d6a9e03ade18b7f68d47".to_string(),
TestDefinition {
id: "e1bd61cdaf5e64863d3d85baffe3e43bd57cdb8dc0b5d6a9e03ade18b7f68d47".to_string(),
name: "bar".to_string(),
range: Some(new_range(3, 16, 3, 20)),
is_dynamic: false,
parent_id: None,
step_ids: Default::default(),
}
)
]
.into_iter() .into_iter()
.collect(), .collect(),
} }

View file

@ -1,4 +1,4 @@
for (let i = 0; i < 10; i++) { for (let i = 0; i < 5; i++) {
Deno.test({ Deno.test({
name: `test ${i}`, name: `test ${i}`,
ignore: true, ignore: true,
@ -7,3 +7,11 @@ for (let i = 0; i < 10; i++) {
}, },
}); });
} }
for (let i = 5; i < 10; i++) {
Deno.test.ignore({
name: `test ${i}`,
fn() {
throw new Error("unreachable");
},
});
}

View file

@ -1,7 +1,8 @@
Check [WILDCARD]/test/only.ts Check [WILDCARD]/test/only.ts
running 1 test from ./test/only.ts running 2 tests from ./test/only.ts
only ... ok ([WILDCARD]) only ... ok ([WILDCARD])
only2 ... ok ([WILDCARD])
ok | 1 passed | 0 failed | 2 filtered out ([WILDCARD]) ok | 2 passed | 0 failed | 2 filtered out ([WILDCARD])
error: Test failed because the "only" option was used error: Test failed because the "only" option was used

View file

@ -9,6 +9,11 @@ Deno.test({
fn() {}, fn() {},
}); });
Deno.test.only({
name: "only2",
fn() {},
});
Deno.test({ Deno.test({
name: "after", name: "after",
fn() {}, fn() {},

View file

@ -812,188 +812,290 @@ declare namespace Deno {
permissions?: PermissionOptions; permissions?: PermissionOptions;
} }
/** Register a test which will be run when `deno test` is used on the command export const test: DenoTest;
* line and the containing module looks like a test module.
*
* `fn` can be async if required.
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.test({
* name: "example test",
* fn() {
* assertEquals("world", "world");
* },
* });
*
* Deno.test({
* name: "example ignored test",
* ignore: Deno.build.os === "windows",
* fn() {
* // This test is ignored only on Windows machines
* },
* });
*
* Deno.test({
* name: "example async test",
* async fn() {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* }
* });
* ```
*
* @category Testing
*/
export function test(t: TestDefinition): void;
/** Register a test which will be run when `deno test` is used on the command interface DenoTest {
* line and the containing module looks like a test module. /** Register a test which will be run when `deno test` is used on the command
* * line and the containing module looks like a test module.
* `fn` can be async if required. *
* * `fn` can be async if required.
* ```ts *
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; * ```ts
* * import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
* Deno.test("My test description", () => { *
* assertEquals("hello", "hello"); * Deno.test({
* }); * name: "example test",
* * fn() {
* Deno.test("My async test description", async () => { * assertEquals("world", "world");
* const decoder = new TextDecoder("utf-8"); * },
* const data = await Deno.readFile("hello_world.txt"); * });
* assertEquals(decoder.decode(data), "Hello world"); *
* }); * Deno.test({
* ``` * name: "example ignored test",
* * ignore: Deno.build.os === "windows",
* @category Testing * fn() {
*/ * // This test is ignored only on Windows machines
export function test( * },
name: string, * });
fn: (t: TestContext) => void | Promise<void>, *
): void; * Deno.test({
* name: "example async test",
* async fn() {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* }
* });
* ```
*
* @category Testing
*/
(t: TestDefinition): void;
/** Register a test which will be run when `deno test` is used on the command /** Register a test which will be run when `deno test` is used on the command
* line and the containing module looks like a test module. * line and the containing module looks like a test module.
* *
* `fn` can be async if required. Declared function must have a name. * `fn` can be async if required.
* *
* ```ts * ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; * import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
* *
* Deno.test(function myTestName() { * Deno.test("My test description", () => {
* assertEquals("hello", "hello"); * assertEquals("hello", "hello");
* }); * });
* *
* Deno.test(async function myOtherTestName() { * Deno.test("My async test description", async () => {
* const decoder = new TextDecoder("utf-8"); * const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt"); * const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world"); * assertEquals(decoder.decode(data), "Hello world");
* }); * });
* ``` * ```
* *
* @category Testing * @category Testing
*/ */
export function test(fn: (t: TestContext) => void | Promise<void>): void; (
name: string,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Register a test which will be run when `deno test` is used on the command /** Register a test which will be run when `deno test` is used on the command
* line and the containing module looks like a test module. * line and the containing module looks like a test module.
* *
* `fn` can be async if required. * `fn` can be async if required. Declared function must have a name.
* *
* ```ts * ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts"; * import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
* *
* Deno.test("My test description", { permissions: { read: true } }, (): void => { * Deno.test(function myTestName() {
* assertEquals("hello", "hello"); * assertEquals("hello", "hello");
* }); * });
* *
* Deno.test("My async test description", { permissions: { read: false } }, async (): Promise<void> => { * Deno.test(async function myOtherTestName() {
* const decoder = new TextDecoder("utf-8"); * const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt"); * const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world"); * assertEquals(decoder.decode(data), "Hello world");
* }); * });
* ``` * ```
* *
* @category Testing * @category Testing
*/ */
export function test( (fn: (t: TestContext) => void | Promise<void>): void;
name: string,
options: Omit<TestDefinition, "fn" | "name">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Register a test which will be run when `deno test` is used on the command /** Register a test which will be run when `deno test` is used on the command
* line and the containing module looks like a test module. * line and the containing module looks like a test module.
* *
* `fn` can be async if required. * `fn` can be async if required.
* *
* ```ts * ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; * import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
* *
* Deno.test( * Deno.test("My test description", { permissions: { read: true } }, (): void => {
* { * assertEquals("hello", "hello");
* name: "My test description", * });
* permissions: { read: true }, *
* }, * Deno.test("My async test description", { permissions: { read: false } }, async (): Promise<void> => {
* () => { * const decoder = new TextDecoder("utf-8");
* assertEquals("hello", "hello"); * const data = await Deno.readFile("hello_world.txt");
* }, * assertEquals(decoder.decode(data), "Hello world");
* ); * });
* * ```
* Deno.test( *
* { * @category Testing
* name: "My async test description", */
* permissions: { read: false }, (
* }, name: string,
* async () => { options: Omit<TestDefinition, "fn" | "name">,
* const decoder = new TextDecoder("utf-8"); fn: (t: TestContext) => void | Promise<void>,
* const data = await Deno.readFile("hello_world.txt"); ): void;
* assertEquals(decoder.decode(data), "Hello world");
* },
* );
* ```
*
* @category Testing
*/
export function test(
options: Omit<TestDefinition, "fn">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Register a test which will be run when `deno test` is used on the command /** Register a test which will be run when `deno test` is used on the command
* line and the containing module looks like a test module. * line and the containing module looks like a test module.
* *
* `fn` can be async if required. Declared function must have a name. * `fn` can be async if required.
* *
* ```ts * ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; * import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
* *
* Deno.test( * Deno.test(
* { permissions: { read: true } }, * {
* function myTestName() { * name: "My test description",
* assertEquals("hello", "hello"); * permissions: { read: true },
* }, * },
* ); * () => {
* * assertEquals("hello", "hello");
* Deno.test( * },
* { permissions: { read: false } }, * );
* async function myOtherTestName() { *
* const decoder = new TextDecoder("utf-8"); * Deno.test(
* const data = await Deno.readFile("hello_world.txt"); * {
* assertEquals(decoder.decode(data), "Hello world"); * name: "My async test description",
* }, * permissions: { read: false },
* ); * },
* ``` * async () => {
* * const decoder = new TextDecoder("utf-8");
* @category Testing * const data = await Deno.readFile("hello_world.txt");
*/ * assertEquals(decoder.decode(data), "Hello world");
export function test( * },
options: Omit<TestDefinition, "fn" | "name">, * );
fn: (t: TestContext) => void | Promise<void>, * ```
): void; *
* @category Testing
*/
(
options: Omit<TestDefinition, "fn" | "name">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Register a test which will be run when `deno test` is used on the command
* line and the containing module looks like a test module.
*
* `fn` can be async if required. Declared function must have a name.
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.test(
* { permissions: { read: true } },
* function myTestName() {
* assertEquals("hello", "hello");
* },
* );
*
* Deno.test(
* { permissions: { read: false } },
* async function myOtherTestName() {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* },
* );
* ```
*
* @category Testing
*/
(
options: Omit<TestDefinition, "fn">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(t: Omit<TestDefinition, "ignore">): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(
name: string,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(fn: (t: TestContext) => void | Promise<void>): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(
name: string,
options: Omit<TestDefinition, "fn" | "name" | "ignore">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(
options: Omit<TestDefinition, "fn" | "name" | "ignore">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for ignoring a particular test case.
*
* @category Testing
*/
ignore(
options: Omit<TestDefinition, "fn" | "ignore">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(t: Omit<TestDefinition, "only">): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(
name: string,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(fn: (t: TestContext) => void | Promise<void>): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(
name: string,
options: Omit<TestDefinition, "fn" | "name" | "only">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(
options: Omit<TestDefinition, "fn" | "name" | "only">,
fn: (t: TestContext) => void | Promise<void>,
): void;
/** Shorthand property for focusing a particular test case.
*
* @category Testing
*/
only(
options: Omit<TestDefinition, "fn" | "only">,
fn: (t: TestContext) => void | Promise<void>,
): void;
}
/** /**
* Context that is passed to a benchmarked function. The instance is shared * Context that is passed to a benchmarked function. The instance is shared