mirror of
https://github.com/astral-sh/ruff
synced 2026-01-22 14:00:51 -05:00
Add unit tests for linter (#9)
This commit is contained in:
@@ -2,19 +2,14 @@ use std::collections::HashSet;
|
||||
|
||||
use rustpython_parser::ast::{Arg, Arguments, ExprKind, Stmt, StmtKind, Suite};
|
||||
|
||||
use crate::check::{Check, CheckKind};
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::visitor::{walk_arguments, walk_stmt, Visitor};
|
||||
|
||||
#[derive(Default)]
|
||||
struct Checker {
|
||||
checks: Vec<Check>,
|
||||
}
|
||||
|
||||
impl Checker {
|
||||
fn new() -> Self {
|
||||
Checker { checks: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor for Checker {
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) {
|
||||
match &stmt.node {
|
||||
@@ -79,9 +74,46 @@ pub fn check_ast(python_ast: &Suite) -> Vec<Check> {
|
||||
python_ast
|
||||
.iter()
|
||||
.flat_map(|stmt| {
|
||||
let mut checker = Checker::new();
|
||||
let mut checker: Checker = Default::default();
|
||||
checker.visit_stmt(stmt);
|
||||
checker.checks
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rustpython_parser::ast::{Alias, Location, Stmt, StmtKind};
|
||||
|
||||
use crate::checker::Checker;
|
||||
use crate::checks::Check;
|
||||
use crate::checks::CheckKind::ImportStarUsage;
|
||||
use crate::visitor::Visitor;
|
||||
|
||||
#[test]
|
||||
fn import_star_usage() {
|
||||
let mut checker: Checker = Default::default();
|
||||
checker.visit_stmt(&Stmt {
|
||||
location: Location::new(1, 1),
|
||||
custom: (),
|
||||
node: StmtKind::ImportFrom {
|
||||
module: Some("bar".to_string()),
|
||||
names: vec![Alias {
|
||||
name: "*".to_string(),
|
||||
asname: None,
|
||||
}],
|
||||
level: 0,
|
||||
},
|
||||
});
|
||||
|
||||
let actual = checker.checks;
|
||||
let expected = vec![Check {
|
||||
kind: ImportStarUsage,
|
||||
location: Location::new(1, 1),
|
||||
}];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 1..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CheckKind {
|
||||
DuplicateArgumentName,
|
||||
ImportStarUsage,
|
||||
@@ -28,6 +28,7 @@ impl CheckKind {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Check {
|
||||
pub kind: CheckKind,
|
||||
pub location: Location,
|
||||
@@ -1,6 +1,6 @@
|
||||
mod cache;
|
||||
mod check;
|
||||
pub mod checker;
|
||||
mod checks;
|
||||
pub mod fs;
|
||||
pub mod linter;
|
||||
pub mod logging;
|
||||
|
||||
@@ -28,3 +28,92 @@ pub fn check_path(path: &Path, mode: &cache::Mode) -> Result<Vec<Message>> {
|
||||
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::cache;
|
||||
use crate::checks::CheckKind::{DuplicateArgumentName, IfTuple, ImportStarUsage};
|
||||
use crate::linter::check_path;
|
||||
use crate::message::Message;
|
||||
|
||||
#[test]
|
||||
fn duplicate_argument_name() -> Result<()> {
|
||||
let actual = check_path(
|
||||
&Path::new("./resources/test/src/duplicate_argument_name.py"),
|
||||
&cache::Mode::None,
|
||||
)?;
|
||||
let expected = vec![
|
||||
Message {
|
||||
kind: DuplicateArgumentName,
|
||||
location: Location::new(1, 25),
|
||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||
},
|
||||
Message {
|
||||
kind: DuplicateArgumentName,
|
||||
location: Location::new(5, 9),
|
||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||
},
|
||||
Message {
|
||||
kind: DuplicateArgumentName,
|
||||
location: Location::new(9, 27),
|
||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||
},
|
||||
];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 1..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_tuple() -> Result<()> {
|
||||
let actual = check_path(
|
||||
&Path::new("./resources/test/src/if_tuple.py"),
|
||||
&cache::Mode::None,
|
||||
)?;
|
||||
let expected = vec![
|
||||
Message {
|
||||
kind: IfTuple,
|
||||
location: Location::new(1, 1),
|
||||
filename: "./resources/test/src/if_tuple.py".to_string(),
|
||||
},
|
||||
Message {
|
||||
kind: IfTuple,
|
||||
location: Location::new(7, 5),
|
||||
filename: "./resources/test/src/if_tuple.py".to_string(),
|
||||
},
|
||||
];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 1..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_star_usage() -> Result<()> {
|
||||
let actual = check_path(
|
||||
&Path::new("./resources/test/src/import_star_usage.py"),
|
||||
&cache::Mode::None,
|
||||
)?;
|
||||
let expected = vec![Message {
|
||||
kind: ImportStarUsage,
|
||||
location: Location::new(1, 1),
|
||||
filename: "./resources/test/src/import_star_usage.py".to_string(),
|
||||
}];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 1..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use colored::Colorize;
|
||||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::check::CheckKind;
|
||||
use crate::checks::CheckKind;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(remote = "Location")]
|
||||
@@ -21,7 +21,7 @@ impl From<LocationDef> for Location {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
pub kind: CheckKind,
|
||||
#[serde(with = "LocationDef")]
|
||||
|
||||
Reference in New Issue
Block a user