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:
parent
9befa566ec
commit
147c845c95
6 changed files with 538 additions and 311 deletions
|
@ -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.
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
|
10
cli/tests/testdata/test/ignore.ts
vendored
10
cli/tests/testdata/test/ignore.ts
vendored
|
@ -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");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
5
cli/tests/testdata/test/only.out
vendored
5
cli/tests/testdata/test/only.out
vendored
|
@ -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
|
||||||
|
|
5
cli/tests/testdata/test/only.ts
vendored
5
cli/tests/testdata/test/only.ts
vendored
|
@ -9,6 +9,11 @@ Deno.test({
|
||||||
fn() {},
|
fn() {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test.only({
|
||||||
|
name: "only2",
|
||||||
|
fn() {},
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
name: "after",
|
name: "after",
|
||||||
fn() {},
|
fn() {},
|
||||||
|
|
456
cli/tsc/dts/lib.deno.ns.d.ts
vendored
456
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue