From 221dd7d12f8428ddd2e89a22cb28a118cf58ca20 Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 10 Jul 2024 17:08:02 -0400 Subject: [PATCH 1/3] feat(linter): generate schemas for rules (with documentation) --- crates/oxc_linter/src/config/mod.rs | 1 + crates/oxc_linter/src/config/rules.rs | 25 +- crates/oxc_linter/src/config/schema.rs | 64 + .../oxc_macros/src/declare_all_lint_rules.rs | 10 + crates/oxc_macros/src/declare_oxc_lint.rs | 59 +- justfile | 4 + npm/oxlint/configuration_schema.json | 9733 ++++++++++++++++- tasks/website/src/linter/json_schema.rs | 9 +- 8 files changed, 9801 insertions(+), 104 deletions(-) create mode 100644 crates/oxc_linter/src/config/schema.rs diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index db9580fee54b7..ffff67f276b12 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -1,6 +1,7 @@ mod env; mod globals; mod rules; +mod schema; mod settings; use std::path::Path; diff --git a/crates/oxc_linter/src/config/rules.rs b/crates/oxc_linter/src/config/rules.rs index d70da6f072810..8696f1fa60927 100644 --- a/crates/oxc_linter/src/config/rules.rs +++ b/crates/oxc_linter/src/config/rules.rs @@ -1,8 +1,6 @@ -use std::{borrow::Cow, fmt, ops::Deref}; +use std::{fmt, ops::Deref}; use oxc_diagnostics::{Error, OxcDiagnostic}; -use rustc_hash::FxHashMap; -use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; use serde::{ de::{self, Deserializer, Visitor}, Deserialize, @@ -25,27 +23,6 @@ pub struct ESLintRule { pub config: Option, } -impl JsonSchema for OxlintRules { - fn schema_name() -> String { - "OxlintRules".to_owned() - } - - fn schema_id() -> Cow<'static, str> { - Cow::Borrowed("OxlintRules") - } - - fn json_schema(gen: &mut SchemaGenerator) -> Schema { - #[allow(unused)] - #[derive(Debug, Clone, JsonSchema)] - #[serde(untagged)] - enum DummyRule { - Toggle(AllowWarnDeny), - ToggleAndConfig(Vec), - } - gen.subschema_for::>() - } -} - // Manually implement Deserialize because the type is a bit complex... // - Handle single value form and array form // - SeverityConf into AllowWarnDeny diff --git a/crates/oxc_linter/src/config/schema.rs b/crates/oxc_linter/src/config/schema.rs new file mode 100644 index 0000000000000..e14311208d8e6 --- /dev/null +++ b/crates/oxc_linter/src/config/schema.rs @@ -0,0 +1,64 @@ +use crate::{rules::RULES, AllowWarnDeny}; + +use super::OxlintRules; +use schemars::{ + gen::SchemaGenerator, + schema::{Schema, SchemaObject}, + JsonSchema, +}; +// use crate::RuleMeta; +use std::borrow::Cow; + +impl JsonSchema for OxlintRules { + fn schema_name() -> String { + "OxlintRules".to_owned() + } + + fn schema_id() -> Cow<'static, str> { + Cow::Borrowed("OxlintRules") + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let mut schema: SchemaObject = SchemaObject::default(); + schema.object().properties.extend(RULES.iter().map(|rule| { + let rule_config_schema = rule.schema(gen); + let mut rule_schema = rule_property_schema(gen, rule_config_schema); + + let docs = rule.documentation(); + rule_schema.metadata().description = docs.map(Into::into); + if let Some(docs) = docs { + // markdownDescription is a non-standard property that VSCode + // uses in intellisense. It lets us show the rule's + // documentation with markdown formatting. + rule_schema + .extensions + .insert("markdownDescription".into(), docs.to_string().into()); + } + + // Don't scope eslint rules, only plugins. + let scoped_name = if rule.plugin_name() == "eslint" { + rule.name().into() + } else { + rule.plugin_name().to_string() + "/" + rule.name() + }; + + (scoped_name, Schema::Object(rule_schema)) + })); + + schema.into() + } +} + +fn rule_property_schema(gen: &mut SchemaGenerator, config_schema: Schema) -> SchemaObject { + let any_list = gen.subschema_for::>().into_object(); + let toggle_schema = gen.subschema_for::().into_object(); + let mut toggle_and_config = SchemaObject::default(); + toggle_and_config.array().items = Some(Schema::Object(toggle_schema.clone()).into()); + toggle_and_config.array().additional_items = Some(Box::new(config_schema)); + + let mut schema = SchemaObject::default(); + schema.subschemas().any_of = + Some(vec![toggle_schema.into(), toggle_and_config.into(), any_list.into()]); + + schema +} diff --git a/crates/oxc_macros/src/declare_all_lint_rules.rs b/crates/oxc_macros/src/declare_all_lint_rules.rs index 5f1c4ff7a0913..596e000b6b5c2 100644 --- a/crates/oxc_macros/src/declare_all_lint_rules.rs +++ b/crates/oxc_macros/src/declare_all_lint_rules.rs @@ -87,6 +87,16 @@ pub fn declare_all_lint_rules(metadata: AllLintRulesMeta) -> TokenStream { } } + /// Gets a [`schemars::schema::Schema`] for the rule's + /// configuration. This will be [`None`] for rules that don't + /// specify a config schema. + pub fn schema(&self, gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + match self { + // #(Self::#struct_names(_) => #struct_names::json_schema(gen)),* + #(Self::#struct_names(_) => gen.subschema_for::<#struct_names>()),* + } + } + pub fn plugin_name(&self) -> &str { match self { #(Self::#struct_names(_) => #plugin_names),* diff --git a/crates/oxc_macros/src/declare_oxc_lint.rs b/crates/oxc_macros/src/declare_oxc_lint.rs index e0c735ba6926e..a8e1cb3b6fa33 100644 --- a/crates/oxc_macros/src/declare_oxc_lint.rs +++ b/crates/oxc_macros/src/declare_oxc_lint.rs @@ -9,6 +9,10 @@ use syn::{ pub struct LintRuleMeta { name: Ident, category: Ident, + /// Struct implementing [`JsonSchema`] that describes the rule's config. + /// + /// Note: Intentionally does not allow `Self` + schema: Option, documentation: String, pub used_in_test: bool, } @@ -32,15 +36,23 @@ impl Parse for LintRuleMeta { input.parse::()?; let category = input.parse()?; + let schema = if input.peek(Token!(,)) { + input.parse::()?; + // allow trailing commas + input.peek(Ident).then(|| input.parse()).transpose()? + } else { + None + }; + // Ignore the rest input.parse::()?; - Ok(Self { name: struct_name, category, documentation, used_in_test: false }) + Ok(Self { name: struct_name, category, schema, documentation, used_in_test: false }) } } pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream { - let LintRuleMeta { name, category, documentation, used_in_test } = metadata; + let LintRuleMeta { name, category, schema, documentation, used_in_test } = metadata; let canonical_name = name.to_string().to_case(Case::Kebab); let category = match category.to_string().as_str() { "correctness" => quote! { RuleCategory::Correctness }, @@ -59,6 +71,20 @@ pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream { Some(quote! { use crate::rule::{RuleCategory, RuleMeta}; }) }; + let schema_impl = if let Some(schema) = schema { + quote! { + gen.subschema_for::<#schema>() + } + } else { + quote! { + { + let mut obj = SchemaObject::default(); + obj.object().additional_properties = Some(Box::new(Schema::Bool(true))); + obj.into() + }; + } + }; + let output = quote! { #import_statement @@ -71,6 +97,35 @@ pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream { Some(#documentation) } } + + impl schemars::JsonSchema for #name { + #[inline] + fn schema_name() -> String { + Self::NAME.to_string() + } + + #[inline] + fn schema_id() -> std::borrow::Cow<'static, str> { + std::borrow::Cow::Borrowed(#canonical_name) + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + use schemars::schema::{Schema, SchemaObject}; + + let mut schema: Schema = #schema_impl; + + let schema = match schema { + Schema::Object(mut obj) => { + let meta = obj.metadata(); + meta.title = Some("Config for ".to_string() + Self::NAME); + Schema::Object(obj) + }, + s => s + }; + + schema + } + } }; TokenStream::from(output) diff --git a/justfile b/justfile index a58cf069079ba..d9d4700d25b9a 100755 --- a/justfile +++ b/justfile @@ -148,6 +148,10 @@ clone-submodule dir url sha: git clone --depth=1 {{url}} {{dir}} || true cd {{dir}} && git fetch origin {{sha}} && git reset --hard {{sha}} +# Re-genenerate the JSON schema for oxlint's config. +linter-schema: + cargo run -p website -- linter-schema-json > npm/oxlint/configuration_schema.json + website path: cargo run -p website -- linter-rules > {{path}}/src/docs/guide/usage/linter/generated-rules.md cargo run -p website -- linter-cli > {{path}}/src/docs/guide/usage/linter/generated-cli.md diff --git a/npm/oxlint/configuration_schema.json b/npm/oxlint/configuration_schema.json index 93e15ac541481..e07baec6f2a2c 100644 --- a/npm/oxlint/configuration_schema.json +++ b/npm/oxlint/configuration_schema.json @@ -85,17 +85,6 @@ } ] }, - "DummyRule": { - "anyOf": [ - { - "$ref": "#/definitions/AllowWarnDeny" - }, - { - "type": "array", - "items": true - } - ] - }, "GlobalValue": { "type": "string", "enum": [ @@ -204,81 +193,9679 @@ } }, "OxlintRules": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/DummyRule" - } - }, - "OxlintSettings": { - "description": "Shared settings for plugins", - "type": "object", "properties": { - "jsdoc": { - "$ref": "#/definitions/JSDocPluginSettings" + "array-callback-return": { + "description": "### What it does\nEnforce return statements in callbacks of array methods\n\n### Why is this bad?\nArray has several methods for filtering, mapping, and folding.\nIf we forget to write return statement in a callback of those, it’s probably a mistake.\nIf you don’t want to use a return or don’t need the returned results,\nconsider using .forEach instead.\n\n### Example\n```javascript\nlet foo = [1, 2, 3, 4];\nfoo.map((a) => {\n console.log(a)\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/array-callback-return" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforce return statements in callbacks of array methods\n\n### Why is this bad?\nArray has several methods for filtering, mapping, and folding.\nIf we forget to write return statement in a callback of those, it’s probably a mistake.\nIf you don’t want to use a return or don’t need the returned results,\nconsider using .forEach instead.\n\n### Example\n```javascript\nlet foo = [1, 2, 3, 4];\nfoo.map((a) => {\n console.log(a)\n});\n```\n" }, - "jsx-a11y": { - "$ref": "#/definitions/JSXA11yPluginSettings" + "constructor-super": { + "description": "### What it does\nRequire 'super()' calls in constructors.\n\n### Why is this bad?\n\n\n### Example\n```javascript\nclass A extends B {\n constructor() {}\n}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/constructor-super" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequire 'super()' calls in constructors.\n\n### Why is this bad?\n\n\n### Example\n```javascript\nclass A extends B {\n constructor() {}\n}\n```\n" }, - "next": { - "$ref": "#/definitions/NextPluginSettings" + "default-case": { + "description": "### What it does\n\nRequire default cases in switch statements\n\n### Why is this bad?\n\nSome code conventions require that all switch statements have a default case, even if the\ndefault case is empty.\n\n### Example\n```javascript\nswitch (foo) {\n case 1:\n break;\n}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/default-case" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nRequire default cases in switch statements\n\n### Why is this bad?\n\nSome code conventions require that all switch statements have a default case, even if the\ndefault case is empty.\n\n### Example\n```javascript\nswitch (foo) {\n case 1:\n break;\n}\n```\n" }, - "react": { - "$ref": "#/definitions/ReactPluginSettings" - } - } - }, - "ReactPluginSettings": { - "type": "object", - "properties": { - "formComponents": { - "type": "array", - "items": { - "$ref": "#/definitions/CustomComponent" - } + "default-case-last": { + "description": "### What it does\nEnforce default clauses in switch statements to be last\n\n### Why is this bad?\nA switch statement can optionally have a default clause.\nIf present, it’s usually the last clause, but it doesn’t need to be. It is also allowed to put the default clause before all case clauses, or anywhere between. The behavior is mostly the same as if it was the last clause. The default block will be still executed only if there is no match in the case clauses (including those defined after the default), but there is also the ability to “fall through” from the default clause to the following clause in the list. However, such flow is not common and it would be confusing to the readers.\nEven if there is no “fall through” logic, it’s still unexpected to see the default clause before or between the case clauses. By convention, it is expected to be the last clause.\nIf a switch statement should have a default clause, it’s considered a best practice to define it as the last clause.\n\n### Example\n```javascript\nswitch (foo) {\n default:\n bar();\n break;\n case \"a\":\n baz();\n break;\n}\n\nswitch (foo) {\n case 1:\n bar();\n break;\n default:\n baz();\n break;\n case 2:\n qux();\n break;\n}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/default-case-last" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforce default clauses in switch statements to be last\n\n### Why is this bad?\nA switch statement can optionally have a default clause.\nIf present, it’s usually the last clause, but it doesn’t need to be. It is also allowed to put the default clause before all case clauses, or anywhere between. The behavior is mostly the same as if it was the last clause. The default block will be still executed only if there is no match in the case clauses (including those defined after the default), but there is also the ability to “fall through” from the default clause to the following clause in the list. However, such flow is not common and it would be confusing to the readers.\nEven if there is no “fall through” logic, it’s still unexpected to see the default clause before or between the case clauses. By convention, it is expected to be the last clause.\nIf a switch statement should have a default clause, it’s considered a best practice to define it as the last clause.\n\n### Example\n```javascript\nswitch (foo) {\n default:\n bar();\n break;\n case \"a\":\n baz();\n break;\n}\n\nswitch (foo) {\n case 1:\n bar();\n break;\n default:\n baz();\n break;\n case 2:\n qux();\n break;\n}\n```\n" }, - "linkComponents": { - "type": "array", - "items": { - "$ref": "#/definitions/CustomComponent" - } - } - } - }, - "TagNamePreference": { - "anyOf": [ - { - "type": "string" + "default-param-last": { + "description": "### What it does\nEnforce default parameters to be last\n\n### Why is this bad?\nPutting default parameter at last allows function calls to omit optional tail arguments.\n\n### Example\n```javascript\n// Correct: optional argument can be omitted\nfunction createUser(id, isAdmin = false) {}\ncreateUser(\"tabby\")\n\n// Incorrect: optional argument can **not** be omitted\nfunction createUser(isAdmin = false, id) {}\ncreateUser(undefined, \"tabby\")\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/default-param-last" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforce default parameters to be last\n\n### Why is this bad?\nPutting default parameter at last allows function calls to omit optional tail arguments.\n\n### Example\n```javascript\n// Correct: optional argument can be omitted\nfunction createUser(id, isAdmin = false) {}\ncreateUser(\"tabby\")\n\n// Incorrect: optional argument can **not** be omitted\nfunction createUser(isAdmin = false, id) {}\ncreateUser(undefined, \"tabby\")\n```\n" }, - { - "type": "object", - "required": [ - "message", - "replacement" + "eqeqeq": { + "description": "### What it does\nRequires the use of the === and !== operators\n\n### Why is this bad?\nUsing non-strict equality operators leads to hard to track bugs due to type coercion.\n\n### Example\n```javascript\nlet a = []\nlet b = false\na == b\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/eqeqeq" + } + }, + { + "type": "array", + "items": true + } ], - "properties": { - "message": { - "type": "string" + "markdownDescription": "### What it does\nRequires the use of the === and !== operators\n\n### Why is this bad?\nUsing non-strict equality operators leads to hard to track bugs due to type coercion.\n\n### Example\n```javascript\nlet a = []\nlet b = false\na == b\n```\n" + }, + "for-direction": { + "description": "### What it does\nDisallow \"for\" loop update causing the counter to move in the wrong direction.\n\n### Why is this bad?\nA for loop that is known to run infinitely or never run is considered a bug.\n\n### Example\n```javascript\nfor (var i = 0; i < 10; i--) {}\n\nfor (var = 10; i >= 0; i++) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" }, - "replacement": { - "type": "string" + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/for-direction" + } + }, + { + "type": "array", + "items": true } - } + ], + "markdownDescription": "### What it does\nDisallow \"for\" loop update causing the counter to move in the wrong direction.\n\n### Why is this bad?\nA for loop that is known to run infinitely or never run is considered a bug.\n\n### Example\n```javascript\nfor (var i = 0; i < 10; i--) {}\n\nfor (var = 10; i >= 0; i++) {}\n```\n" }, - { - "type": "object", - "required": [ - "message" + "getter-return": { + "description": "### What it does\nRequires all getters to have a return statement\n\n### Why is this bad?\nGetters should always return a value. If they don't, it's probably a mistake.\n\n### Example\n```javascript\nclass Person{\n get name(){\n // no return\n }\n}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/getter-return" + } + }, + { + "type": "array", + "items": true + } ], - "properties": { - "message": { - "type": "string" + "markdownDescription": "### What it does\nRequires all getters to have a return statement\n\n### Why is this bad?\nGetters should always return a value. If they don't, it's probably a mistake.\n\n### Example\n```javascript\nclass Person{\n get name(){\n // no return\n }\n}\n```\n" + }, + "guard-for-in": { + "description": "### What it does\nThis rule is aimed at preventing unexpected behavior that could arise from using a for in loop without filtering the results in the loop. As such, it will warn when for in loops do not filter their results with an if statement.\n\n### Why is this bad?\n\n\n### Example\n```javascript\nfor (key in foo) {\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/guard-for-in" + } + }, + { + "type": "array", + "items": true } - } + ], + "markdownDescription": "### What it does\nThis rule is aimed at preventing unexpected behavior that could arise from using a for in loop without filtering the results in the loop. As such, it will warn when for in loops do not filter their results with an if statement.\n\n### Why is this bad?\n\n\n### Example\n```javascript\nfor (key in foo) {\n```\n" }, - { - "type": "boolean" - } - ] + "import/default": { + "description": "### What it does\n\nIf a default import is requested, this rule will report if there is no default export in the imported module.\n\n### Example\n\n```javascript\n// ./bar.js\nexport function bar() { return null }\n\n// ./foo.js\nimport bar from './bar' // no default export found in ./bar\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/default" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nIf a default import is requested, this rule will report if there is no default export in the imported module.\n\n### Example\n\n```javascript\n// ./bar.js\nexport function bar() { return null }\n\n// ./foo.js\nimport bar from './bar' // no default export found in ./bar\n```\n" + }, + "import/export": { + "description": "### What it does\nReports funny business with exports, like repeated exports of names or defaults.\n\n### Example\n```javascript\nlet foo;\nexport { foo }; // Multiple exports of name 'foo'.\nexport * from \"./export-all\" // export-all.js also export foo\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/export" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nReports funny business with exports, like repeated exports of names or defaults.\n\n### Example\n```javascript\nlet foo;\nexport { foo }; // Multiple exports of name 'foo'.\nexport * from \"./export-all\" // export-all.js also export foo\n```\n" + }, + "import/max-dependencies": { + "description": "### What it does\n\nForbid modules to have too many dependencies (import or require statements).\n\n### Why is this bad?\n\nThis is a useful rule because a module with too many dependencies is a code smell, and\nusually indicates the module is doing too much and/or should be broken up into smaller\nmodules.\n\n### Example\n\nGiven `{\"max\": 2}`\n```javascript\nimport a from './a';\nimport b from './b';\nimport c from './c';\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/max-dependencies" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nForbid modules to have too many dependencies (import or require statements).\n\n### Why is this bad?\n\nThis is a useful rule because a module with too many dependencies is a code smell, and\nusually indicates the module is doing too much and/or should be broken up into smaller\nmodules.\n\n### Example\n\nGiven `{\"max\": 2}`\n```javascript\nimport a from './a';\nimport b from './b';\nimport c from './c';\n```\n" + }, + "import/named": { + "description": "### What it does\n\n### Why is this bad?\n\n### Example\n```javascript\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/named" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\n### Why is this bad?\n\n### Example\n```javascript\n```\n" + }, + "import/namespace": { + "description": "### What it does\nEnforces names exist at the time they are dereferenced, when imported as a full namespace (i.e. import * as foo from './foo'; foo.bar(); will report if bar is not exported by ./foo.).\nWill report at the import declaration if there are no exported names found.\nAlso, will report for computed references (i.e. foo[\"bar\"]()).\nReports on assignment to a member of an imported namespace.\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/namespace" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforces names exist at the time they are dereferenced, when imported as a full namespace (i.e. import * as foo from './foo'; foo.bar(); will report if bar is not exported by ./foo.).\nWill report at the import declaration if there are no exported names found.\nAlso, will report for computed references (i.e. foo[\"bar\"]()).\nReports on assignment to a member of an imported namespace.\n" + }, + "import/no-amd": { + "description": "### What it does\n\nForbid AMD `require` and `define` calls.\n\n### Example\n\n```javascript\n// fail\nrequire([a, b], function() {} );\n// pass\nrequire('../name');\nrequire(`../name`);\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-amd" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nForbid AMD `require` and `define` calls.\n\n### Example\n\n```javascript\n// fail\nrequire([a, b], function() {} );\n// pass\nrequire('../name');\nrequire(`../name`);\n```\n" + }, + "import/no-cycle": { + "description": "### What it does\n\nEnsures that there is no resolvable path back to this module via its dependencies.\n\nThis includes cycles of depth 1 (imported module imports me) to \"∞\" (or Infinity),\nif the maxDepth option is not set.\n\n### Why is this bad?\n\nDependency cycles lead to confusing architectures where bugs become hard to find.\n\nIt is common to import an `undefined` value that is caused by a cyclic dependency.\n\n### Example\n```javascript\n// dep-b.js\nimport './dep-a.js'\nexport function b() { /* ... */ }\n```\n\n```javascript\n// dep-a.js\nimport { b } from './dep-b.js' // reported: Dependency cycle detected.\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-cycle" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnsures that there is no resolvable path back to this module via its dependencies.\n\nThis includes cycles of depth 1 (imported module imports me) to \"∞\" (or Infinity),\nif the maxDepth option is not set.\n\n### Why is this bad?\n\nDependency cycles lead to confusing architectures where bugs become hard to find.\n\nIt is common to import an `undefined` value that is caused by a cyclic dependency.\n\n### Example\n```javascript\n// dep-b.js\nimport './dep-a.js'\nexport function b() { /* ... */ }\n```\n\n```javascript\n// dep-a.js\nimport { b } from './dep-b.js' // reported: Dependency cycle detected.\n```\n" + }, + "import/no-default-export": { + "description": "### What it does\n\nForbid a module to have a default exports. This help your editor to provide better auto imports.\n\n### Examples\n\n```javascript\n// bad1.js\n\n// There is a default export.\nexport const foo = 'foo';\nconst bar = 'bar';\nexport default 'bar';\n```\n\n```javascript\n// bad2.js\n\n// There is a default export.\nconst foo = 'foo';\nexport { foo as default }\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-default-export" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nForbid a module to have a default exports. This help your editor to provide better auto imports.\n\n### Examples\n\n```javascript\n// bad1.js\n\n// There is a default export.\nexport const foo = 'foo';\nconst bar = 'bar';\nexport default 'bar';\n```\n\n```javascript\n// bad2.js\n\n// There is a default export.\nconst foo = 'foo';\nexport { foo as default }\n```\n\n" + }, + "import/no-duplicates": { + "description": "### What it does\n\nReports if a resolved path is imported more than once.\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-duplicates" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nReports if a resolved path is imported more than once.\n" + }, + "import/no-named-as-default": { + "description": "### What it does\n\nReports use of an exported name as the locally imported name of a default export.\n\n### Example\n\n```javascript\n// foo.js\nexport default 'foo';\nexport const bar = 'baz';\n```\nValid:\n```javascript\nimport foo from './foo.js';\n```\nInvalid:\n```javascript\n// using exported name 'bar' as identifier for default export.\nimport bar from './foo.js';\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-named-as-default" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nReports use of an exported name as the locally imported name of a default export.\n\n### Example\n\n```javascript\n// foo.js\nexport default 'foo';\nexport const bar = 'baz';\n```\nValid:\n```javascript\nimport foo from './foo.js';\n```\nInvalid:\n```javascript\n// using exported name 'bar' as identifier for default export.\nimport bar from './foo.js';\n```\n" + }, + "import/no-named-as-default-member": { + "description": "### What it does\n\nReports use of an exported name as a property on the default export.\n\n### Example\n\n```javascript\n// ./bar.js\nexport function bar() { return null }\nexport default () => { return 1 }\n\n// ./foo.js\nimport bar from './bar'\nconst bar = foo.bar // trying to access named export via default\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-named-as-default-member" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nReports use of an exported name as a property on the default export.\n\n### Example\n\n```javascript\n// ./bar.js\nexport function bar() { return null }\nexport default () => { return 1 }\n\n// ./foo.js\nimport bar from './bar'\nconst bar = foo.bar // trying to access named export via default\n```\n" + }, + "import/no-self-import": { + "description": "### What it does\n\nForbid a module from importing itself. This can sometimes happen during refactoring.\n\n### Example\n\n```javascript\n// foo.js\nimport foo from './foo.js'\nconst foo = require('./foo')\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-self-import" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nForbid a module from importing itself. This can sometimes happen during refactoring.\n\n### Example\n\n```javascript\n// foo.js\nimport foo from './foo.js'\nconst foo = require('./foo')\n```\n" + }, + "jest/consistent-test-it": { + "description": "### What it does\n\nJest allows you to choose how you want to define your tests, using the `it` or\nthe `test` keywords, with multiple permutations for each:\n\n- **it:** `it`, `xit`, `fit`, `it.only`, `it.skip`.\n- **test:** `test`, `xtest`, `test.only`, `test.skip`.\n\n### Example\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"test\"}]*/\ntest('foo'); // valid\ntest.only('foo'); // valid\n\nit('foo'); // invalid\nit.only('foo'); // invalid\n```\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"it\"}]*/\nit('foo'); // valid\nit.only('foo'); // valid\ntest('foo'); // invalid\ntest.only('foo'); // invalid\n```\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"it\", \"withinDescribe\": \"test\"}]*/\nit('foo'); // valid\ndescribe('foo', function () {\n test('bar'); // valid\n});\n\ntest('foo'); // invalid\ndescribe('foo', function () {\n it('bar'); // invalid\n});\n```\n\n#### Options\n\nThis rule can be configured as follows\n```json5\n{\n type: 'object',\n properties: {\n fn: {\n enum: ['it', 'test'],\n },\n withinDescribe: {\n enum: ['it', 'test'],\n },\n },\n additionalProperties: false,\n}\n```\n\n##### fn\nDecides whether to use `test` or `it`.\n\n##### withinDescribe\nDecides whether to use `test` or `it` within a `describe` scope.\n\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/consistent-test-it\": \"error\"\n }\n}\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/consistent-test-it" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nJest allows you to choose how you want to define your tests, using the `it` or\nthe `test` keywords, with multiple permutations for each:\n\n- **it:** `it`, `xit`, `fit`, `it.only`, `it.skip`.\n- **test:** `test`, `xtest`, `test.only`, `test.skip`.\n\n### Example\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"test\"}]*/\ntest('foo'); // valid\ntest.only('foo'); // valid\n\nit('foo'); // invalid\nit.only('foo'); // invalid\n```\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"it\"}]*/\nit('foo'); // valid\nit.only('foo'); // valid\ntest('foo'); // invalid\ntest.only('foo'); // invalid\n```\n\n```javascript\n/*eslint jest/consistent-test-it: [\"error\", {\"fn\": \"it\", \"withinDescribe\": \"test\"}]*/\nit('foo'); // valid\ndescribe('foo', function () {\n test('bar'); // valid\n});\n\ntest('foo'); // invalid\ndescribe('foo', function () {\n it('bar'); // invalid\n});\n```\n\n#### Options\n\nThis rule can be configured as follows\n```json5\n{\n type: 'object',\n properties: {\n fn: {\n enum: ['it', 'test'],\n },\n withinDescribe: {\n enum: ['it', 'test'],\n },\n },\n additionalProperties: false,\n}\n```\n\n##### fn\nDecides whether to use `test` or `it`.\n\n##### withinDescribe\nDecides whether to use `test` or `it` within a `describe` scope.\n\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/consistent-test-it\": \"error\"\n }\n}\n" + }, + "jest/expect-expect": { + "description": "### What it does\n\nThis rule triggers when there is no call made to `expect` in a test, ensure that there is at least one `expect` call made in a test.\n\n### Why is this bad?\n\n People may forget to add assertions.\n\n### Example\n\n```javascript\nit('should be a test', () => {\n console.log('no assertion');\n});\ntest('should assert something', () => {});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/expect-expect" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule triggers when there is no call made to `expect` in a test, ensure that there is at least one `expect` call made in a test.\n\n### Why is this bad?\n\n People may forget to add assertions.\n\n### Example\n\n```javascript\nit('should be a test', () => {\n console.log('no assertion');\n});\ntest('should assert something', () => {});\n```\n" + }, + "jest/max-expects": { + "description": "### What it does\nAs more assertions are made, there is a possible tendency for the test to be\nmore likely to mix multiple objectives. To avoid this, this rule reports when\nthe maximum number of assertions is exceeded.\n\n### Why is this bad?\n\nThis rule enforces a maximum number of `expect()` calls.\nThe following patterns are considered warnings (with the default option of `{ \"max\": 5 } `):\n\n### Example\n\n```javascript\ntest('should not pass', () => {\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n});\n\nit('should not pass', () => {\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/max-expects" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nAs more assertions are made, there is a possible tendency for the test to be\nmore likely to mix multiple objectives. To avoid this, this rule reports when\nthe maximum number of assertions is exceeded.\n\n### Why is this bad?\n\nThis rule enforces a maximum number of `expect()` calls.\nThe following patterns are considered warnings (with the default option of `{ \"max\": 5 } `):\n\n### Example\n\n```javascript\ntest('should not pass', () => {\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n});\n\nit('should not pass', () => {\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n expect(true).toBeDefined();\n});\n```\n" + }, + "jest/max-nested-describe": { + "description": "### What it does\n\nThis rule enforces a maximum depth to nested `describe()` calls to improve code\nclarity in your tests.\n\nThe following patterns are considered warnings (with the default option of\n`{ \"max\": 5 } `):\n\n### Example\n\n```javascript\n\n// invalid\ndescribe('foo', () => {\n describe('bar', () => {\n describe('baz', () => {\n describe('qux', () => {\n describe('quxx', () => {\n describe('too many', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n });\n});\n\ndescribe('foo', function () {\n describe('bar', function () {\n describe('baz', function () {\n describe('qux', function () {\n describe('quxx', function () {\n describe('too many', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n });\n});\n\n// valid\ndescribe('foo', () => {\n describe('bar', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n describe('qux', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n});\n\ndescribe('foo2', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n});\n\ndescribe('foo', function () {\n describe('bar', function () {\n describe('baz', function () {\n describe('qux', function () {\n describe('this is the limit', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n});\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/max-nested-describe" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule enforces a maximum depth to nested `describe()` calls to improve code\nclarity in your tests.\n\nThe following patterns are considered warnings (with the default option of\n`{ \"max\": 5 } `):\n\n### Example\n\n```javascript\n\n// invalid\ndescribe('foo', () => {\n describe('bar', () => {\n describe('baz', () => {\n describe('qux', () => {\n describe('quxx', () => {\n describe('too many', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n });\n});\n\ndescribe('foo', function () {\n describe('bar', function () {\n describe('baz', function () {\n describe('qux', function () {\n describe('quxx', function () {\n describe('too many', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n });\n});\n\n// valid\ndescribe('foo', () => {\n describe('bar', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n describe('qux', () => {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n});\n\ndescribe('foo2', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n});\n\ndescribe('foo', function () {\n describe('bar', function () {\n describe('baz', function () {\n describe('qux', function () {\n describe('this is the limit', function () {\n it('should get something', () => {\n expect(getSomething()).toBe('Something');\n });\n });\n });\n });\n });\n});\n```\n\n" + }, + "jest/no-alias-methods": { + "description": "### What it does\n\nThis rule ensures that only the canonical name as used in the Jest documentation is used in the code.\n\n### Why is this bad?\n\nThese aliases are going to be removed in the next major version of Jest - see [jestjs/jest#13164](https://github.com/jestjs/jest/issues/13164) for more.\nThis rule will makes it easier to search for all occurrences of the method within code, and it ensures consistency among the method names used.\n\n### Example\n```javascript\nexpect(a).toBeCalled();\nexpect(a).toBeCalledTimes();\nexpect(a).toBeCalledWith();\nexpect(a).lastCalledWith();\nexpect(a).nthCalledWith();\nexpect(a).toReturn();\nexpect(a).toReturnTimes();\nexpect(a).toReturnWith();\nexpect(a).lastReturnedWith();\nexpect(a).nthReturnedWith();\nexpect(a).toThrowError();\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-alias-methods" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule ensures that only the canonical name as used in the Jest documentation is used in the code.\n\n### Why is this bad?\n\nThese aliases are going to be removed in the next major version of Jest - see [jestjs/jest#13164](https://github.com/jestjs/jest/issues/13164) for more.\nThis rule will makes it easier to search for all occurrences of the method within code, and it ensures consistency among the method names used.\n\n### Example\n```javascript\nexpect(a).toBeCalled();\nexpect(a).toBeCalledTimes();\nexpect(a).toBeCalledWith();\nexpect(a).lastCalledWith();\nexpect(a).nthCalledWith();\nexpect(a).toReturn();\nexpect(a).toReturnTimes();\nexpect(a).toReturnWith();\nexpect(a).lastReturnedWith();\nexpect(a).nthReturnedWith();\nexpect(a).toThrowError();\n```\n" + }, + "jest/no-commented-out-tests": { + "description": "### What it does\n\nThis rule raises a warning about commented out tests. It's similar to\nno-disabled-tests rule.\n\n### Why is this bad?\n\nYou may forget to uncomment some tests. This rule raises a warning about commented out tests. It's similar to\nno-disabled-tests rule.\n\n### Example\n\n```javascript\n// describe('foo', () => {});\n// it('foo', () => {});\n// test('foo', () => {});\n\n// describe.skip('foo', () => {});\n// it.skip('foo', () => {});\n// test.skip('foo', () => {});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-commented-out-tests" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule raises a warning about commented out tests. It's similar to\nno-disabled-tests rule.\n\n### Why is this bad?\n\nYou may forget to uncomment some tests. This rule raises a warning about commented out tests. It's similar to\nno-disabled-tests rule.\n\n### Example\n\n```javascript\n// describe('foo', () => {});\n// it('foo', () => {});\n// test('foo', () => {});\n\n// describe.skip('foo', () => {});\n// it.skip('foo', () => {});\n// test.skip('foo', () => {});\n```\n" + }, + "jest/no-conditional-expect": { + "description": "### What it does\n\nThis rule prevents the use of expect in conditional blocks, such as ifs & catch(s).\nThis includes using expect in callbacks to functions named catch, which are assumed to be promises.\n\n### Why is this bad?\n\nJest only considers a test to have failed if it throws an error, meaning if calls to assertion functions like expect occur in conditional code such as a catch statement, tests can end up passing but not actually test anything.\nAdditionally, conditionals tend to make tests more brittle and complex, as they increase the amount of mental thinking needed to understand what is actually being tested.\n\n### Example\n```javascript\nit('foo', () => {\n doTest && expect(1).toBe(2);\n});\n\nit('bar', () => {\n if (!skipTest) {\n expect(1).toEqual(2);\n }\n});\n\nit('throws an error', async () => {\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-conditional-expect" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule prevents the use of expect in conditional blocks, such as ifs & catch(s).\nThis includes using expect in callbacks to functions named catch, which are assumed to be promises.\n\n### Why is this bad?\n\nJest only considers a test to have failed if it throws an error, meaning if calls to assertion functions like expect occur in conditional code such as a catch statement, tests can end up passing but not actually test anything.\nAdditionally, conditionals tend to make tests more brittle and complex, as they increase the amount of mental thinking needed to understand what is actually being tested.\n\n### Example\n```javascript\nit('foo', () => {\n doTest && expect(1).toBe(2);\n});\n\nit('bar', () => {\n if (!skipTest) {\n expect(1).toEqual(2);\n }\n});\n\nit('throws an error', async () => {\n```\n" + }, + "jest/no-confusing-set-timeout": { + "description": "### What it does\n\nDisallow confusing usages of jest.setTimeout\n\n### Why is this bad?\n\n- being called anywhere other than in global scope\n- being called multiple times\n- being called after other Jest functions like hooks, `describe`, `test`, or `it`\n\n\n### Example\n\nAll of these are invalid case:\n```javascript\nescribe('test foo', () => {\n jest.setTimeout(1000);\n it('test-description', () => {\n // test logic;\n });\n});\n\ndescribe('test bar', () => {\n it('test-description', () => {\n jest.setTimeout(1000);\n // test logic;\n });\n});\n\ntest('foo-bar', () => {\n jest.setTimeout(1000);\n});\n\ndescribe('unit test', () => {\n beforeEach(() => {\n jest.setTimeout(1000);\n });\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-confusing-set-timeout" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nDisallow confusing usages of jest.setTimeout\n\n### Why is this bad?\n\n- being called anywhere other than in global scope\n- being called multiple times\n- being called after other Jest functions like hooks, `describe`, `test`, or `it`\n\n\n### Example\n\nAll of these are invalid case:\n```javascript\nescribe('test foo', () => {\n jest.setTimeout(1000);\n it('test-description', () => {\n // test logic;\n });\n});\n\ndescribe('test bar', () => {\n it('test-description', () => {\n jest.setTimeout(1000);\n // test logic;\n });\n});\n\ntest('foo-bar', () => {\n jest.setTimeout(1000);\n});\n\ndescribe('unit test', () => {\n beforeEach(() => {\n jest.setTimeout(1000);\n });\n});\n```\n" + }, + "jest/no-deprecated-functions": { + "description": "### What it does\nOver the years Jest has accrued some debt in the form of functions that have\neither been renamed for clarity, or replaced with more powerful APIs.\n\nThis rule can also autofix a number of these deprecations for you.\n#### `jest.resetModuleRegistry`\nThis function was renamed to `resetModules` in Jest 15 and removed in Jest 27.\n\n#### `jest.addMatchers`\nThis function was replaced with `expect.extend` in Jest 17 and removed in Jest 27.\n\n#### `require.requireActual` & `require.requireMock`\nThese functions were replaced in Jest 21 and removed in Jest 26.\n\nOriginally, the `requireActual` & `requireMock` the `requireActual`&\n`requireMock` functions were placed onto the `require` function.\n\nThese functions were later moved onto the `jest` object in order to be easier\nfor type checkers to handle, and their use via `require` deprecated. Finally,\nthe release of Jest 26 saw them removed from the `require` function altogether.\n\n#### `jest.runTimersToTime`\nThis function was renamed to `advanceTimersByTime` in Jest 22 and removed in Jest 27.\n\n#### `jest.genMockFromModule`\nThis function was renamed to `createMockFromModule` in Jest 26, and is scheduled for removal in Jest 30.\n\n### Why is this bad?\n\nWhile typically these deprecated functions are kept in the codebase for a number\nof majors, eventually they are removed completely.\n\n### Example\n```javascript\njest.resetModuleRegistry // since Jest 15\njest.addMatchers // since Jest 17\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-deprecated-functions" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nOver the years Jest has accrued some debt in the form of functions that have\neither been renamed for clarity, or replaced with more powerful APIs.\n\nThis rule can also autofix a number of these deprecations for you.\n#### `jest.resetModuleRegistry`\nThis function was renamed to `resetModules` in Jest 15 and removed in Jest 27.\n\n#### `jest.addMatchers`\nThis function was replaced with `expect.extend` in Jest 17 and removed in Jest 27.\n\n#### `require.requireActual` & `require.requireMock`\nThese functions were replaced in Jest 21 and removed in Jest 26.\n\nOriginally, the `requireActual` & `requireMock` the `requireActual`&\n`requireMock` functions were placed onto the `require` function.\n\nThese functions were later moved onto the `jest` object in order to be easier\nfor type checkers to handle, and their use via `require` deprecated. Finally,\nthe release of Jest 26 saw them removed from the `require` function altogether.\n\n#### `jest.runTimersToTime`\nThis function was renamed to `advanceTimersByTime` in Jest 22 and removed in Jest 27.\n\n#### `jest.genMockFromModule`\nThis function was renamed to `createMockFromModule` in Jest 26, and is scheduled for removal in Jest 30.\n\n### Why is this bad?\n\nWhile typically these deprecated functions are kept in the codebase for a number\nof majors, eventually they are removed completely.\n\n### Example\n```javascript\njest.resetModuleRegistry // since Jest 15\njest.addMatchers // since Jest 17\n```\n" + }, + "jest/no-disabled-tests": { + "description": "### What it does\nThis rule raises a warning about disabled tests.\n\n### Why is this bad?\n\nJest has a feature that allows you to temporarily mark tests as disabled. This\nfeature is often helpful while debugging or to create placeholders for future\ntests. Before committing changes we may want to check that all tests are\nrunning.\n\n### Example\n\n```js\ndescribe.skip('foo', () => {});\nit.skip('foo', () => {});\ntest.skip('foo', () => {});\n\ndescribe['skip']('bar', () => {});\nit['skip']('bar', () => {});\ntest['skip']('bar', () => {});\n\nxdescribe('foo', () => {});\nxit('foo', () => {});\nxtest('foo', () => {});\n\nit('bar');\ntest('bar');\n\nit('foo', () => {\n pending();\n});\n```\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/no-disabled-tests\": \"error\"\n }\n}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-disabled-tests" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThis rule raises a warning about disabled tests.\n\n### Why is this bad?\n\nJest has a feature that allows you to temporarily mark tests as disabled. This\nfeature is often helpful while debugging or to create placeholders for future\ntests. Before committing changes we may want to check that all tests are\nrunning.\n\n### Example\n\n```js\ndescribe.skip('foo', () => {});\nit.skip('foo', () => {});\ntest.skip('foo', () => {});\n\ndescribe['skip']('bar', () => {});\nit['skip']('bar', () => {});\ntest['skip']('bar', () => {});\n\nxdescribe('foo', () => {});\nxit('foo', () => {});\nxtest('foo', () => {});\n\nit('bar');\ntest('bar');\n\nit('foo', () => {\n pending();\n});\n```\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/no-disabled-tests\": \"error\"\n }\n}\n```\n" + }, + "jest/no-done-callback": { + "description": "### What it does\n\nThis rule checks the function parameter of hooks & tests for use of the done argument, suggesting you return a promise instead.\n\n### Why is this bad?\n\nWhen calling asynchronous code in hooks and tests, jest needs to know when the asynchronous work is complete to progress the current run.\nOriginally the most common pattern to achieve this was to use callbacks:\n\n```javascript\ntest('the data is peanut butter', done => {\n function callback(data) {\n try {\n expect(data).toBe('peanut butter');\n done();\n } catch (error) {\n done(error);\n }\n }\n\n fetchData(callback);\n});\n```\n\nThis can be very error-prone however, as it requires careful understanding of how assertions work in tests or otherwise tests won't behave as expected.\n\n### Example\n```javascript\nbeforeEach(done => {\n // ...\n});\n\ntest('myFunction()', done => {\n // ...\n});\n\ntest('myFunction()', function (done) {\n // ...\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-done-callback" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule checks the function parameter of hooks & tests for use of the done argument, suggesting you return a promise instead.\n\n### Why is this bad?\n\nWhen calling asynchronous code in hooks and tests, jest needs to know when the asynchronous work is complete to progress the current run.\nOriginally the most common pattern to achieve this was to use callbacks:\n\n```javascript\ntest('the data is peanut butter', done => {\n function callback(data) {\n try {\n expect(data).toBe('peanut butter');\n done();\n } catch (error) {\n done(error);\n }\n }\n\n fetchData(callback);\n});\n```\n\nThis can be very error-prone however, as it requires careful understanding of how assertions work in tests or otherwise tests won't behave as expected.\n\n### Example\n```javascript\nbeforeEach(done => {\n // ...\n});\n\ntest('myFunction()', done => {\n // ...\n});\n\ntest('myFunction()', function (done) {\n // ...\n});\n```\n" + }, + "jest/no-duplicate-hooks": { + "description": "### What it does\n\nA `describe` block should not contain duplicate hooks.\n\n### Example\n```javascript\n\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n});\n\n// Nested describe scenario\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n describe('bar', () => {\n test('bar_test', () => {\n afterAll(() => {\n // some teardown\n });\n afterAll(() => {\n // some teardown\n });\n });\n });\n});\n```\n\n```javascript\n\n// valid\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n});\n\n// Nested describe scenario\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n describe('bar', () => {\n test('bar_test', () => {\n beforeEach(() => {\n // some setup\n });\n });\n });\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-duplicate-hooks" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nA `describe` block should not contain duplicate hooks.\n\n### Example\n```javascript\n\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n});\n\n// Nested describe scenario\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n describe('bar', () => {\n test('bar_test', () => {\n afterAll(() => {\n // some teardown\n });\n afterAll(() => {\n // some teardown\n });\n });\n });\n});\n```\n\n```javascript\n\n// valid\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n});\n\n// Nested describe scenario\ndescribe('foo', () => {\n beforeEach(() => {\n // some setup\n });\n test('foo_test', () => {\n // some test\n });\n describe('bar', () => {\n test('bar_test', () => {\n beforeEach(() => {\n // some setup\n });\n });\n });\n});\n```\n" + }, + "jest/no-export": { + "description": "### What it does\n\nPrevents using exports if a file has one or more tests in it.\n\n### Why is this bad?\n\nThis rule aims to eliminate duplicate runs of tests by exporting things from test files.\n If you import from a test file, then all the tests in that file will be run in each imported instance.\nso bottom line, don't export from a test, but instead move helper functions into a separate file when they need to be shared across tests.\n\n### Example\n```javascript\nexport function myHelper() {}\ndescribe('a test', () => {\n expect(1).toBe(1);\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-export" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nPrevents using exports if a file has one or more tests in it.\n\n### Why is this bad?\n\nThis rule aims to eliminate duplicate runs of tests by exporting things from test files.\n If you import from a test file, then all the tests in that file will be run in each imported instance.\nso bottom line, don't export from a test, but instead move helper functions into a separate file when they need to be shared across tests.\n\n### Example\n```javascript\nexport function myHelper() {}\ndescribe('a test', () => {\n expect(1).toBe(1);\n});\n```\n" + }, + "jest/no-focused-tests": { + "description": "### What it does\nThis rule reminds you to remove `.only` from your tests by raising a warning\nwhenever you are using the exclusivity feature.\n\n### Why is this bad?\n\nJest has a feature that allows you to focus tests by appending `.only` or\nprepending `f` to a test-suite or a test-case. This feature is really helpful to\ndebug a failing test, so you don’t have to execute all of your tests. After you\nhave fixed your test and before committing the changes you have to remove\n`.only` to ensure all tests are executed on your build system.\n\n### Example\n\n```javascript\ndescribe.only('foo', () => {});\nit.only('foo', () => {});\ndescribe['only']('bar', () => {});\nit['only']('bar', () => {});\ntest.only('foo', () => {});\ntest['only']('bar', () => {});\nfdescribe('foo', () => {});\nfit('foo', () => {});\nfit.each`\ntable\n`();\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-focused-tests" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThis rule reminds you to remove `.only` from your tests by raising a warning\nwhenever you are using the exclusivity feature.\n\n### Why is this bad?\n\nJest has a feature that allows you to focus tests by appending `.only` or\nprepending `f` to a test-suite or a test-case. This feature is really helpful to\ndebug a failing test, so you don’t have to execute all of your tests. After you\nhave fixed your test and before committing the changes you have to remove\n`.only` to ensure all tests are executed on your build system.\n\n### Example\n\n```javascript\ndescribe.only('foo', () => {});\nit.only('foo', () => {});\ndescribe['only']('bar', () => {});\nit['only']('bar', () => {});\ntest.only('foo', () => {});\ntest['only']('bar', () => {});\nfdescribe('foo', () => {});\nfit('foo', () => {});\nfit.each`\ntable\n`();\n```\n" + }, + "jest/no-hooks": { + "description": "### What it does\nJest provides global functions for setup and teardown tasks, which are called before/after each test case\nand each test suite. The use of these hooks promotes shared state between tests.\n\n### Why is this bad?\n\nThis rule reports for the following function calls:\n* beforeAll\n* beforeEach\n* afterAll\n* afterEach\n\n### Example\n\n```javascript\nfunction setupFoo(options) { /* ... */ }\nfunction setupBar(options) { /* ... */ }\n\ndescribe('foo', () => {\n let foo;\n beforeEach(() => {\n foo = setupFoo();\n });\n afterEach(() => {\n foo = null;\n });\n it('does something', () => {\n expect(foo.doesSomething()).toBe(true);\n });\n describe('with bar', () => {\n let bar;\n beforeEach(() => {\n bar = setupBar();\n });\n afterEach(() => {\n bar = null;\n });\n it('does something with bar', () => {\n expect(foo.doesSomething(bar)).toBe(true);\n });\n });\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-hooks" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nJest provides global functions for setup and teardown tasks, which are called before/after each test case\nand each test suite. The use of these hooks promotes shared state between tests.\n\n### Why is this bad?\n\nThis rule reports for the following function calls:\n* beforeAll\n* beforeEach\n* afterAll\n* afterEach\n\n### Example\n\n```javascript\nfunction setupFoo(options) { /* ... */ }\nfunction setupBar(options) { /* ... */ }\n\ndescribe('foo', () => {\n let foo;\n beforeEach(() => {\n foo = setupFoo();\n });\n afterEach(() => {\n foo = null;\n });\n it('does something', () => {\n expect(foo.doesSomething()).toBe(true);\n });\n describe('with bar', () => {\n let bar;\n beforeEach(() => {\n bar = setupBar();\n });\n afterEach(() => {\n bar = null;\n });\n it('does something with bar', () => {\n expect(foo.doesSomething(bar)).toBe(true);\n });\n });\n});\n```\n" + }, + "jest/no-identical-title": { + "description": "### What it does\n\nThis rule looks at the title of every test and test suite.\nIt will report when two test suites or two test cases at the same level of a test suite have the same title.\n\n### Why is this bad?\n\nHaving identical titles for two different tests or test suites may create confusion.\nFor example, when a test with the same title as another test in the same test suite fails, it is harder to know which one failed and thus harder to fix.\n\n### Example\n```javascript\n describe('baz', () => {\n //...\n });\n\n describe('baz', () => {\n // Has the same title as a previous test suite\n // ...\n });\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-identical-title" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule looks at the title of every test and test suite.\nIt will report when two test suites or two test cases at the same level of a test suite have the same title.\n\n### Why is this bad?\n\nHaving identical titles for two different tests or test suites may create confusion.\nFor example, when a test with the same title as another test in the same test suite fails, it is harder to know which one failed and thus harder to fix.\n\n### Example\n```javascript\n describe('baz', () => {\n //...\n });\n\n describe('baz', () => {\n // Has the same title as a previous test suite\n // ...\n });\n```\n" + }, + "jest/no-interpolation-in-snapshots": { + "description": "### What it does\n\nPrevents the use of string interpolations in snapshots.\n\n### Why is this bad?\n\nInterpolation prevents snapshots from being updated. Instead, properties should\nbe overloaded with a matcher by using\n[property matchers](https://jestjs.io/docs/en/snapshot-testing#property-matchers).\n\n### Example\n\n```javascript\nexpect(something).toMatchInlineSnapshot(\n `Object {\n property: ${interpolated}\n }`,\n);\n\nexpect(something).toMatchInlineSnapshot(\n { other: expect.any(Number) },\n `Object {\n other: Any,\n property: ${interpolated}\n }`,\n);\n\nexpect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot(\n `${interpolated}`,\n);\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-interpolation-in-snapshots" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nPrevents the use of string interpolations in snapshots.\n\n### Why is this bad?\n\nInterpolation prevents snapshots from being updated. Instead, properties should\nbe overloaded with a matcher by using\n[property matchers](https://jestjs.io/docs/en/snapshot-testing#property-matchers).\n\n### Example\n\n```javascript\nexpect(something).toMatchInlineSnapshot(\n `Object {\n property: ${interpolated}\n }`,\n);\n\nexpect(something).toMatchInlineSnapshot(\n { other: expect.any(Number) },\n `Object {\n other: Any,\n property: ${interpolated}\n }`,\n);\n\nexpect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot(\n `${interpolated}`,\n);\n```\n" + }, + "jest/no-jasmine-globals": { + "description": "### What it does\n\nThis rule reports on any usage of Jasmine globals, which is not ported to Jest, and suggests alternatives from Jest's own API.\n\n### Example\n```javascript\njasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;\ntest('my test', () => {\n pending();\n});\ntest('my test', () => {\n jasmine.createSpy();\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-jasmine-globals" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule reports on any usage of Jasmine globals, which is not ported to Jest, and suggests alternatives from Jest's own API.\n\n### Example\n```javascript\njasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;\ntest('my test', () => {\n pending();\n});\ntest('my test', () => {\n jasmine.createSpy();\n});\n```\n" + }, + "jest/no-large-snapshots": { + "description": "### What it does\n\nWhen using Jest's snapshot capability one should be mindful of the size of\ncreated snapshots. As a general best practice snapshots should be limited in\nsize in order to be more manageable and reviewable. A stored snapshot is only as\ngood as its review and as such keeping it short, sweet, and readable is\nimportant to allow for thorough reviews.\n\n### Example\n\n```javascript\n\n// invalid\nexports[`a large snapshot 1`] = `\nline 1\nline 2\nline 3\nline 4\nline 5\nline 6\nline 7\nline 8\nline 9\nline 10\nline 11\nline 12\nline 13\nline 14\nline 15\nline 16\nline 17\nline 18\nline 19\nline 20\nline 21\nline 22\nline 23\nline 24\nline 25\nline 26\nline 27\nline 28\nline 29\nline 30\nline 31\nline 32\nline 33\nline 34\nline 35\nline 36\nline 37\nline 38\nline 39\nline 40\nline 41\nline 42\nline 43\nline 44\nline 45\nline 46\nline 47\nline 48\nline 49\nline 50\nline 51\n`;\n\n// valid\nexports[`a more manageable and readable snapshot 1`] = `\nline 1\nline 2\nline 3\nline 4\n`;\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-large-snapshots" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen using Jest's snapshot capability one should be mindful of the size of\ncreated snapshots. As a general best practice snapshots should be limited in\nsize in order to be more manageable and reviewable. A stored snapshot is only as\ngood as its review and as such keeping it short, sweet, and readable is\nimportant to allow for thorough reviews.\n\n### Example\n\n```javascript\n\n// invalid\nexports[`a large snapshot 1`] = `\nline 1\nline 2\nline 3\nline 4\nline 5\nline 6\nline 7\nline 8\nline 9\nline 10\nline 11\nline 12\nline 13\nline 14\nline 15\nline 16\nline 17\nline 18\nline 19\nline 20\nline 21\nline 22\nline 23\nline 24\nline 25\nline 26\nline 27\nline 28\nline 29\nline 30\nline 31\nline 32\nline 33\nline 34\nline 35\nline 36\nline 37\nline 38\nline 39\nline 40\nline 41\nline 42\nline 43\nline 44\nline 45\nline 46\nline 47\nline 48\nline 49\nline 50\nline 51\n`;\n\n// valid\nexports[`a more manageable and readable snapshot 1`] = `\nline 1\nline 2\nline 3\nline 4\n`;\n```\n\n" + }, + "jest/no-mocks-import": { + "description": "### What it does\n\nThis rule reports imports from a path containing a __mocks__ component.\n\n### Example\n```javascript\nimport thing from './__mocks__/index';\nrequire('./__mocks__/index');\nrequire('__mocks__');\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-mocks-import" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule reports imports from a path containing a __mocks__ component.\n\n### Example\n```javascript\nimport thing from './__mocks__/index';\nrequire('./__mocks__/index');\nrequire('__mocks__');\n\n" + }, + "jest/no-restricted-jest-methods": { + "description": "### What it does\n\nRestrict the use of specific `jest` methods.\n\n### Example\n```javascript\njest.useFakeTimers();\nit('calls the callback after 1 second via advanceTimersByTime', () => {\n // ...\n\n jest.advanceTimersByTime(1000);\n\n // ...\n});\n\ntest('plays video', () => {\n const spy = jest.spyOn(video, 'play');\n\n // ...\n});\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-restricted-jest-methods" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nRestrict the use of specific `jest` methods.\n\n### Example\n```javascript\njest.useFakeTimers();\nit('calls the callback after 1 second via advanceTimersByTime', () => {\n // ...\n\n jest.advanceTimersByTime(1000);\n\n // ...\n});\n\ntest('plays video', () => {\n const spy = jest.spyOn(video, 'play');\n\n // ...\n});\n\n" + }, + "jest/no-restricted-matchers": { + "description": "### What it does\n\nBan specific matchers & modifiers from being used, and can suggest alternatives.\n\n### Example\n```javascript\n\nit('is false', () => {\n if this has a modifier (i.e. `not.toBeFalsy`), it would be considered fine\n expect(a).toBeFalsy();\n});\n\nit('resolves', async () => {\n // all uses of this modifier are disallowed, regardless of matcher\n await expect(myPromise()).resolves.toBe(true);\n});\n\ndescribe('when an error happens', () => {\n it('does not upload the file', async () => {\n // all uses of this matcher are disallowed\n expect(uploadFileMock).not.toHaveBeenCalledWith('file.name');\n });\n});\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-restricted-matchers" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nBan specific matchers & modifiers from being used, and can suggest alternatives.\n\n### Example\n```javascript\n\nit('is false', () => {\n if this has a modifier (i.e. `not.toBeFalsy`), it would be considered fine\n expect(a).toBeFalsy();\n});\n\nit('resolves', async () => {\n // all uses of this modifier are disallowed, regardless of matcher\n await expect(myPromise()).resolves.toBe(true);\n});\n\ndescribe('when an error happens', () => {\n it('does not upload the file', async () => {\n // all uses of this matcher are disallowed\n expect(uploadFileMock).not.toHaveBeenCalledWith('file.name');\n });\n});\n\n" + }, + "jest/no-standalone-expect": { + "description": "### What it does\n\nPrevents `expect` statements outside of a `test` or `it` block. An `expect`\nwithin a helper function (but outside of a `test` or `it` block) will not\ntrigger this rule.\n\nStatements like `expect.hasAssertions()` will NOT trigger this rule since these\ncalls will execute if they are not in a test block.\n\n### Example\n```javascript\ndescribe('a test', () => {\n expect(1).toBe(1);\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-standalone-expect" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nPrevents `expect` statements outside of a `test` or `it` block. An `expect`\nwithin a helper function (but outside of a `test` or `it` block) will not\ntrigger this rule.\n\nStatements like `expect.hasAssertions()` will NOT trigger this rule since these\ncalls will execute if they are not in a test block.\n\n### Example\n```javascript\ndescribe('a test', () => {\n expect(1).toBe(1);\n});\n```\n" + }, + "jest/no-test-prefixes": { + "description": "### What it does\n\nRequire using `.only` and `.skip` over `f` and `x`.\n\n### Why is this bad?\n\nJest allows you to choose how you want to define focused and skipped tests,\nwith multiple permutations for each:\n- only & skip: it.only, test.only, describe.only, it.skip, test.skip, describe.skip.\n- 'f' & 'x': fit, fdescribe, xit, xtest, xdescribe.\n\nThis rule enforces usages from the only & skip list.\n\n### Example\n```javascript\nfit('foo'); // invalid\nfdescribe('foo'); // invalid\nxit('foo'); // invalid\nxtest('foo'); // invalid\nxdescribe('foo'); // invalid\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-test-prefixes" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nRequire using `.only` and `.skip` over `f` and `x`.\n\n### Why is this bad?\n\nJest allows you to choose how you want to define focused and skipped tests,\nwith multiple permutations for each:\n- only & skip: it.only, test.only, describe.only, it.skip, test.skip, describe.skip.\n- 'f' & 'x': fit, fdescribe, xit, xtest, xdescribe.\n\nThis rule enforces usages from the only & skip list.\n\n### Example\n```javascript\nfit('foo'); // invalid\nfdescribe('foo'); // invalid\nxit('foo'); // invalid\nxtest('foo'); // invalid\nxdescribe('foo'); // invalid\n```\n" + }, + "jest/no-test-return-statement": { + "description": "### What it does\n\nDisallow explicitly returning from tests.\n\n### Why is this bad?\n\nTests in Jest should be void and not return values.\nIf you are returning Promises then you should update the test to use\n`async/await`.\n\n### Example\n```javascript\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-test-return-statement" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nDisallow explicitly returning from tests.\n\n### Why is this bad?\n\nTests in Jest should be void and not return values.\nIf you are returning Promises then you should update the test to use\n`async/await`.\n\n### Example\n```javascript\n```\n" + }, + "jest/no-untyped-mock-factory": { + "description": "### What it does\n\nThis rule triggers a warning if `mock()` or `doMock()` is used without a generic\ntype parameter or return type.\n\n### Why is this bad?\n\nBy default, `jest.mock` and `jest.doMock` allow any type to be returned by a\nmock factory. A generic type parameter can be used to enforce that the factory\nreturns an object with the same shape as the original module, or some other\nstrict type. Requiring a type makes it easier to use TypeScript to catch changes\nneeded in test mocks when the source module changes.\n\n### Example\n\n// invalid\n```typescript\njest.mock('../moduleName', () => {\n return jest.fn(() => 42);\n});\n\njest.mock('./module', () => ({\n ...jest.requireActual('./module'),\n foo: jest.fn(),\n}));\n\njest.mock('random-num', () => {\n return jest.fn(() => 42);\n});\n```\n\n// valid\n```typescript\n\n// Uses typeof import()\njest.mock('../moduleName', () => {\n return jest.fn(() => 42);\n});\n\njest.mock('./module', () => ({\n ...jest.requireActual('./module'),\n foo: jest.fn(),\n}));\n\n// Uses custom type\njest.mock<() => number>('random-num', () => {\n return jest.fn(() => 42);\n});\n\n// No factory\njest.mock('random-num');\n\n// Virtual mock\njest.mock(\n '../moduleName',\n () => {\n return jest.fn(() => 42);\n },\n { virtual: true },\n);\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-untyped-mock-factory" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule triggers a warning if `mock()` or `doMock()` is used without a generic\ntype parameter or return type.\n\n### Why is this bad?\n\nBy default, `jest.mock` and `jest.doMock` allow any type to be returned by a\nmock factory. A generic type parameter can be used to enforce that the factory\nreturns an object with the same shape as the original module, or some other\nstrict type. Requiring a type makes it easier to use TypeScript to catch changes\nneeded in test mocks when the source module changes.\n\n### Example\n\n// invalid\n```typescript\njest.mock('../moduleName', () => {\n return jest.fn(() => 42);\n});\n\njest.mock('./module', () => ({\n ...jest.requireActual('./module'),\n foo: jest.fn(),\n}));\n\njest.mock('random-num', () => {\n return jest.fn(() => 42);\n});\n```\n\n// valid\n```typescript\n\n// Uses typeof import()\njest.mock('../moduleName', () => {\n return jest.fn(() => 42);\n});\n\njest.mock('./module', () => ({\n ...jest.requireActual('./module'),\n foo: jest.fn(),\n}));\n\n// Uses custom type\njest.mock<() => number>('random-num', () => {\n return jest.fn(() => 42);\n});\n\n// No factory\njest.mock('random-num');\n\n// Virtual mock\njest.mock(\n '../moduleName',\n () => {\n return jest.fn(() => 42);\n },\n { virtual: true },\n);\n```\n\n" + }, + "jest/prefer-called-with": { + "description": "### What it does\nSuggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`\n\n### Example\n\n```javascript\n\n// valid\nexpect(noArgsFunction).toBeCalledWith();\nexpect(roughArgsFunction).toBeCalledWith(expect.anything(), expect.any(Date));\nexpect(anyArgsFunction).toBeCalledTimes(1);\nexpect(uncalledFunction).not.toBeCalled();\n\n// invalid\nexpect(someFunction).toBeCalled();\nexpect(someFunction).toHaveBeenCalled();\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-called-with" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nSuggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`\n\n### Example\n\n```javascript\n\n// valid\nexpect(noArgsFunction).toBeCalledWith();\nexpect(roughArgsFunction).toBeCalledWith(expect.anything(), expect.any(Date));\nexpect(anyArgsFunction).toBeCalledTimes(1);\nexpect(uncalledFunction).not.toBeCalled();\n\n// invalid\nexpect(someFunction).toBeCalled();\nexpect(someFunction).toHaveBeenCalled();\n```\n\n" + }, + "jest/prefer-comparison-matcher": { + "description": "### What it does\n\nThis rule checks for comparisons in tests that could be replaced with one of the\nfollowing built-in comparison matchers:\n- `toBeGreaterThan`\n- `toBeGreaterThanOrEqual`\n- `toBeLessThan`\n- `toBeLessThanOrEqual`\n\n### Examples\n\n```js\n// invalid\nexpect(x > 5).toBe(true);\nexpect(x < 7).not.toEqual(true);\nexpect(x <= y).toStrictEqual(true);\n```\n\n```js ///\n// valid\nexpect(x).toBeGreaterThan(5);\nexpect(x).not.toBeLessThanOrEqual(7);\nexpect(x).toBeLessThanOrEqual(y);\n// special case - see below\nexpect(x < 'Carl').toBe(true);\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-comparison-matcher" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule checks for comparisons in tests that could be replaced with one of the\nfollowing built-in comparison matchers:\n- `toBeGreaterThan`\n- `toBeGreaterThanOrEqual`\n- `toBeLessThan`\n- `toBeLessThanOrEqual`\n\n### Examples\n\n```js\n// invalid\nexpect(x > 5).toBe(true);\nexpect(x < 7).not.toEqual(true);\nexpect(x <= y).toStrictEqual(true);\n```\n\n```js ///\n// valid\nexpect(x).toBeGreaterThan(5);\nexpect(x).not.toBeLessThanOrEqual(7);\nexpect(x).toBeLessThanOrEqual(y);\n// special case - see below\nexpect(x < 'Carl').toBe(true);\n```\n\n" + }, + "jest/prefer-equality-matcher": { + "description": "### What it does\nJest has built-in matchers for expecting equality, which allow for more readable\ntests and error messages if an expectation fails.\n\n### Example\n\n```javascript\n// invalid\nexpect(x === 5).toBe(true);\nexpect(name === 'Carl').not.toEqual(true);\nexpect(myObj !== thatObj).toStrictEqual(true);\n\n// valid\nexpect(x).toBe(5);\nexpect(name).not.toEqual('Carl');\nexpect(myObj).toStrictEqual(thatObj);\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-equality-matcher" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nJest has built-in matchers for expecting equality, which allow for more readable\ntests and error messages if an expectation fails.\n\n### Example\n\n```javascript\n// invalid\nexpect(x === 5).toBe(true);\nexpect(name === 'Carl').not.toEqual(true);\nexpect(myObj !== thatObj).toStrictEqual(true);\n\n// valid\nexpect(x).toBe(5);\nexpect(name).not.toEqual('Carl');\nexpect(myObj).toStrictEqual(thatObj);\n```\n" + }, + "jest/prefer-expect-resolves": { + "description": "### What it does\n\nWhen working with promises, there are two primary ways you can test the resolved\nvalue:\n1. use the `resolve` modifier on `expect`\n(`await expect(...).resolves.` style)\n2. `await` the promise and assert against its result\n(`expect(await ...).` style)\n\nWhile the second style is arguably less dependent on `jest`, if the promise\nrejects it will be treated as a general error, resulting in less predictable\nbehaviour and output from `jest`.\n\nAdditionally, favoring the first style ensures consistency with its `rejects`\ncounterpart, as there is no way of \"awaiting\" a rejection.\n\n### Example\n\n```javascript\n// valid\nit('passes', async () => {\n await expect(someValue()).resolves.toBe(true);\n});\nit('is true', async () => {\n const myPromise = Promise.resolve(true);\n\n await expect(myPromise).resolves.toBe(true);\n});\n\nit('errors', async () => {\n await expect(Promise.reject(new Error('oh noes!'))).rejects.toThrowError(\n 'oh noes!',\n );\n});\n\n// invalid\nit('passes', async () => {\n expect(await someValue()).toBe(true);\n});\nit('is true', async () => {\n const myPromise = Promise.resolve(true);\n expect(await myPromise).toBe(true);\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-expect-resolves" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen working with promises, there are two primary ways you can test the resolved\nvalue:\n1. use the `resolve` modifier on `expect`\n(`await expect(...).resolves.` style)\n2. `await` the promise and assert against its result\n(`expect(await ...).` style)\n\nWhile the second style is arguably less dependent on `jest`, if the promise\nrejects it will be treated as a general error, resulting in less predictable\nbehaviour and output from `jest`.\n\nAdditionally, favoring the first style ensures consistency with its `rejects`\ncounterpart, as there is no way of \"awaiting\" a rejection.\n\n### Example\n\n```javascript\n// valid\nit('passes', async () => {\n await expect(someValue()).resolves.toBe(true);\n});\nit('is true', async () => {\n const myPromise = Promise.resolve(true);\n\n await expect(myPromise).resolves.toBe(true);\n});\n\nit('errors', async () => {\n await expect(Promise.reject(new Error('oh noes!'))).rejects.toThrowError(\n 'oh noes!',\n );\n});\n\n// invalid\nit('passes', async () => {\n expect(await someValue()).toBe(true);\n});\nit('is true', async () => {\n const myPromise = Promise.resolve(true);\n expect(await myPromise).toBe(true);\n});\n```\n" + }, + "jest/prefer-hooks-in-order": { + "description": "### What it does\n\nWhile hooks can be setup in any order, they're always called by `jest` in this\nspecific order:\n1. `beforeAll`\n2. `beforeEach`\n3. `afterEach`\n4. `afterAll`\n\nThis rule aims to make that more obvious by enforcing grouped hooks be setup in\nthat order within tests.\n\n### Example\n\n```javascript\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n seedMyDatabase();\n });\n beforeAll(() => {\n createMyDatabase();\n });\n it('accepts this input', () => {\n // ...\n });\n it('returns that value', () => {\n // ...\n });\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n it('accepts that input', () => {\n // ...\n });\n it('throws an error', () => {\n // ...\n });\n afterEach(() => {\n clearLogger();\n });\n beforeEach(() => {\n mockLogger();\n });\n it('logs a message', () => {\n // ...\n });\n });\n afterAll(() => {\n removeMyDatabase();\n });\n});\n```\n\n```javascript\n// valid\ndescribe('foo', () => {\n beforeAll(() => {\n createMyDatabase();\n });\n\n beforeEach(() => {\n seedMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n it('returns that value', () => {\n // ...\n });\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n it('accepts that input', () => {\n // ...\n });\n it('throws an error', () => {\n // ...\n });\n beforeEach(() => {\n mockLogger();\n });\n afterEach(() => {\n clearLogger();\n });\n it('logs a message', () => {\n // ...\n });\n });\n afterAll(() => {\n removeMyDatabase();\n });\n});\n```\n\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/prefer-hooks-in-order\": \"error\"\n }\n}\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-hooks-in-order" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhile hooks can be setup in any order, they're always called by `jest` in this\nspecific order:\n1. `beforeAll`\n2. `beforeEach`\n3. `afterEach`\n4. `afterAll`\n\nThis rule aims to make that more obvious by enforcing grouped hooks be setup in\nthat order within tests.\n\n### Example\n\n```javascript\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n seedMyDatabase();\n });\n beforeAll(() => {\n createMyDatabase();\n });\n it('accepts this input', () => {\n // ...\n });\n it('returns that value', () => {\n // ...\n });\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n it('accepts that input', () => {\n // ...\n });\n it('throws an error', () => {\n // ...\n });\n afterEach(() => {\n clearLogger();\n });\n beforeEach(() => {\n mockLogger();\n });\n it('logs a message', () => {\n // ...\n });\n });\n afterAll(() => {\n removeMyDatabase();\n });\n});\n```\n\n```javascript\n// valid\ndescribe('foo', () => {\n beforeAll(() => {\n createMyDatabase();\n });\n\n beforeEach(() => {\n seedMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n it('returns that value', () => {\n // ...\n });\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n it('accepts that input', () => {\n // ...\n });\n it('throws an error', () => {\n // ...\n });\n beforeEach(() => {\n mockLogger();\n });\n afterEach(() => {\n clearLogger();\n });\n it('logs a message', () => {\n // ...\n });\n });\n afterAll(() => {\n removeMyDatabase();\n });\n});\n```\n\n\nThis rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md),\nto use it, add the following configuration to your `.eslintrc.json`:\n\n```json\n{\n \"rules\": {\n \"vitest/prefer-hooks-in-order\": \"error\"\n }\n}\n" + }, + "jest/prefer-hooks-on-top": { + "description": "### What it does\n\nWhile hooks can be setup anywhere in a test file, they are always called in a\nspecific order, which means it can be confusing if they're intermixed with test\ncases.\n\n### Example\n\n```javascript\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n seedMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n\n beforeAll(() => {\n createMyDatabase();\n });\n\n it('returns that value', () => {\n // ...\n });\n\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n it('accepts that input', () => {\n // ...\n });\n\n it('throws an error', () => {\n // ...\n });\n\n afterEach(() => {\n clearLogger();\n });\n\n beforeEach(() => {\n mockLogger();\n });\n\n it('logs a message', () => {\n // ...\n });\n });\n\n afterAll(() => {\n removeMyDatabase();\n });\n});\n\n// valid\ndescribe('foo', () => {\n beforeAll(() => {\n createMyDatabase();\n });\n\n beforeEach(() => {\n seedMyDatabase();\n });\n\n afterAll(() => {\n clearMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n\n it('returns that value', () => {\n // ...\n });\n\n describe('when the database has specific values', () => {\n const specificValue = '...';\n\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n beforeEach(() => {\n mockLogger();\n });\n\n afterEach(() => {\n clearLogger();\n });\n\n it('accepts that input', () => {\n // ...\n });\n\n it('throws an error', () => {\n // ...\n });\n\n it('logs a message', () => {\n // ...\n });\n });\n});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-hooks-on-top" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhile hooks can be setup anywhere in a test file, they are always called in a\nspecific order, which means it can be confusing if they're intermixed with test\ncases.\n\n### Example\n\n```javascript\n// invalid\ndescribe('foo', () => {\n beforeEach(() => {\n seedMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n\n beforeAll(() => {\n createMyDatabase();\n });\n\n it('returns that value', () => {\n // ...\n });\n\n describe('when the database has specific values', () => {\n const specificValue = '...';\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n it('accepts that input', () => {\n // ...\n });\n\n it('throws an error', () => {\n // ...\n });\n\n afterEach(() => {\n clearLogger();\n });\n\n beforeEach(() => {\n mockLogger();\n });\n\n it('logs a message', () => {\n // ...\n });\n });\n\n afterAll(() => {\n removeMyDatabase();\n });\n});\n\n// valid\ndescribe('foo', () => {\n beforeAll(() => {\n createMyDatabase();\n });\n\n beforeEach(() => {\n seedMyDatabase();\n });\n\n afterAll(() => {\n clearMyDatabase();\n });\n\n it('accepts this input', () => {\n // ...\n });\n\n it('returns that value', () => {\n // ...\n });\n\n describe('when the database has specific values', () => {\n const specificValue = '...';\n\n beforeEach(() => {\n seedMyDatabase(specificValue);\n });\n\n beforeEach(() => {\n mockLogger();\n });\n\n afterEach(() => {\n clearLogger();\n });\n\n it('accepts that input', () => {\n // ...\n });\n\n it('throws an error', () => {\n // ...\n });\n\n it('logs a message', () => {\n // ...\n });\n });\n});\n```\n" + }, + "jest/prefer-jest-mocked": { + "description": "### What it does\n\nWhen working with mocks of functions using Jest, it's recommended to use the\n`jest.mocked()` helper function to properly type the mocked functions. This rule\nenforces the use of `jest.mocked()` for better type safety and readability.\n\nRestricted types:\n\n\n- `jest.Mock`\n- `jest.MockedFunction`\n- `jest.MockedClass`\n- `jest.MockedObject`\n\n### Examples\n\n```typescript\n// invalid\n(foo as jest.Mock).mockReturnValue(1);\nconst mock = (foo as jest.Mock).mockReturnValue(1);\n(foo as unknown as jest.Mock).mockReturnValue(1);\n(Obj.foo as jest.Mock).mockReturnValue(1);\n([].foo as jest.Mock).mockReturnValue(1);\n\n// valid\njest.mocked(foo).mockReturnValue(1);\nconst mock = jest.mocked(foo).mockReturnValue(1);\njest.mocked(Obj.foo).mockReturnValue(1);\njest.mocked([].foo).mockReturnValue(1);\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-jest-mocked" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen working with mocks of functions using Jest, it's recommended to use the\n`jest.mocked()` helper function to properly type the mocked functions. This rule\nenforces the use of `jest.mocked()` for better type safety and readability.\n\nRestricted types:\n\n\n- `jest.Mock`\n- `jest.MockedFunction`\n- `jest.MockedClass`\n- `jest.MockedObject`\n\n### Examples\n\n```typescript\n// invalid\n(foo as jest.Mock).mockReturnValue(1);\nconst mock = (foo as jest.Mock).mockReturnValue(1);\n(foo as unknown as jest.Mock).mockReturnValue(1);\n(Obj.foo as jest.Mock).mockReturnValue(1);\n([].foo as jest.Mock).mockReturnValue(1);\n\n// valid\njest.mocked(foo).mockReturnValue(1);\nconst mock = jest.mocked(foo).mockReturnValue(1);\njest.mocked(Obj.foo).mockReturnValue(1);\njest.mocked([].foo).mockReturnValue(1);\n```\n" + }, + "jest/prefer-lowercase-title": { + "description": "### What it does\n\nEnforce `it`, `test` and `describe` to have descriptions that begin with a\nlowercase letter. This provides more readable test failures. This rule is not\nenabled by default.\n\n### Example\n\n```javascript\n// invalid\nit('Adds 1 + 2 to equal 3', () => {\n expect(sum(1, 2)).toBe(3);\n});\n\n// valid\nit('adds 1 + 2 to equal 3', () => {\n expect(sum(1, 2)).toBe(3);\n});\n```\n\n## Options\n```json\n{\n \"jest/prefer-lowercase-title\": [\n \"error\",\n {\n \"ignore\": [\"describe\", \"test\"]\n }\n ]\n}\n```\n\n### `ignore`\n\nThis array option controls which Jest functions are checked by this rule. There\nare three possible values:\n- `\"describe\"`\n- `\"test\"`\n- `\"it\"`\n\nBy default, none of these options are enabled (the equivalent of\n`{ \"ignore\": [] }`).\n\nExample of **correct** code for the `{ \"ignore\": [\"describe\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"describe\"] }] */\ndescribe('Uppercase description');\n```\n\nExample of **correct** code for the `{ \"ignore\": [\"test\"] }` option:\n\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"test\"] }] */\ntest('Uppercase description');\n```\n\nExample of **correct** code for the `{ \"ignore\": [\"it\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"it\"] }] */\nit('Uppercase description');\n```\n\n### `allowedPrefixes`\nThis array option allows specifying prefixes, which contain capitals that titles\ncan start with. This can be useful when writing tests for API endpoints, where\nyou'd like to prefix with the HTTP method.\nBy default, nothing is allowed (the equivalent of `{ \"allowedPrefixes\": [] }`).\n\nExample of **correct** code for the `{ \"allowedPrefixes\": [\"GET\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"allowedPrefixes\": [\"GET\"] }] */\ndescribe('GET /live');\n```\n\n### `ignoreTopLevelDescribe`\nThis option can be set to allow only the top-level `describe` blocks to have a\ntitle starting with an upper-case letter.\nExample of **correct** code for the `{ \"ignoreTopLevelDescribe\": true }` option:\n\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignoreTopLevelDescribe\": true }] */\ndescribe('MyClass', () => {\n describe('#myMethod', () => {\n it('does things', () => {\n //\n });\n });\n});\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-lowercase-title" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce `it`, `test` and `describe` to have descriptions that begin with a\nlowercase letter. This provides more readable test failures. This rule is not\nenabled by default.\n\n### Example\n\n```javascript\n// invalid\nit('Adds 1 + 2 to equal 3', () => {\n expect(sum(1, 2)).toBe(3);\n});\n\n// valid\nit('adds 1 + 2 to equal 3', () => {\n expect(sum(1, 2)).toBe(3);\n});\n```\n\n## Options\n```json\n{\n \"jest/prefer-lowercase-title\": [\n \"error\",\n {\n \"ignore\": [\"describe\", \"test\"]\n }\n ]\n}\n```\n\n### `ignore`\n\nThis array option controls which Jest functions are checked by this rule. There\nare three possible values:\n- `\"describe\"`\n- `\"test\"`\n- `\"it\"`\n\nBy default, none of these options are enabled (the equivalent of\n`{ \"ignore\": [] }`).\n\nExample of **correct** code for the `{ \"ignore\": [\"describe\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"describe\"] }] */\ndescribe('Uppercase description');\n```\n\nExample of **correct** code for the `{ \"ignore\": [\"test\"] }` option:\n\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"test\"] }] */\ntest('Uppercase description');\n```\n\nExample of **correct** code for the `{ \"ignore\": [\"it\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignore\": [\"it\"] }] */\nit('Uppercase description');\n```\n\n### `allowedPrefixes`\nThis array option allows specifying prefixes, which contain capitals that titles\ncan start with. This can be useful when writing tests for API endpoints, where\nyou'd like to prefix with the HTTP method.\nBy default, nothing is allowed (the equivalent of `{ \"allowedPrefixes\": [] }`).\n\nExample of **correct** code for the `{ \"allowedPrefixes\": [\"GET\"] }` option:\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"allowedPrefixes\": [\"GET\"] }] */\ndescribe('GET /live');\n```\n\n### `ignoreTopLevelDescribe`\nThis option can be set to allow only the top-level `describe` blocks to have a\ntitle starting with an upper-case letter.\nExample of **correct** code for the `{ \"ignoreTopLevelDescribe\": true }` option:\n\n```js\n/* eslint jest/prefer-lowercase-title: [\"error\", { \"ignoreTopLevelDescribe\": true }] */\ndescribe('MyClass', () => {\n describe('#myMethod', () => {\n it('does things', () => {\n //\n });\n });\n});\n```\n\n" + }, + "jest/prefer-mock-promise-shorthand": { + "description": "### What it does\n\nWhen working with mocks of functions that return promises, Jest provides some\nAPI sugar functions to reduce the amount of boilerplate you have to write.\nThese methods should be preferred when possible.\n\n### Example\n\n```javascript\n// invalid\njest.fn().mockImplementation(() => Promise.resolve(123));\njest\n .spyOn(fs.promises, 'readFile')\n .mockReturnValue(Promise.reject(new Error('oh noes!')));\n\nmyFunction\n .mockReturnValueOnce(Promise.resolve(42))\n .mockImplementationOnce(() => Promise.resolve(42))\n .mockReturnValue(Promise.reject(new Error('too many calls!')));\n```\n\n// valid\n```javascript\njest.fn().mockResolvedValue(123);\njest.spyOn(fs.promises, 'readFile').mockRejectedValue(new Error('oh noes!'));\n\nmyFunction\n .mockResolvedValueOnce(42)\n .mockResolvedValueOnce(42)\n .mockRejectedValue(new Error('too many calls!'));\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-mock-promise-shorthand" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen working with mocks of functions that return promises, Jest provides some\nAPI sugar functions to reduce the amount of boilerplate you have to write.\nThese methods should be preferred when possible.\n\n### Example\n\n```javascript\n// invalid\njest.fn().mockImplementation(() => Promise.resolve(123));\njest\n .spyOn(fs.promises, 'readFile')\n .mockReturnValue(Promise.reject(new Error('oh noes!')));\n\nmyFunction\n .mockReturnValueOnce(Promise.resolve(42))\n .mockImplementationOnce(() => Promise.resolve(42))\n .mockReturnValue(Promise.reject(new Error('too many calls!')));\n```\n\n// valid\n```javascript\njest.fn().mockResolvedValue(123);\njest.spyOn(fs.promises, 'readFile').mockRejectedValue(new Error('oh noes!'));\n\nmyFunction\n .mockResolvedValueOnce(42)\n .mockResolvedValueOnce(42)\n .mockRejectedValue(new Error('too many calls!'));\n```\n\n" + }, + "jest/prefer-spy-on": { + "description": "### What it does\n\nWhen mocking a function by overwriting a property you have to manually restore\nthe original implementation when cleaning up. When using `jest.spyOn()` Jest\nkeeps track of changes, and they can be restored with `jest.restoreAllMocks()`,\n`mockFn.mockRestore()` or by setting `restoreMocks` to `true` in the Jest\nconfig.\n\nNote: The mock created by `jest.spyOn()` still behaves the same as the original\nfunction. The original function can be overwritten with\n`mockFn.mockImplementation()` or by some of the\n[other mock functions](https://jestjs.io/docs/en/mock-function-api).\n\n### Example\n\n```javascript\n// invalid\nDate.now = jest.fn();\nDate.now = jest.fn(() => 10);\n\n// valid\njest.spyOn(Date, 'now');\njest.spyOn(Date, 'now').mockImplementation(() => 10);\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-spy-on" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen mocking a function by overwriting a property you have to manually restore\nthe original implementation when cleaning up. When using `jest.spyOn()` Jest\nkeeps track of changes, and they can be restored with `jest.restoreAllMocks()`,\n`mockFn.mockRestore()` or by setting `restoreMocks` to `true` in the Jest\nconfig.\n\nNote: The mock created by `jest.spyOn()` still behaves the same as the original\nfunction. The original function can be overwritten with\n`mockFn.mockImplementation()` or by some of the\n[other mock functions](https://jestjs.io/docs/en/mock-function-api).\n\n### Example\n\n```javascript\n// invalid\nDate.now = jest.fn();\nDate.now = jest.fn(() => 10);\n\n// valid\njest.spyOn(Date, 'now');\njest.spyOn(Date, 'now').mockImplementation(() => 10);\n```\n" + }, + "jest/prefer-strict-equal": { + "description": "### What it does\n\nThis rule triggers a warning if `toEqual()` is used to assert equality.\n\n### Example\n\n```javascript\n// invalid\nexpect({ a: 'a', b: undefined }).toEqual({ a: 'a' });\n\n// valid\nexpect({ a: 'a', b: undefined }).toStrictEqual({ a: 'a' });\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-strict-equal" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule triggers a warning if `toEqual()` is used to assert equality.\n\n### Example\n\n```javascript\n// invalid\nexpect({ a: 'a', b: undefined }).toEqual({ a: 'a' });\n\n// valid\nexpect({ a: 'a', b: undefined }).toStrictEqual({ a: 'a' });\n```\n\n" + }, + "jest/prefer-to-be": { + "description": "### What it does\n\nWhen asserting against primitive literals such as numbers and strings, the\nequality matchers all operate the same, but read slightly differently in code.\n\nThis rule recommends using the `toBe` matcher in these situations, as it forms\nthe most grammatically natural sentence. For `null`, `undefined`, and `NaN` this\nrule recommends using their specific `toBe` matchers, as they give better error\nmessages as well.\n\n### Example\n\n```javascript\n// valid\nexpect(value).not.toBe(5);\nexpect(getMessage()).toBe('hello world');\nexpect(loadMessage()).resolves.toBe('hello world');\nexpect(didError).not.toBe(true);\nexpect(catchError()).toStrictEqual({ message: 'oh noes!' });\n\n// invalid\nexpect(value).not.toEqual(5);\nexpect(getMessage()).toStrictEqual('hello world');\nexpect(loadMessage()).resolves.toEqual('hello world');\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-to-be" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nWhen asserting against primitive literals such as numbers and strings, the\nequality matchers all operate the same, but read slightly differently in code.\n\nThis rule recommends using the `toBe` matcher in these situations, as it forms\nthe most grammatically natural sentence. For `null`, `undefined`, and `NaN` this\nrule recommends using their specific `toBe` matchers, as they give better error\nmessages as well.\n\n### Example\n\n```javascript\n// valid\nexpect(value).not.toBe(5);\nexpect(getMessage()).toBe('hello world');\nexpect(loadMessage()).resolves.toBe('hello world');\nexpect(didError).not.toBe(true);\nexpect(catchError()).toStrictEqual({ message: 'oh noes!' });\n\n// invalid\nexpect(value).not.toEqual(5);\nexpect(getMessage()).toStrictEqual('hello world');\nexpect(loadMessage()).resolves.toEqual('hello world');\n```\n" + }, + "jest/prefer-to-contain": { + "description": "### What it does\n\nIn order to have a better failure message, `toContain()` should be used upon\nasserting expectations on an array containing an object.\n\n### Why is this bad?\n\nTThis rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is\nused to assert object inclusion in an array\n\n### Example\n\n```javascript\n// valid\nexpect(a).toContain(b);\nexpect(a).not.toContain(b);\n\n// invalid\nexpect(a.includes(b)).toBe(true);\nexpect(a.includes(b)).not.toBe(true);\nexpect(a.includes(b)).toBe(false);\nexpect(a.includes(b)).toEqual(true);\nexpect(a.includes(b)).toStrictEqual(true);\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-to-contain" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nIn order to have a better failure message, `toContain()` should be used upon\nasserting expectations on an array containing an object.\n\n### Why is this bad?\n\nTThis rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is\nused to assert object inclusion in an array\n\n### Example\n\n```javascript\n// valid\nexpect(a).toContain(b);\nexpect(a).not.toContain(b);\n\n// invalid\nexpect(a.includes(b)).toBe(true);\nexpect(a.includes(b)).not.toBe(true);\nexpect(a.includes(b)).toBe(false);\nexpect(a.includes(b)).toEqual(true);\nexpect(a.includes(b)).toStrictEqual(true);\n```\n\n" + }, + "jest/prefer-to-have-length": { + "description": "### What it does\n\nIn order to have a better failure message, `toHaveLength()` should be used upon\nasserting expectations on objects length property.\n\n### Why is this bad?\n\nThis rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is\nused to assert objects length property.\n\n### Example\n\n```javascript\n// valid\nexpect.hasAssertions;\nexpect.hasAssertions();\nexpect(files).toHaveLength(1);\nexpect(files.name).toBe('file');\n\n// invalid\nexpect(files[\"length\"]).toBe(1);\nexpect(files[\"length\"]).toBe(1,);\nexpect(files[\"length\"])[\"not\"].toBe(1)\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-to-have-length" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nIn order to have a better failure message, `toHaveLength()` should be used upon\nasserting expectations on objects length property.\n\n### Why is this bad?\n\nThis rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is\nused to assert objects length property.\n\n### Example\n\n```javascript\n// valid\nexpect.hasAssertions;\nexpect.hasAssertions();\nexpect(files).toHaveLength(1);\nexpect(files.name).toBe('file');\n\n// invalid\nexpect(files[\"length\"]).toBe(1);\nexpect(files[\"length\"]).toBe(1,);\nexpect(files[\"length\"])[\"not\"].toBe(1)\n```\n\n" + }, + "jest/prefer-todo": { + "description": "### What it does\nWhen test cases are empty then it is better to mark them as `test.todo` as it\nwill be highlighted in the summary output.\n\n### Why is this bad?\n\nThis rule triggers a warning if empty test cases are used without 'test.todo'.\n\n### Example\n\n```javascript\ntest('i need to write this test'); // invalid\ntest('i need to write this test', () => {}); // invalid\ntest.skip('i need to write this test', () => {}); // invalid\n\ntest.todo('i need to write this test');\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/prefer-todo" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nWhen test cases are empty then it is better to mark them as `test.todo` as it\nwill be highlighted in the summary output.\n\n### Why is this bad?\n\nThis rule triggers a warning if empty test cases are used without 'test.todo'.\n\n### Example\n\n```javascript\ntest('i need to write this test'); // invalid\ntest('i need to write this test', () => {}); // invalid\ntest.skip('i need to write this test', () => {}); // invalid\n\ntest.todo('i need to write this test');\n```\n" + }, + "jest/require-hook": { + "description": "### What it does\nThis rule flags any expression that is either at the toplevel of a test file or\ndirectly within the body of a `describe`, _except_ for the following:\n\n- `import` statements\n- `const` variables\n- `let` _declarations_, and initializations to `null` or `undefined`\n- Classes\n- Types\n- Calls to the standard Jest globals\n\n### Example\n```javascript\n// invalid\nimport { database, isCity } from '../database';\nimport { Logger } from '../../../src/Logger';\nimport { loadCities } from '../api';\n\njest.mock('../api');\n\nconst initializeCityDatabase = () => {\n database.addCity('Vienna');\n database.addCity('San Juan');\n database.addCity('Wellington');\n};\n\nconst clearCityDatabase = () => {\n database.clear();\n};\n\ninitializeCityDatabase();\n\ntest('that persists cities', () => {\n expect(database.cities.length).toHaveLength(3);\n});\ntest('city database has Vienna', () => {\n expect(isCity('Vienna')).toBeTruthy();\n});\n\ntest('city database has San Juan', () => {\n expect(isCity('San Juan')).toBeTruthy();\n});\n\ndescribe('when loading cities from the api', () => {\n let consoleWarnSpy = jest.spyOn(console, 'warn');\n loadCities.mockResolvedValue(['Wellington', 'London']);\n\n it('does not duplicate cities', async () => {\n await database.loadCities();\n expect(database.cities).toHaveLength(4);\n });\n});\nclearCityDatabase();\n\n// valid\nimport { database, isCity } from '../database';\nimport { Logger } from '../../../src/Logger';\nimport { loadCities } from '../api';\n\njest.mock('../api');\nconst initializeCityDatabase = () => {\n database.addCity('Vienna');\n database.addCity('San Juan');\n database.addCity('Wellington');\n};\n\nconst clearCityDatabase = () => {\n database.clear();\n};\n\nbeforeEach(() => {\n initializeCityDatabase();\n});\n\ntest('that persists cities', () => {\n expect(database.cities.length).toHaveLength(3);\n});\n\ntest('city database has Vienna', () => {\n expect(isCity('Vienna')).toBeTruthy();\n});\n\ntest('city database has San Juan', () => {\n expect(isCity('San Juan')).toBeTruthy();\n});\n\ndescribe('when loading cities from the api', () => {\n let consoleWarnSpy;\n beforeEach(() => {\n consoleWarnSpy = jest.spyOn(console, 'warn');\n loadCities.mockResolvedValue(['Wellington', 'London']);\n });\n\n it('does not duplicate cities', async () => {\n await database.loadCities();\n expect(database.cities).toHaveLength(4);\n });\n});\nafterEach(() => {\n clearCityDatabase();\n});\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-hook" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThis rule flags any expression that is either at the toplevel of a test file or\ndirectly within the body of a `describe`, _except_ for the following:\n\n- `import` statements\n- `const` variables\n- `let` _declarations_, and initializations to `null` or `undefined`\n- Classes\n- Types\n- Calls to the standard Jest globals\n\n### Example\n```javascript\n// invalid\nimport { database, isCity } from '../database';\nimport { Logger } from '../../../src/Logger';\nimport { loadCities } from '../api';\n\njest.mock('../api');\n\nconst initializeCityDatabase = () => {\n database.addCity('Vienna');\n database.addCity('San Juan');\n database.addCity('Wellington');\n};\n\nconst clearCityDatabase = () => {\n database.clear();\n};\n\ninitializeCityDatabase();\n\ntest('that persists cities', () => {\n expect(database.cities.length).toHaveLength(3);\n});\ntest('city database has Vienna', () => {\n expect(isCity('Vienna')).toBeTruthy();\n});\n\ntest('city database has San Juan', () => {\n expect(isCity('San Juan')).toBeTruthy();\n});\n\ndescribe('when loading cities from the api', () => {\n let consoleWarnSpy = jest.spyOn(console, 'warn');\n loadCities.mockResolvedValue(['Wellington', 'London']);\n\n it('does not duplicate cities', async () => {\n await database.loadCities();\n expect(database.cities).toHaveLength(4);\n });\n});\nclearCityDatabase();\n\n// valid\nimport { database, isCity } from '../database';\nimport { Logger } from '../../../src/Logger';\nimport { loadCities } from '../api';\n\njest.mock('../api');\nconst initializeCityDatabase = () => {\n database.addCity('Vienna');\n database.addCity('San Juan');\n database.addCity('Wellington');\n};\n\nconst clearCityDatabase = () => {\n database.clear();\n};\n\nbeforeEach(() => {\n initializeCityDatabase();\n});\n\ntest('that persists cities', () => {\n expect(database.cities.length).toHaveLength(3);\n});\n\ntest('city database has Vienna', () => {\n expect(isCity('Vienna')).toBeTruthy();\n});\n\ntest('city database has San Juan', () => {\n expect(isCity('San Juan')).toBeTruthy();\n});\n\ndescribe('when loading cities from the api', () => {\n let consoleWarnSpy;\n beforeEach(() => {\n consoleWarnSpy = jest.spyOn(console, 'warn');\n loadCities.mockResolvedValue(['Wellington', 'London']);\n });\n\n it('does not duplicate cities', async () => {\n await database.loadCities();\n expect(database.cities).toHaveLength(4);\n });\n});\nafterEach(() => {\n clearCityDatabase();\n});\n```\n\n" + }, + "jest/require-to-throw-message": { + "description": "### What it does\nThis rule triggers a warning if `toThrow()` or `toThrowError()` is used without an error message.\n\n### Example\n```javascript\n// invalid\ntest('all the things', async () => {\n expect(() => a()).toThrow();\n expect(() => a()).toThrowError();\n await expect(a()).rejects.toThrow();\n await expect(a()).rejects.toThrowError();\n});\n\n// valid\ntest('all the things', async () => {\n expect(() => a()).toThrow('a');\n expect(() => a()).toThrowError('a');\n await expect(a()).rejects.toThrow('a');\n await expect(a()).rejects.toThrowError('a');\n});\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-to-throw-message" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThis rule triggers a warning if `toThrow()` or `toThrowError()` is used without an error message.\n\n### Example\n```javascript\n// invalid\ntest('all the things', async () => {\n expect(() => a()).toThrow();\n expect(() => a()).toThrowError();\n await expect(a()).rejects.toThrow();\n await expect(a()).rejects.toThrowError();\n});\n\n// valid\ntest('all the things', async () => {\n expect(() => a()).toThrow('a');\n expect(() => a()).toThrowError('a');\n await expect(a()).rejects.toThrow('a');\n await expect(a()).rejects.toThrowError('a');\n});\n```\n\n" + }, + "jest/require-top-level-describe": { + "description": "### What it does\n\nThis rule triggers a warning if a test case (`test` and `it`) or a hook\n(`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) is not located in a\ntop-level `describe` block.\n\n### Example\n\n```javascript\n// invalid\nAbove a describe block\ntest('my test', () => {});\ndescribe('test suite', () => {\n it('test', () => {});\n});\n// Below a describe block\ndescribe('test suite', () => {});\ntest('my test', () => {});\n// Same for hooks\nbeforeAll('my beforeAll', () => {});\ndescribe('test suite', () => {});\nafterEach('my afterEach', () => {});\n\n//valid\n// Above a describe block\n// In a describe block\ndescribe('test suite', () => {\n test('my test', () => {});\n});\n\n// In a nested describe block\ndescribe('test suite', () => {\n test('my test', () => {});\ndescribe('another test suite', () => {\n test('my other test', () => {});\n});\n});\n```\n\n### Options\n\nYou can also enforce a limit on the number of describes allowed at the top-level\nusing the `maxNumberOfTopLevelDescribes` option:\n\n```json\n{\n \"jest/require-top-level-describe\": [\n \"error\",\n {\n \"maxNumberOfTopLevelDescribes\": 2\n }\n ]\n}\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-top-level-describe" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule triggers a warning if a test case (`test` and `it`) or a hook\n(`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) is not located in a\ntop-level `describe` block.\n\n### Example\n\n```javascript\n// invalid\nAbove a describe block\ntest('my test', () => {});\ndescribe('test suite', () => {\n it('test', () => {});\n});\n// Below a describe block\ndescribe('test suite', () => {});\ntest('my test', () => {});\n// Same for hooks\nbeforeAll('my beforeAll', () => {});\ndescribe('test suite', () => {});\nafterEach('my afterEach', () => {});\n\n//valid\n// Above a describe block\n// In a describe block\ndescribe('test suite', () => {\n test('my test', () => {});\n});\n\n// In a nested describe block\ndescribe('test suite', () => {\n test('my test', () => {});\ndescribe('another test suite', () => {\n test('my other test', () => {});\n});\n});\n```\n\n### Options\n\nYou can also enforce a limit on the number of describes allowed at the top-level\nusing the `maxNumberOfTopLevelDescribes` option:\n\n```json\n{\n \"jest/require-top-level-describe\": [\n \"error\",\n {\n \"maxNumberOfTopLevelDescribes\": 2\n }\n ]\n}\n```\n\n" + }, + "jest/valid-describe-callback": { + "description": "### What it does\n\nThis rule validates that the second parameter of a `describe()` function is a\ncallback function. This callback function:\n- should not be\n[async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- should not contain any parameters\n- should not contain any `return` statements\n\n### Why is this bad?\n\nUsing an improper `describe()` callback function can lead to unexpected test\nerrors.\n\n### Example\n\n```javascript\n// Async callback functions are not allowed\ndescribe('myFunction()', async () => {\n // ...\n});\n\n// Callback function parameters are not allowed\ndescribe('myFunction()', done => {\n // ...\n});\n\n// Returning a value from a describe block is not allowed\ndescribe('myFunction', () =>\n it('returns a truthy value', () => {\n expect(myFunction()).toBeTruthy();\n}));\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/valid-describe-callback" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule validates that the second parameter of a `describe()` function is a\ncallback function. This callback function:\n- should not be\n[async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- should not contain any parameters\n- should not contain any `return` statements\n\n### Why is this bad?\n\nUsing an improper `describe()` callback function can lead to unexpected test\nerrors.\n\n### Example\n\n```javascript\n// Async callback functions are not allowed\ndescribe('myFunction()', async () => {\n // ...\n});\n\n// Callback function parameters are not allowed\ndescribe('myFunction()', done => {\n // ...\n});\n\n// Returning a value from a describe block is not allowed\ndescribe('myFunction', () =>\n it('returns a truthy value', () => {\n expect(myFunction()).toBeTruthy();\n}));\n```\n" + }, + "jest/valid-expect": { + "description": "### What it does\n\nThis rule triggers a warning if `expect()` is called with more than one argument\nor without arguments. It would also issue a warning if there is nothing called\non `expect()`, e.g.:\n\n### Example\n```javascript\nexpect();\nexpect('something');\nexpect(true).toBeDefined;\nexpect(Promise.resolve('Hi!')).resolves.toBe('Hi!');\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/valid-expect" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nThis rule triggers a warning if `expect()` is called with more than one argument\nor without arguments. It would also issue a warning if there is nothing called\non `expect()`, e.g.:\n\n### Example\n```javascript\nexpect();\nexpect('something');\nexpect(true).toBeDefined;\nexpect(Promise.resolve('Hi!')).resolves.toBe('Hi!');\n```\n" + }, + "jest/valid-title": { + "description": "### What it does\n\nChecks that the title of Jest blocks are valid by ensuring that titles are:\n\n- not empty,\n- is a string,\n- not prefixed with their block name,\n- have no leading or trailing spaces\n\n### Example\n```javascript\ndescribe('', () => {});\ndescribe('foo', () => {\n it('', () => {});\n});\nit('', () => {});\ntest('', () => {});\nxdescribe('', () => {});\nxit('', () => {});\nxtest('', () => {});\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/valid-title" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nChecks that the title of Jest blocks are valid by ensuring that titles are:\n\n- not empty,\n- is a string,\n- not prefixed with their block name,\n- have no leading or trailing spaces\n\n### Example\n```javascript\ndescribe('', () => {});\ndescribe('foo', () => {\n it('', () => {});\n});\nit('', () => {});\ntest('', () => {});\nxdescribe('', () => {});\nxit('', () => {});\nxtest('', () => {});\n```\n" + }, + "jsdoc/check-access": { + "description": "### What it does\nChecks that `@access` tags use one of the following values:\n- \"package\", \"private\", \"protected\", \"public\"\n\nAlso reports:\n- Mixing of `@access` with `@public`, `@private`, `@protected`, or `@package` on the same doc block.\n- Use of multiple instances of `@access` (or the `@public`, etc) on the same doc block.\n\n### Why is this bad?\nIt is important to have a consistent way of specifying access levels.\n\n### Example\n```javascript\n// Passing\n/** @access private */\n\n/** @private */\n\n// Failing\n/** @access private @public */\n\n/** @access invalidlevel */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/check-access" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nChecks that `@access` tags use one of the following values:\n- \"package\", \"private\", \"protected\", \"public\"\n\nAlso reports:\n- Mixing of `@access` with `@public`, `@private`, `@protected`, or `@package` on the same doc block.\n- Use of multiple instances of `@access` (or the `@public`, etc) on the same doc block.\n\n### Why is this bad?\nIt is important to have a consistent way of specifying access levels.\n\n### Example\n```javascript\n// Passing\n/** @access private */\n\n/** @private */\n\n// Failing\n/** @access private @public */\n\n/** @access invalidlevel */\n```\n" + }, + "jsdoc/check-property-names": { + "description": "### What it does\nEnsures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.\n\n### Why is this bad?\n`@property` tags with the same name can be confusing and may indicate a mistake.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {object} state\n * @property {number} foo\n */\n/**\n * @typedef {object} state\n * @property {object} foo\n * @property {number} foo.bar\n */\n\n// Failing\n/**\n * @typedef {object} state\n * @property {number} foo\n * @property {string} foo\n */\n\n/**\n * @typedef {object} state\n * @property {number} foo.bar\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/check-property-names" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnsures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.\n\n### Why is this bad?\n`@property` tags with the same name can be confusing and may indicate a mistake.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {object} state\n * @property {number} foo\n */\n/**\n * @typedef {object} state\n * @property {object} foo\n * @property {number} foo.bar\n */\n\n// Failing\n/**\n * @typedef {object} state\n * @property {number} foo\n * @property {string} foo\n */\n\n/**\n * @typedef {object} state\n * @property {number} foo.bar\n */\n```\n" + }, + "jsdoc/check-tag-names": { + "description": "### What it does\nReports invalid block tag names.\nAdditionally checks for tag names that are redundant when using a type checker such as TypeScript.\n\n### Why is this bad?\nUsing invalid tags can lead to confusion and make the documentation harder to read.\n\n### Example\n```javascript\n// Passing\n/** @param */\n\n// Failing\n/** @Param */\n/** @foo */\n\n/**\n * This is redundant when typed.\n * @type {string}\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/check-tag-names" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nReports invalid block tag names.\nAdditionally checks for tag names that are redundant when using a type checker such as TypeScript.\n\n### Why is this bad?\nUsing invalid tags can lead to confusion and make the documentation harder to read.\n\n### Example\n```javascript\n// Passing\n/** @param */\n\n// Failing\n/** @Param */\n/** @foo */\n\n/**\n * This is redundant when typed.\n * @type {string}\n */\n```\n" + }, + "jsdoc/empty-tags": { + "description": "### What it does\nExpects the following tags to be empty of any content:\n- `@abstract`\n- `@async`\n- `@generator`\n- `@global`\n- `@hideconstructor`\n- `@ignore`\n- `@inner`\n- `@instance`\n- `@override`\n- `@readonly`\n- `@inheritDoc`\n- `@internal`\n- `@overload`\n- `@package`\n- `@private`\n- `@protected`\n- `@public`\n- `@static`\n\n### Why is this bad?\nThe void tags should be empty.\n\n### Example\n```javascript\n// Passing\n/** @async */\n\n/** @private */\n\n// Failing\n/** @async foo */\n\n/** @private bar */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/empty-tags" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nExpects the following tags to be empty of any content:\n- `@abstract`\n- `@async`\n- `@generator`\n- `@global`\n- `@hideconstructor`\n- `@ignore`\n- `@inner`\n- `@instance`\n- `@override`\n- `@readonly`\n- `@inheritDoc`\n- `@internal`\n- `@overload`\n- `@package`\n- `@private`\n- `@protected`\n- `@public`\n- `@static`\n\n### Why is this bad?\nThe void tags should be empty.\n\n### Example\n```javascript\n// Passing\n/** @async */\n\n/** @private */\n\n// Failing\n/** @async foo */\n\n/** @private bar */\n```\n" + }, + "jsdoc/implements-on-classes": { + "description": "### What it does\nReports an issue with any non-constructor function using `@implements`.\n\n### Why is this bad?\nConstructor functions should be\nwhether marked with `@class`, `@constructs`, or being an ES6 class constructor.\n\n### Example\n```javascript\n// Passing\nclass Foo {\n /**\n * @implements {SomeClass}\n */\n constructor() {}\n}\n/**\n * @implements {SomeClass}\n * @class\n */\nfunction quux () {}\n\n// Failing\n/**\n * @implements {SomeClass}\n */\nfunction quux () {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/implements-on-classes" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nReports an issue with any non-constructor function using `@implements`.\n\n### Why is this bad?\nConstructor functions should be\nwhether marked with `@class`, `@constructs`, or being an ES6 class constructor.\n\n### Example\n```javascript\n// Passing\nclass Foo {\n /**\n * @implements {SomeClass}\n */\n constructor() {}\n}\n/**\n * @implements {SomeClass}\n * @class\n */\nfunction quux () {}\n\n// Failing\n/**\n * @implements {SomeClass}\n */\nfunction quux () {}\n```\n" + }, + "jsdoc/no-defaults": { + "description": "### What it does\nThis rule reports defaults being used on the relevant portion of `@param` or `@default`.\nIt also optionally reports the presence of the square-bracketed optional arguments at all.\n\n### Why is this bad?\nThe rule is intended to prevent the indication of defaults on tags\nwhere this would be redundant with ES6 default parameters.\n\n### Example\n```javascript\n// Passing\n/** @param {number} foo */\nfunction quux (foo) {}\n/** @param foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param {number} [foo=\"7\"] */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/no-defaults" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThis rule reports defaults being used on the relevant portion of `@param` or `@default`.\nIt also optionally reports the presence of the square-bracketed optional arguments at all.\n\n### Why is this bad?\nThe rule is intended to prevent the indication of defaults on tags\nwhere this would be redundant with ES6 default parameters.\n\n### Example\n```javascript\n// Passing\n/** @param {number} foo */\nfunction quux (foo) {}\n/** @param foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param {number} [foo=\"7\"] */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-param": { + "description": "### What it does\nRequires that all function parameters are documented with JSDoc `@param` tags.\n\n### Why is this bad?\nThe rule is aimed at enforcing code quality and maintainability by requiring that all function parameters are documented.\n\n### Example\n```javascript\n// Passing\n/** @param foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo, bar) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-param" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that all function parameters are documented with JSDoc `@param` tags.\n\n### Why is this bad?\nThe rule is aimed at enforcing code quality and maintainability by requiring that all function parameters are documented.\n\n### Example\n```javascript\n// Passing\n/** @param foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo, bar) {}\n```\n" + }, + "jsdoc/require-param-description": { + "description": "### What it does\nRequires that each `@param` tag has a description value.\n\n### Why is this bad?\nThe description of a param should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param foo Foo. */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-param-description" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that each `@param` tag has a description value.\n\n### Why is this bad?\nThe description of a param should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param foo Foo. */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-param-name": { + "description": "### What it does\nRequires that all `@param` tags have names.\n\n### Why is this bad?\nThe name of a param should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param {SomeType} foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param {SomeType} */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-param-name" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that all `@param` tags have names.\n\n### Why is this bad?\nThe name of a param should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param {SomeType} foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param {SomeType} */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-param-type": { + "description": "### What it does\nRequires that each `@param` tag has a type value (within curly brackets).\n\n### Why is this bad?\nThe type of a parameter should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param {SomeType} foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-param-type" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that each `@param` tag has a type value (within curly brackets).\n\n### Why is this bad?\nThe type of a parameter should be documented.\n\n### Example\n```javascript\n// Passing\n/** @param {SomeType} foo */\nfunction quux (foo) {}\n\n// Failing\n/** @param foo */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-property": { + "description": "### What it does\nRequires that all `@typedef` and `@namespace` tags have `@property` tags\nwhen their type is a plain `object`, `Object`, or `PlainObject`.\n\n### Why is this bad?\nObject type should have properties defined.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {Object} SomeTypedef\n * @property {SomeType} propName Prop description\n */\n/**\n * @typedef {object} Foo\n * @property someProp\n */\n\n// Failing\n/**\n * @typedef {Object} SomeTypedef\n */\n/**\n * @namespace {Object} SomeNamesoace\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-property" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that all `@typedef` and `@namespace` tags have `@property` tags\nwhen their type is a plain `object`, `Object`, or `PlainObject`.\n\n### Why is this bad?\nObject type should have properties defined.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {Object} SomeTypedef\n * @property {SomeType} propName Prop description\n */\n/**\n * @typedef {object} Foo\n * @property someProp\n */\n\n// Failing\n/**\n * @typedef {Object} SomeTypedef\n */\n/**\n * @namespace {Object} SomeNamesoace\n */\n```\n" + }, + "jsdoc/require-property-description": { + "description": "### What it does\nRequires that all `@property` tags have descriptions.\n\n### Why is this bad?\nThe description of a property should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo Foo.\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-property-description" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that all `@property` tags have descriptions.\n\n### Why is this bad?\nThe description of a property should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo Foo.\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n```\n" + }, + "jsdoc/require-property-name": { + "description": "### What it does\nRequires that all `@property` tags have names.\n\n### Why is this bad?\nThe name of a property type should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number}\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-property-name" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that all `@property` tags have names.\n\n### Why is this bad?\nThe name of a property type should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number}\n */\n```\n" + }, + "jsdoc/require-property-type": { + "description": "### What it does\nRequires that each `@property` tag has a type value (within curly brackets).\n\n### Why is this bad?\nThe type of a property should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property foo\n */\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-property-type" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that each `@property` tag has a type value (within curly brackets).\n\n### Why is this bad?\nThe type of a property should be documented.\n\n### Example\n```javascript\n// Passing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property {number} foo\n */\n\n// Failing\n/**\n * @typedef {SomeType} SomeTypedef\n * @property foo\n */\n```\n" + }, + "jsdoc/require-returns": { + "description": "### What it does\nRequires that return statements are documented.\nWill also report if multiple `@returns` tags are present.\n\n### Why is this bad?\nThe rule is intended to prevent the omission of `@returns` tag when necessary.\n\n### Example\n```javascript\n// Passing\n/** @returns Foo. */\nfunction quux () { return foo; }\n\n// Failing\n/** Foo. */\nfunction quux () { return foo; }\n/**\n * @returns Foo!\n * @returns Foo?\n */\nfunction quux () { return foo; }\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-returns" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that return statements are documented.\nWill also report if multiple `@returns` tags are present.\n\n### Why is this bad?\nThe rule is intended to prevent the omission of `@returns` tag when necessary.\n\n### Example\n```javascript\n// Passing\n/** @returns Foo. */\nfunction quux () { return foo; }\n\n// Failing\n/** Foo. */\nfunction quux () { return foo; }\n/**\n * @returns Foo!\n * @returns Foo?\n */\nfunction quux () { return foo; }\n```\n" + }, + "jsdoc/require-returns-description": { + "description": "### What it does\nRequires that the `@returns` tag has a description value.\nThe error will not be reported if the return value is `void `or `undefined` or if it is `Promise` or `Promise`.\n\n### Why is this bad?\nA `@returns` tag should have a description value.\n\n### Example\n```javascript\n// Passing\n/** @returns Foo. */\nfunction quux (foo) {}\n\n// Failing\n/** @returns */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-returns-description" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that the `@returns` tag has a description value.\nThe error will not be reported if the return value is `void `or `undefined` or if it is `Promise` or `Promise`.\n\n### Why is this bad?\nA `@returns` tag should have a description value.\n\n### Example\n```javascript\n// Passing\n/** @returns Foo. */\nfunction quux (foo) {}\n\n// Failing\n/** @returns */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-returns-type": { + "description": "### What it does\nRequires that `@returns` tag has a type value (in curly brackets).\n\n### Why is this bad?\nA `@returns` tag should have a type value.\n\n### Example\n```javascript\n// Passing\n/** @returns {string} */\nfunction quux (foo) {}\n\n// Failing\n/** @returns */\nfunction quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-returns-type" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that `@returns` tag has a type value (in curly brackets).\n\n### Why is this bad?\nA `@returns` tag should have a type value.\n\n### Example\n```javascript\n// Passing\n/** @returns {string} */\nfunction quux (foo) {}\n\n// Failing\n/** @returns */\nfunction quux (foo) {}\n```\n" + }, + "jsdoc/require-yields": { + "description": "### What it does\nRequires that yields are documented.\nWill also report if multiple `@yields` tags are present.\n\n### Why is this bad?\nThe rule is intended to prevent the omission of `@yields` tags when they are necessary.\n\n### Example\n```javascript\n// Passing\n/** * @yields Foo */\nfunction * quux (foo) { yield foo; }\n\n// Failing\nfunction * quux (foo) { yield foo; }\n/**\n * @yields {undefined}\n * @yields {void}\n */\nfunction * quux (foo) {}\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/require-yields" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nRequires that yields are documented.\nWill also report if multiple `@yields` tags are present.\n\n### Why is this bad?\nThe rule is intended to prevent the omission of `@yields` tags when they are necessary.\n\n### Example\n```javascript\n// Passing\n/** * @yields Foo */\nfunction * quux (foo) { yield foo; }\n\n// Failing\nfunction * quux (foo) { yield foo; }\n/**\n * @yields {undefined}\n * @yields {void}\n */\nfunction * quux (foo) {}\n```\n" + }, + "jsx_a11y/alt-text": { + "description": "### What it does\n\nEnforce that all elements that require alternative text have meaningful\ninformation to relay back to the end user.\n\n### Why is this necessary?\n\nAlternative text is a critical component of accessibility for screen\nreader users, enabling them to understand the content and function\nof an element.\n\n### What it checks\n\nThis rule checks for alternative text on the following elements:\n``, ``, ``, and ``.\n\n### How to fix it\n\nEnsure that the `alt` attribute is present and contains meaningful\ntext that describes the element's content or purpose.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\"A\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/alt-text" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce that all elements that require alternative text have meaningful\ninformation to relay back to the end user.\n\n### Why is this necessary?\n\nAlternative text is a critical component of accessibility for screen\nreader users, enabling them to understand the content and function\nof an element.\n\n### What it checks\n\nThis rule checks for alternative text on the following elements:\n``, ``, ``, and ``.\n\n### How to fix it\n\nEnsure that the `alt` attribute is present and contains meaningful\ntext that describes the element's content or purpose.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\"A\n```\n" + }, + "jsx_a11y/anchor-has-content": { + "description": "### What it does\n\nEnforce that anchors have content and that the content is accessible to screen readers.\nAccessible means that it is not hidden using the `aria-hidden` prop.\n\nAlternatively, you may use the `title` prop or the `aria-label` prop.\n\n### Why is this bad?\n\n\n### Example\n\n#### good\n\n```\nAnchor Content!\n \n \n \n \n```\n\n#### bad\n\n```\n\n\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/anchor-has-content" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce that anchors have content and that the content is accessible to screen readers.\nAccessible means that it is not hidden using the `aria-hidden` prop.\n\nAlternatively, you may use the `title` prop or the `aria-label` prop.\n\n### Why is this bad?\n\n\n### Example\n\n#### good\n\n```\nAnchor Content!\n \n \n \n \n```\n\n#### bad\n\n```\n\n\n```\n\n" + }, + "jsx_a11y/anchor-is-valid": { + "description": "### What it does\nThe HTML element, with a valid href attribute, is formally defined as representing a **hyperlink**.\nThat is, a link between one HTML document and another, or between one location inside an HTML document and another location inside the same document.\n\nWhile before it was possible to attach logic to an anchor element, with the advent of JSX libraries,\nit's now easier to attach logic to any HTML element, anchors included.\n\nThis rule is designed to prevent users to attach logic at the click of anchors, and also makes\nsure that the `href` provided to the anchor element is valid. If the anchor has logic attached to it,\nthe rules suggests to turn it to a `button`, because that's likely what the user wants.\n\nAnchor `` elements should be used for navigation, while `` should be\nused for user interaction.\n\nConsider the following:\n\n```javascript\nPerform action\nPerform action\nPerform action\n````\n\nAll these anchor implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with:\n\n```javascript\n\n```\n`\n### Why is this bad?\nThere are **many reasons** why an anchor should not have a logic and have a correct `href` attribute:\n- it can disrupt the correct flow of the user navigation e.g. a user that wants to open the link\nin another tab, but the default \"click\" behaviour is prevented\n- it can source of invalid links, and crawlers can't navigate the website, risking to penalise SEO ranking\n\n### Example\n\n#### Valid\n\n```javascript\nnavigate here\n```\n\n```javascript\nnavigate here\n```\n\n```javascript\nnavigate here\n```\n\n#### Invalid\n\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n\n### Reference\n\n- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/anchor-is-valid" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nThe HTML element, with a valid href attribute, is formally defined as representing a **hyperlink**.\nThat is, a link between one HTML document and another, or between one location inside an HTML document and another location inside the same document.\n\nWhile before it was possible to attach logic to an anchor element, with the advent of JSX libraries,\nit's now easier to attach logic to any HTML element, anchors included.\n\nThis rule is designed to prevent users to attach logic at the click of anchors, and also makes\nsure that the `href` provided to the anchor element is valid. If the anchor has logic attached to it,\nthe rules suggests to turn it to a `button`, because that's likely what the user wants.\n\nAnchor `` elements should be used for navigation, while `` should be\nused for user interaction.\n\nConsider the following:\n\n```javascript\nPerform action\nPerform action\nPerform action\n````\n\nAll these anchor implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with:\n\n```javascript\n\n```\n`\n### Why is this bad?\nThere are **many reasons** why an anchor should not have a logic and have a correct `href` attribute:\n- it can disrupt the correct flow of the user navigation e.g. a user that wants to open the link\nin another tab, but the default \"click\" behaviour is prevented\n- it can source of invalid links, and crawlers can't navigate the website, risking to penalise SEO ranking\n\n### Example\n\n#### Valid\n\n```javascript\nnavigate here\n```\n\n```javascript\nnavigate here\n```\n\n```javascript\nnavigate here\n```\n\n#### Invalid\n\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n```javascript\nnavigate here\n```\n\n### Reference\n\n- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)\n" + }, + "jsx_a11y/aria-activedescendant-has-tabindex": { + "description": "### What it does\n\nEnforce elements with aria-activedescendant are tabbable.\n\n### Example\n```jsx\n// Good\n\n\n\n\n
\n\n
\n
\n
\n
\n
\n
\n\n\n\n\n// Bad\n
\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/aria-activedescendant-has-tabindex" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce elements with aria-activedescendant are tabbable.\n\n### Example\n```jsx\n// Good\n\n\n\n\n
\n\n
\n
\n
\n
\n
\n
\n\n\n\n\n// Bad\n
\n```\n" + }, + "jsx_a11y/aria-props": { + "description": "### What it does\nEnforces that elements do not use invalid ARIA attributes.\n\n### Why is this bad?\nUsing invalid ARIA attributes can mislead screen readers and other assistive technologies.\nIt may cause the accessibility features of the website to fail, making it difficult\nfor users with disabilities to use the site effectively.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/aria-props" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforces that elements do not use invalid ARIA attributes.\n\n### Why is this bad?\nUsing invalid ARIA attributes can mislead screen readers and other assistive technologies.\nIt may cause the accessibility features of the website to fail, making it difficult\nfor users with disabilities to use the site effectively.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n" + }, + "jsx_a11y/aria-role": { + "description": "### What it does\nElements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.\n\n### Why is this bad?\nThe intent of this Success Criterion is to ensure that Assistive Technologies (AT) can gather information about,\nactivate (or set) and keep up to date on the status of user interface controls in the content(such as screen readers, screen magnifiers, and speech recognition software, used by people with disabilities).\n\nWhen standard controls from accessible technologies are used, this process is straightforward. If the user interface elements are used according to specification the conditions of this provision will be met.\n\nIf custom controls are created, however, or interface elements are programmed (in code or script) to have a different role and/or function than usual,\nthen additional measures need to be taken to ensure that the controls provide important information to assistive technologies and allow themselves to be controlled by assistive technologies.\nA particularly important state of a user interface control is whether or not it has focus. The focus state of a control can be programmatically determined, and notifications about change of focus are sent to user agents and assistive technology.\nOther examples of user interface control state are whether or not a checkbox or radio button has been selected, or whether or not a collapsible tree or list node is expanded or collapsed.\n\n### Rule options\nThis rule takes one optional object argument of type object:\n```\n{\n \"rules\": {\n \"jsx-a11y/aria-role\": [ 2, {\n \"allowedInvalidRoles\": [\"text\"],\n \"ignoreNonDOM\": true\n }],\n }\n }\n```\nallowedInvalidRules is an optional string array of custom roles that should be allowed in addition to the ARIA spec, such as for cases when you need to use a non-standard role.\n\nFor the ignoreNonDOM option, this determines if developer created components are checked.\n\n### Example\n// good\n```javascript\n
\n
\n
\n \n```\n\n// bad\n```javascript\n
\n
\n
\n \n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/aria-role" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nElements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.\n\n### Why is this bad?\nThe intent of this Success Criterion is to ensure that Assistive Technologies (AT) can gather information about,\nactivate (or set) and keep up to date on the status of user interface controls in the content(such as screen readers, screen magnifiers, and speech recognition software, used by people with disabilities).\n\nWhen standard controls from accessible technologies are used, this process is straightforward. If the user interface elements are used according to specification the conditions of this provision will be met.\n\nIf custom controls are created, however, or interface elements are programmed (in code or script) to have a different role and/or function than usual,\nthen additional measures need to be taken to ensure that the controls provide important information to assistive technologies and allow themselves to be controlled by assistive technologies.\nA particularly important state of a user interface control is whether or not it has focus. The focus state of a control can be programmatically determined, and notifications about change of focus are sent to user agents and assistive technology.\nOther examples of user interface control state are whether or not a checkbox or radio button has been selected, or whether or not a collapsible tree or list node is expanded or collapsed.\n\n### Rule options\nThis rule takes one optional object argument of type object:\n```\n{\n \"rules\": {\n \"jsx-a11y/aria-role\": [ 2, {\n \"allowedInvalidRoles\": [\"text\"],\n \"ignoreNonDOM\": true\n }],\n }\n }\n```\nallowedInvalidRules is an optional string array of custom roles that should be allowed in addition to the ARIA spec, such as for cases when you need to use a non-standard role.\n\nFor the ignoreNonDOM option, this determines if developer created components are checked.\n\n### Example\n// good\n```javascript\n
\n
\n
\n \n```\n\n// bad\n```javascript\n
\n
\n
\n \n```\n" + }, + "jsx_a11y/aria-unsupported-elements": { + "description": "### What it does\n\nCertain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` and/or `aria-*` props.\n\n### Example\n\n```jsx\n// Good\n\t\n\n// Bad\n\n```\n\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/aria-unsupported-elements" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nCertain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` and/or `aria-*` props.\n\n### Example\n\n```jsx\n// Good\n\t\n\n// Bad\n\n```\n\n" + }, + "jsx_a11y/autocomplete-valid": { + "description": "### What it does\nEnforces that an element's autocomplete attribute must be a valid value.\n\n### Why is this bad?\nIncorrectly using the autocomplete attribute may decrease the accessibility of the website for users.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/autocomplete-valid" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\nEnforces that an element's autocomplete attribute must be a valid value.\n\n### Why is this bad?\nIncorrectly using the autocomplete attribute may decrease the accessibility of the website for users.\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n" + }, + "jsx_a11y/click-events-have-key-events": { + "description": "### What it does\n\nEnforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress.\n\n### Why is this bad?\n\nCoding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.\nThis does not apply for interactive or hidden elements.\n\n### Example\n```jsx\n// Good\n
void 0} onKeyDown={() => void 0} />\n\n// Bad\n
void 0} />\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/click-events-have-key-events" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress.\n\n### Why is this bad?\n\nCoding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.\nThis does not apply for interactive or hidden elements.\n\n### Example\n```jsx\n// Good\n
void 0} onKeyDown={() => void 0} />\n\n// Bad\n
void 0} />\n```\n" + }, + "jsx_a11y/heading-has-content": { + "description": "### What it does\n\nEnforce that heading elements (h1, h2, etc.) have content and\nthat the content is accessible to screen readers.\nAccessible means that it is not hidden using the aria-hidden prop.\n\n### Why is this bad?\n\nScreen readers alert users to the presence of a heading tag.\nIf the heading is empty or the text cannot be accessed,\nthis could either confuse users or even prevent them\nfrom accessing information on the page's structure.\n\n### Example\n```javascript\n// Bad\n

\n\n// Good\n

Foo

\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/heading-has-content" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnforce that heading elements (h1, h2, etc.) have content and\nthat the content is accessible to screen readers.\nAccessible means that it is not hidden using the aria-hidden prop.\n\n### Why is this bad?\n\nScreen readers alert users to the presence of a heading tag.\nIf the heading is empty or the text cannot be accessed,\nthis could either confuse users or even prevent them\nfrom accessing information on the page's structure.\n\n### Example\n```javascript\n// Bad\n

\n\n// Good\n

Foo

\n```\n" + }, + "jsx_a11y/html-has-lang": { + "description": "### What it does\n\nEnsures that every HTML document has a lang attribute\n\n### Why is this bad?\nIf the language of a webpage is not specified,\nthe screen reader assumes the default language set by the user.\nLanguage settings become an issue for users who speak multiple languages\nand access website in more than one language.\n\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n", + "anyOf": [ + { + "$ref": "#/definitions/AllowWarnDeny" + }, + { + "items": { + "$ref": "#/definitions/AllowWarnDeny" + }, + "additionalItems": { + "$ref": "#/definitions/html-has-lang" + } + }, + { + "type": "array", + "items": true + } + ], + "markdownDescription": "### What it does\n\nEnsures that every HTML document has a lang attribute\n\n### Why is this bad?\nIf the language of a webpage is not specified,\nthe screen reader assumes the default language set by the user.\nLanguage settings become an issue for users who speak multiple languages\nand access website in more than one language.\n\n\n### Example\n```javascript\n// Bad\n\n\n// Good\n\n```\n" + }, + "jsx_a11y/iframe-has-title": { + "description": "### What it does\n\nEnforce iframe elements have a title attribute.\n\n### Why is this necessary?\n\nScreen reader users rely on a iframe title to describe the contents of the iframe.\nNavigating through iframe and iframe elements quickly becomes difficult and confusing for users of this technology if the markup does not contain a title attribute.\n\n### What it checks\n\nThis rule checks for title property on iframe element.\n\n### Example\n```javascript\n// Bad\n