mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Use fake rules for testing deprecation and removal infrastructure (#9752)
Updates #9689 and #9691 to use rule testing infrastructure from #9747
This commit is contained in:
parent
e5008ca714
commit
46c0937bfa
5 changed files with 235 additions and 83 deletions
|
@ -824,7 +824,9 @@ fn nursery_prefix() {
|
|||
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
Found 4 errors.
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
Found 6 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
|
@ -846,7 +848,9 @@ fn nursery_all() {
|
|||
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
Found 5 errors.
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
Found 7 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
|
@ -1094,7 +1098,7 @@ fn preview_enabled_group_ignore() {
|
|||
#[test]
|
||||
fn removed_direct() {
|
||||
// Selection of a removed rule should fail
|
||||
let mut cmd = RuffCheck::default().args(["--select", "PLR1706"]).build();
|
||||
let mut cmd = RuffCheck::default().args(["--select", "RUF931"]).build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
|
@ -1102,7 +1106,28 @@ fn removed_direct() {
|
|||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: Rule `PLR1706` was removed and cannot be selected.
|
||||
Cause: Rule `RUF931` was removed and cannot be selected.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn removed_direct_multiple() {
|
||||
// Selection of multiple removed rule should fail with a message
|
||||
// including all the rules
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "RUF930", "--select", "RUF931"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: The following rules have been removed and cannot be selected:
|
||||
- RUF930
|
||||
- RUF931
|
||||
|
||||
"###);
|
||||
}
|
||||
|
||||
|
@ -1110,12 +1135,8 @@ fn removed_direct() {
|
|||
fn removed_indirect() {
|
||||
// Selection _including_ a removed rule without matching should not fail
|
||||
// nor should the rule be used
|
||||
let mut cmd = RuffCheck::default().args(["--select", "PLR"]).build();
|
||||
assert_cmd_snapshot!(cmd.pass_stdin(r###"
|
||||
# This would have been a PLR1706 violation
|
||||
x, y = 1, 2
|
||||
maximum = x >= y and x or y
|
||||
"""###), @r###"
|
||||
let mut cmd = RuffCheck::default().args(["--select", "RUF93"]).build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -1128,74 +1149,49 @@ maximum = x >= y and x or y
|
|||
fn deprecated_direct() {
|
||||
// Selection of a deprecated rule without preview enabled should still work
|
||||
// but a warning should be displayed
|
||||
let mut cmd = RuffCheck::default().args(["--select", "TRY200"]).build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
def reciprocal(n):
|
||||
try:
|
||||
return 1 / n
|
||||
except ZeroDivisionError:
|
||||
raise ValueError()
|
||||
"###), @r###"
|
||||
let mut cmd = RuffCheck::default().args(["--select", "RUF920"]).build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:6:9: TRY200 Use `raise from` to specify exception cause
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: Rule `TRY200` is deprecated and will be removed in a future release.
|
||||
warning: Rule `RUF920` is deprecated and will be removed in a future release.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deprecated_multiple_direct() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "ANN101", "--select", "ANN102"])
|
||||
.args(["--select", "RUF920", "--select", "RUF921"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
class Foo:
|
||||
def a(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def b(cls):
|
||||
pass
|
||||
"###), @r###"
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:3:11: ANN101 Missing type annotation for `self` in method
|
||||
-:7:11: ANN102 Missing type annotation for `cls` in classmethod
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
Found 2 errors.
|
||||
|
||||
----- stderr -----
|
||||
warning: Rule `ANN102` is deprecated and will be removed in a future release.
|
||||
warning: Rule `ANN101` is deprecated and will be removed in a future release.
|
||||
warning: Rule `RUF921` is deprecated and will be removed in a future release.
|
||||
warning: Rule `RUF920` is deprecated and will be removed in a future release.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deprecated_indirect() {
|
||||
// `ANN` includes deprecated rules `ANN101` and `ANN102` but should not warn
|
||||
// `RUF92` includes deprecated rules but should not warn
|
||||
// since it is not a "direct" selection
|
||||
let mut cmd = RuffCheck::default().args(["--select", "ANN1"]).build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
class Foo:
|
||||
def a(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def b(cls):
|
||||
pass
|
||||
"###), @r###"
|
||||
let mut cmd = RuffCheck::default().args(["--select", "RUF92"]).build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:3:11: ANN101 Missing type annotation for `self` in method
|
||||
-:7:11: ANN102 Missing type annotation for `cls` in classmethod
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
Found 2 errors.
|
||||
|
||||
----- stderr -----
|
||||
|
@ -1206,40 +1202,26 @@ class Foo:
|
|||
fn deprecated_direct_preview_enabled() {
|
||||
// Direct selection of a deprecated rule in preview should fail
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "TRY200", "--preview"])
|
||||
.args(["--select", "RUF920", "--preview"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
def reciprocal(n):
|
||||
try:
|
||||
return 1 / n
|
||||
except ZeroDivisionError:
|
||||
raise ValueError()
|
||||
"###), @r###"
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: Selection of deprecated rule `TRY200` is not allowed when preview is enabled.
|
||||
Cause: Selection of deprecated rule `RUF920` is not allowed when preview is enabled.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deprecated_indirect_preview_enabled() {
|
||||
// `TRY200` is deprecated and should be off by default in preview.
|
||||
// `RUF920` is deprecated and should be off by default in preview.
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "TRY", "--preview"])
|
||||
.args(["--select", "RUF92", "--preview"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
def reciprocal(n):
|
||||
try:
|
||||
return 1 / n
|
||||
except ZeroDivisionError:
|
||||
raise ValueError()
|
||||
"###), @r###"
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -1253,16 +1235,9 @@ fn deprecated_multiple_direct_preview_enabled() {
|
|||
// Direct selection of the deprecated rules in preview should fail with
|
||||
// a message listing all of the rule codes
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "ANN101", "--select", "ANN102", "--preview"])
|
||||
.args(["--select", "RUF920", "--select", "RUF921", "--preview"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin(r###"
|
||||
def reciprocal(n):
|
||||
try:
|
||||
return 1 / n
|
||||
except ZeroDivisionError:
|
||||
raise ValueError()
|
||||
"###), @r###"
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
@ -1270,8 +1245,8 @@ def reciprocal(n):
|
|||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: Selection of deprecated rules is not allowed when preview is enabled. Remove selection of:
|
||||
- ANN102
|
||||
- ANN101
|
||||
- RUF921
|
||||
- RUF920
|
||||
|
||||
"###);
|
||||
}
|
||||
|
@ -1793,7 +1768,9 @@ extend-safe-fixes = ["RUF9"]
|
|||
-:1:1: RUF901 Hey this is a stable test rule with a safe fix.
|
||||
-:1:1: RUF902 [*] Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
Found 4 errors.
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
Found 6 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
|
|
|
@ -951,6 +951,14 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
#[cfg(feature = "test-rules")]
|
||||
#[allow(deprecated)]
|
||||
(Ruff, "912") => (RuleGroup::Nursery, rules::ruff::rules::NurseryTestRule),
|
||||
#[cfg(feature = "test-rules")]
|
||||
(Ruff, "920") => (RuleGroup::Deprecated, rules::ruff::rules::DeprecatedTestRule),
|
||||
#[cfg(feature = "test-rules")]
|
||||
(Ruff, "921") => (RuleGroup::Deprecated, rules::ruff::rules::AnotherDeprecatedTestRule),
|
||||
#[cfg(feature = "test-rules")]
|
||||
(Ruff, "930") => (RuleGroup::Removed, rules::ruff::rules::RemovedTestRule),
|
||||
#[cfg(feature = "test-rules")]
|
||||
(Ruff, "931") => (RuleGroup::Removed, rules::ruff::rules::AnotherRemovedTestRule),
|
||||
|
||||
|
||||
// flake8-django
|
||||
|
|
|
@ -236,6 +236,16 @@ pub fn check_path(
|
|||
}
|
||||
Rule::NurseryTestRule => test_rules::NurseryTestRule::diagnostic(locator, indexer),
|
||||
Rule::PreviewTestRule => test_rules::PreviewTestRule::diagnostic(locator, indexer),
|
||||
Rule::DeprecatedTestRule => {
|
||||
test_rules::DeprecatedTestRule::diagnostic(locator, indexer)
|
||||
}
|
||||
Rule::AnotherDeprecatedTestRule => {
|
||||
test_rules::AnotherDeprecatedTestRule::diagnostic(locator, indexer)
|
||||
}
|
||||
Rule::RemovedTestRule => test_rules::RemovedTestRule::diagnostic(locator, indexer),
|
||||
Rule::AnotherRemovedTestRule => {
|
||||
test_rules::AnotherRemovedTestRule::diagnostic(locator, indexer)
|
||||
}
|
||||
_ => unreachable!("All test rules must have an implementation"),
|
||||
};
|
||||
if let Some(diagnostic) = diagnostic {
|
||||
|
|
|
@ -39,6 +39,10 @@ pub(crate) const TEST_RULES: &[Rule] = &[
|
|||
Rule::StableTestRuleDisplayOnlyFix,
|
||||
Rule::PreviewTestRule,
|
||||
Rule::NurseryTestRule,
|
||||
Rule::DeprecatedTestRule,
|
||||
Rule::AnotherDeprecatedTestRule,
|
||||
Rule::RemovedTestRule,
|
||||
Rule::AnotherRemovedTestRule,
|
||||
];
|
||||
|
||||
pub(crate) trait TestRule {
|
||||
|
@ -254,6 +258,7 @@ impl TestRule for PreviewTestRule {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
|
@ -289,3 +294,147 @@ impl TestRule for NurseryTestRule {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Tests must pass!
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// bar
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct DeprecatedTestRule;
|
||||
|
||||
impl Violation for DeprecatedTestRule {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::None;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Hey this is a deprecated test rule.")
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRule for DeprecatedTestRule {
|
||||
fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option<Diagnostic> {
|
||||
Some(Diagnostic::new(
|
||||
DeprecatedTestRule,
|
||||
ruff_text_size::TextRange::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Tests must pass!
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// bar
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct AnotherDeprecatedTestRule;
|
||||
|
||||
impl Violation for AnotherDeprecatedTestRule {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::None;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Hey this is another deprecated test rule.")
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRule for AnotherDeprecatedTestRule {
|
||||
fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option<Diagnostic> {
|
||||
Some(Diagnostic::new(
|
||||
AnotherDeprecatedTestRule,
|
||||
ruff_text_size::TextRange::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Tests must pass!
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// bar
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct RemovedTestRule;
|
||||
|
||||
impl Violation for RemovedTestRule {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::None;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Hey this is a removed test rule.")
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRule for RemovedTestRule {
|
||||
fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option<Diagnostic> {
|
||||
Some(Diagnostic::new(
|
||||
RemovedTestRule,
|
||||
ruff_text_size::TextRange::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Tests must pass!
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// bar
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct AnotherRemovedTestRule;
|
||||
|
||||
impl Violation for AnotherRemovedTestRule {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::None;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Hey this is a another removed test rule.")
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRule for AnotherRemovedTestRule {
|
||||
fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option<Diagnostic> {
|
||||
Some(Diagnostic::new(
|
||||
AnotherRemovedTestRule,
|
||||
ruff_text_size::TextRange::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -909,7 +909,15 @@ impl LintConfiguration {
|
|||
}
|
||||
|
||||
// Check if the selector is empty because preview mode is disabled
|
||||
if selector.rules(&PreviewOptions::default()).next().is_none() {
|
||||
if selector.rules(&preview).next().is_none()
|
||||
&& selector
|
||||
.rules(&PreviewOptions {
|
||||
mode: PreviewMode::Enabled,
|
||||
require_explicit: preview.require_explicit,
|
||||
})
|
||||
.next()
|
||||
.is_some()
|
||||
{
|
||||
ignored_preview_selectors.insert(selector);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue