mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-31 15:47:41 +00:00
Use insta_cmd (#6737)
This commit is contained in:
parent
7ead2c17b1
commit
e02d76f070
6 changed files with 423 additions and 311 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -1114,11 +1114,23 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
"regex",
|
||||
"serde",
|
||||
"similar",
|
||||
"walkdir",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "insta-cmd"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809d3023d1d6e8d5c2206f199251f75cb26180e41f18cb0f22dd119161cb5127"
|
||||
dependencies = [
|
||||
"insta",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
|
@ -2169,6 +2181,7 @@ dependencies = [
|
|||
"glob",
|
||||
"ignore",
|
||||
"insta",
|
||||
"insta-cmd",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"itoa",
|
||||
|
|
|
@ -70,7 +70,10 @@ wild = { version = "2" }
|
|||
|
||||
[dev-dependencies]
|
||||
assert_cmd = { version = "2.0.8" }
|
||||
# Avoid writing colored snapshots when running tests from the terminal
|
||||
colored = { workspace = true, features = ["no-color"]}
|
||||
insta = { workspace = true, features = ["filters"] }
|
||||
insta-cmd = { version = "0.4.0" }
|
||||
tempfile = "3.6.0"
|
||||
ureq = { version = "2.6.2", features = [] }
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#![cfg(not(target_family = "wasm"))]
|
||||
|
||||
use std::io::{ErrorKind, Read};
|
||||
use std::io::{ErrorKind, Read, Write};
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, TcpStream};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Stdio;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::{fs, process, str};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use assert_cmd::Command;
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use insta_cmd::get_cargo_bin;
|
||||
use log::info;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
|
@ -29,13 +29,14 @@ impl Blackd {
|
|||
// Get free TCP port to run on
|
||||
let address = TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?.local_addr()?;
|
||||
|
||||
let server = process::Command::new("blackd")
|
||||
.args([
|
||||
"--bind-host",
|
||||
&address.ip().to_string(),
|
||||
"--bind-port",
|
||||
&address.port().to_string(),
|
||||
])
|
||||
let args = [
|
||||
"--bind-host",
|
||||
&address.ip().to_string(),
|
||||
"--bind-port",
|
||||
&address.port().to_string(),
|
||||
];
|
||||
let server = Command::new("blackd")
|
||||
.args(args)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.spawn()
|
||||
|
@ -51,16 +52,16 @@ impl Blackd {
|
|||
Err(e) => return Err(e.into()),
|
||||
Ok(_) => {
|
||||
info!("`blackd` ready");
|
||||
break;
|
||||
return Ok(Self {
|
||||
address,
|
||||
server,
|
||||
client: ureq::agent(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
address,
|
||||
server,
|
||||
client: ureq::agent(),
|
||||
})
|
||||
bail!("blackd {:?} failed to start", args)
|
||||
}
|
||||
|
||||
/// Format given code with blackd.
|
||||
|
@ -104,34 +105,42 @@ fn run_test(path: &Path, blackd: &Blackd, ruff_args: &[&str]) -> Result<()> {
|
|||
let input = fs::read(path)?;
|
||||
|
||||
// Step 1: Run `ruff` on the input.
|
||||
let step_1 = &Command::cargo_bin(BIN_NAME)?
|
||||
let mut step_1 = Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(ruff_args)
|
||||
.write_stdin(input)
|
||||
.assert()
|
||||
.append_context("step", "running input through ruff");
|
||||
if !step_1.get_output().status.success() {
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
if let Some(mut stdin) = step_1.stdin.take() {
|
||||
stdin.write_all(input.as_ref())?;
|
||||
}
|
||||
let step_1_output = step_1.wait_with_output()?;
|
||||
if !step_1_output.status.success() {
|
||||
return Err(anyhow!(
|
||||
"Running input through ruff failed:\n{}",
|
||||
str::from_utf8(&step_1.get_output().stderr)?
|
||||
str::from_utf8(&step_1_output.stderr)?
|
||||
));
|
||||
}
|
||||
let step_1_output = step_1.get_output().stdout.clone();
|
||||
|
||||
// Step 2: Run `blackd` on the input.
|
||||
let step_2_output = blackd.check(&step_1_output)?;
|
||||
let step_2_output = blackd.check(&step_1_output.stdout.clone())?;
|
||||
|
||||
// Step 3: Re-run `ruff` on the input.
|
||||
let step_3 = &Command::cargo_bin(BIN_NAME)?
|
||||
let mut step_3 = Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(ruff_args)
|
||||
.write_stdin(step_2_output.clone())
|
||||
.assert();
|
||||
if !step_3.get_output().status.success() {
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
if let Some(mut stdin) = step_3.stdin.take() {
|
||||
stdin.write_all(step_2_output.as_ref())?;
|
||||
}
|
||||
let step_3_output = step_3.wait_with_output()?;
|
||||
if !step_3_output.status.success() {
|
||||
return Err(anyhow!(
|
||||
"Running input through ruff after black failed:\n{}",
|
||||
str::from_utf8(&step_3.get_output().stderr)?
|
||||
str::from_utf8(&step_3_output.stderr)?
|
||||
));
|
||||
}
|
||||
let step_3_output = step_3.get_output().stdout.clone();
|
||||
let step_3_output = step_3_output.stdout.clone();
|
||||
|
||||
assert_eq!(
|
||||
str::from_utf8(&step_2_output),
|
||||
|
@ -177,11 +186,13 @@ fn test_ruff_black_compatibility() -> Result<()> {
|
|||
"--fix",
|
||||
"--line-length",
|
||||
"88",
|
||||
"--select ALL",
|
||||
"--select",
|
||||
"ALL",
|
||||
// Exclude ruff codes, specifically RUF100, because it causes differences that are not a
|
||||
// problem. Ruff would add a `# noqa: W292` after the first run, black introduces a
|
||||
// newline, and ruff removes the `# noqa: W292` again.
|
||||
"--ignore RUF",
|
||||
"--ignore",
|
||||
"RUF",
|
||||
];
|
||||
|
||||
for entry in paths {
|
||||
|
|
|
@ -8,14 +8,15 @@ use std::fs::Permissions;
|
|||
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
||||
#[cfg(unix)]
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
#[cfg(unix)]
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use assert_cmd::Command;
|
||||
#[cfg(unix)]
|
||||
use clap::Parser;
|
||||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||
#[cfg(unix)]
|
||||
use path_absolutize::path_dedot;
|
||||
#[cfg(unix)]
|
||||
|
@ -27,315 +28,280 @@ use ruff_cli::args::Args;
|
|||
use ruff_cli::run;
|
||||
|
||||
const BIN_NAME: &str = "ruff";
|
||||
const STDIN_BASE_OPTIONS: &[&str] = &["--isolated", "--no-cache", "-", "--format", "text"];
|
||||
|
||||
#[test]
|
||||
fn stdin_success() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
cmd.args(["-", "--format", "text", "--isolated"])
|
||||
.write_stdin("")
|
||||
.assert()
|
||||
.success();
|
||||
Ok(())
|
||||
fn stdin_success() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.pass_stdin(""), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_error() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--isolated"])
|
||||
.write_stdin("import os\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"-:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
"#
|
||||
);
|
||||
Ok(())
|
||||
fn stdin_error() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.pass_stdin("import os\n"), @r#"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_filename() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args([
|
||||
"-",
|
||||
"--format",
|
||||
"text",
|
||||
"--stdin-filename",
|
||||
"F401.py",
|
||||
"--isolated",
|
||||
])
|
||||
.write_stdin("import os\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"F401.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
"#
|
||||
);
|
||||
Ok(())
|
||||
fn stdin_filename() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(["--stdin-filename", "F401.py"])
|
||||
.pass_stdin("import os\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
F401.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_source_type() -> Result<()> {
|
||||
// Raise `TCH` errors in `.py` files.
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args([
|
||||
"-",
|
||||
"--format",
|
||||
"text",
|
||||
"--stdin-filename",
|
||||
"TCH.py",
|
||||
"--isolated",
|
||||
])
|
||||
.write_stdin("import os\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"TCH.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
"#
|
||||
);
|
||||
/// Raise `TCH` errors in `.py` files ...
|
||||
fn stdin_source_type_py() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(["--stdin-filename", "TCH.py"])
|
||||
.pass_stdin("import os\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
TCH.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
|
||||
// But not in `.pyi` files.
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
cmd.args([
|
||||
"-",
|
||||
"--format",
|
||||
"text",
|
||||
"--stdin-filename",
|
||||
"TCH.pyi",
|
||||
"--isolated",
|
||||
"--select",
|
||||
"TCH",
|
||||
])
|
||||
.write_stdin("import os\n")
|
||||
.assert()
|
||||
.success();
|
||||
Ok(())
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
/// ... but not in `.pyi` files.
|
||||
#[test]
|
||||
fn stdin_source_type_pyi() {
|
||||
let args = ["--stdin-filename", "TCH.pyi", "--select", "TCH"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("import os\n"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn stdin_json() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args([
|
||||
"-",
|
||||
"--format",
|
||||
"json",
|
||||
"--stdin-filename",
|
||||
"F401.py",
|
||||
"--isolated",
|
||||
])
|
||||
.write_stdin("import os\n")
|
||||
.assert()
|
||||
.failure();
|
||||
fn stdin_json() {
|
||||
let args = [
|
||||
"-",
|
||||
"--isolated",
|
||||
"--no-cache",
|
||||
"--format",
|
||||
"json",
|
||||
"--stdin-filename",
|
||||
"F401.py",
|
||||
];
|
||||
|
||||
let directory = path_dedot::CWD.to_str().unwrap();
|
||||
let binding = Path::new(directory).join("F401.py");
|
||||
let file_path = binding.display();
|
||||
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
format!(
|
||||
r#"[
|
||||
{{
|
||||
"code": "F401",
|
||||
"end_location": {{
|
||||
"column": 10,
|
||||
"row": 1
|
||||
}},
|
||||
"filename": "{file_path}",
|
||||
"fix": {{
|
||||
"applicability": "Automatic",
|
||||
"edits": [
|
||||
{{
|
||||
"content": "",
|
||||
"end_location": {{
|
||||
"column": 1,
|
||||
"row": 2
|
||||
}},
|
||||
"location": {{
|
||||
"column": 1,
|
||||
"row": 1
|
||||
}}
|
||||
}}
|
||||
],
|
||||
"message": "Remove unused import: `os`"
|
||||
}},
|
||||
"location": {{
|
||||
"column": 8,
|
||||
"row": 1
|
||||
}},
|
||||
"message": "`os` imported but unused",
|
||||
"noqa_row": 1,
|
||||
"url": "https://beta.ruff.rs/docs/rules/unused-import"
|
||||
}}
|
||||
]"#
|
||||
)
|
||||
);
|
||||
Ok(())
|
||||
insta::with_settings!({filters => vec![
|
||||
(file_path.to_string().as_str(), "/path/to/F401.py"),
|
||||
]}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(args)
|
||||
.pass_stdin("import os\n"));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_autofix() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--fix", "--isolated"])
|
||||
.write_stdin("import os\nimport sys\n\nprint(sys.version)\n")
|
||||
.assert()
|
||||
.success();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
"import sys\n\nprint(sys.version)\n"
|
||||
);
|
||||
Ok(())
|
||||
fn stdin_autofix() {
|
||||
let args = ["--fix"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("import os\nimport sys\n\nprint(sys.version)\n"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
import sys
|
||||
|
||||
print(sys.version)
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_autofix_when_not_fixable_should_still_print_contents() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--fix", "--isolated"])
|
||||
.write_stdin("import os\nimport sys\n\nif (1, 2):\n print(sys.version)\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
"import sys\n\nif (1, 2):\n print(sys.version)\n"
|
||||
);
|
||||
Ok(())
|
||||
fn stdin_autofix_when_not_fixable_should_still_print_contents() {
|
||||
let args = ["--fix"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("import os\nimport sys\n\nif (1, 2):\n print(sys.version)\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
import sys
|
||||
|
||||
if (1, 2):
|
||||
print(sys.version)
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_autofix_when_no_issues_should_still_print_contents() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--fix", "--isolated"])
|
||||
.write_stdin("import sys\n\nprint(sys.version)\n")
|
||||
.assert()
|
||||
.success();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
"import sys\n\nprint(sys.version)\n"
|
||||
);
|
||||
Ok(())
|
||||
fn stdin_autofix_when_no_issues_should_still_print_contents() {
|
||||
let args = ["--fix"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("import sys\n\nprint(sys.version)\n"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
import sys
|
||||
|
||||
print(sys.version)
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_source() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--show-source", "--isolated"])
|
||||
.write_stdin("l = 1")
|
||||
.assert()
|
||||
.failure();
|
||||
assert!(str::from_utf8(&output.get_output().stdout)?.contains("l = 1"));
|
||||
Ok(())
|
||||
fn show_source() {
|
||||
let args = ["--show-source"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("l = 1"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
|
|
||||
1 | l = 1
|
||||
| ^ E741
|
||||
|
|
||||
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explain_status_codes() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
cmd.args(["--explain", "F401"]).assert().success();
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
cmd.args(["--explain", "RUF404"]).assert().failure();
|
||||
Ok(())
|
||||
fn explain_status_codes_f401() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)).args(["--explain", "F401"]));
|
||||
}
|
||||
#[test]
|
||||
fn explain_status_codes_ruf404() {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)).args(["--explain", "RUF404"]), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: invalid value 'RUF404' for '[RULE]': unknown rule code
|
||||
|
||||
For more information, try '--help'.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_statistics() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
.args([
|
||||
"-",
|
||||
"--format",
|
||||
"text",
|
||||
"--select",
|
||||
"F401",
|
||||
"--statistics",
|
||||
"--isolated",
|
||||
])
|
||||
.write_stdin("import sys\nimport os\n\nprint(os.getuid())\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?
|
||||
.lines()
|
||||
.last()
|
||||
.unwrap(),
|
||||
"1\tF401\t[*] `sys` imported but unused"
|
||||
);
|
||||
Ok(())
|
||||
fn show_statistics() {
|
||||
let args = ["--select", "F401", "--statistics"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
1 F401 [*] `sys` imported but unused
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_prefix() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
|
||||
fn nursery_prefix() {
|
||||
// `--select E` should detect E741, but not E225, which is in the nursery.
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--isolated", "--select", "E"])
|
||||
.write_stdin("I=42\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"-:1:1: E741 Ambiguous variable name: `I`
|
||||
Found 1 error.
|
||||
"#
|
||||
);
|
||||
let args = ["--select", "E"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("I=42\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `I`
|
||||
Found 1 error.
|
||||
|
||||
Ok(())
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_all() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
|
||||
fn nursery_all() {
|
||||
// `--select ALL` should detect E741, but not E225, which is in the nursery.
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--isolated", "--select", "E"])
|
||||
.write_stdin("I=42\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"-:1:1: E741 Ambiguous variable name: `I`
|
||||
Found 1 error.
|
||||
"#
|
||||
);
|
||||
let args = ["--select", "ALL"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("I=42\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `I`
|
||||
-:1:1: D100 Missing docstring in public module
|
||||
Found 2 errors.
|
||||
|
||||
Ok(())
|
||||
----- stderr -----
|
||||
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
|
||||
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_direct() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
|
||||
fn nursery_direct() {
|
||||
// `--select E225` should detect E225.
|
||||
let output = cmd
|
||||
.args(["-", "--format", "text", "--isolated", "--select", "E225"])
|
||||
.write_stdin("I=42\n")
|
||||
.assert()
|
||||
.failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
r#"-:1:2: E225 Missing whitespace around operator
|
||||
Found 1 error.
|
||||
"#
|
||||
);
|
||||
let args = ["--select", "E225"];
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(STDIN_BASE_OPTIONS)
|
||||
.args(args)
|
||||
.pass_stdin("I=42\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:2: E225 Missing whitespace around operator
|
||||
Found 1 error.
|
||||
|
||||
Ok(())
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
/// An unreadable pyproject.toml in non-isolated mode causes ruff to hard-error trying to build up
|
||||
|
@ -376,17 +342,17 @@ fn unreadable_dir() -> Result<()> {
|
|||
|
||||
// We (currently?) have to use a subcommand to check exit status (currently wrong) and logging
|
||||
// output
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd
|
||||
// TODO(konstin): This should be a failure, but we currently can't track that
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(["--no-cache", "--isolated"])
|
||||
.arg(&unreadable_dir)
|
||||
.assert()
|
||||
// TODO(konstin): This should be a failure, but we currently can't track that
|
||||
.success();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stderr)?,
|
||||
"warning: Encountered error: Permission denied (os error 13)\n"
|
||||
);
|
||||
.arg(&unreadable_dir), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
warning: Encountered error: Permission denied (os error 13)
|
||||
"###);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -416,17 +382,22 @@ fn check_input_from_argfile() -> Result<()> {
|
|||
format!("@{}", &input_file_path.display()),
|
||||
];
|
||||
|
||||
let mut cmd = Command::cargo_bin(BIN_NAME)?;
|
||||
let output = cmd.args(args).write_stdin("").assert().failure();
|
||||
assert_eq!(
|
||||
str::from_utf8(&output.get_output().stdout)?,
|
||||
format!(
|
||||
"{}:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
",
|
||||
file_a_path.display()
|
||||
)
|
||||
);
|
||||
insta::with_settings!({filters => vec![
|
||||
(file_a_path.display().to_string().as_str(), "/path/to/a.py"),
|
||||
]}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(args)
|
||||
.pass_stdin(""), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
/path/to/a.py:1:8: F401 [*] `os` imported but unused
|
||||
Found 1 error.
|
||||
[*] 1 potentially fixable with the --fix option.
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
source: crates/ruff_cli/tests/integration_test.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- "--explain"
|
||||
- F401
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# unused-import (F401)
|
||||
|
||||
Derived from the **Pyflakes** linter.
|
||||
|
||||
Autofix is sometimes available.
|
||||
|
||||
## What it does
|
||||
Checks for unused imports.
|
||||
|
||||
## Why is this bad?
|
||||
Unused imports add a performance overhead at runtime, and risk creating
|
||||
import cycles. They also increase the cognitive load of reading the code.
|
||||
|
||||
If an import statement is used to check for the availability or existence
|
||||
of a module, consider using `importlib.util.find_spec` instead.
|
||||
|
||||
## Example
|
||||
```python
|
||||
import numpy as np # unused import
|
||||
|
||||
|
||||
def area(radius):
|
||||
return 3.14 * radius**2
|
||||
```
|
||||
|
||||
Use instead:
|
||||
```python
|
||||
def area(radius):
|
||||
return 3.14 * radius**2
|
||||
```
|
||||
|
||||
To check the availability of a module, use `importlib.util.find_spec`:
|
||||
```python
|
||||
from importlib.util import find_spec
|
||||
|
||||
if find_spec("numpy") is not None:
|
||||
print("numpy is installed")
|
||||
else:
|
||||
print("numpy is not installed")
|
||||
```
|
||||
|
||||
## Options
|
||||
- `pyflakes.extend-generics`
|
||||
|
||||
## References
|
||||
- [Python documentation: `import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement)
|
||||
- [Python documentation: `importlib.util.find_spec`](https://docs.python.org/3/library/importlib.html#importlib.util.find_spec)
|
||||
|
||||
----- stderr -----
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
source: crates/ruff_cli/tests/integration_test.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- "-"
|
||||
- "--isolated"
|
||||
- "--no-cache"
|
||||
- "--format"
|
||||
- json
|
||||
- "--stdin-filename"
|
||||
- F401.py
|
||||
stdin: "import os\n"
|
||||
---
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
[
|
||||
{
|
||||
"code": "F401",
|
||||
"end_location": {
|
||||
"column": 10,
|
||||
"row": 1
|
||||
},
|
||||
"filename": "/path/to/F401.py",
|
||||
"fix": {
|
||||
"applicability": "Automatic",
|
||||
"edits": [
|
||||
{
|
||||
"content": "",
|
||||
"end_location": {
|
||||
"column": 1,
|
||||
"row": 2
|
||||
},
|
||||
"location": {
|
||||
"column": 1,
|
||||
"row": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": "Remove unused import: `os`"
|
||||
},
|
||||
"location": {
|
||||
"column": 8,
|
||||
"row": 1
|
||||
},
|
||||
"message": "`os` imported but unused",
|
||||
"noqa_row": 1,
|
||||
"url": "https://beta.ruff.rs/docs/rules/unused-import"
|
||||
}
|
||||
]
|
||||
----- stderr -----
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue