mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 06:42:02 +00:00
Add unit tests for linter (#9)
This commit is contained in:
parent
52afc02023
commit
4a67c8d44b
10 changed files with 168 additions and 18 deletions
22
.github/workflows/ci.yaml
vendored
22
.github/workflows/ci.yaml
vendored
|
@ -73,6 +73,28 @@ jobs:
|
|||
${{ runner.os }}-
|
||||
- run: cargo clippy -- -D warnings
|
||||
|
||||
cargo_test:
|
||||
name: "cargo test"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: cache-cargo
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
${{ runner.os }}-build-
|
||||
${{ runner.os }}-
|
||||
- run: cargo test
|
||||
|
||||
maturin_build:
|
||||
name: "maturin build"
|
||||
runs-on: ubuntu-latest
|
||||
|
|
10
resources/test/src/duplicate_argument_name.py
Normal file
10
resources/test/src/duplicate_argument_name.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
def foo(x: int, y: int, x: int) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def bar(x: int, y: int, *, x: int) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def baz(x: int, y: int, **x: int) -> None:
|
||||
pass
|
|
@ -1,5 +0,0 @@
|
|||
from bar import *
|
||||
|
||||
|
||||
def baz(x: int, x: int) -> None:
|
||||
pass
|
|
@ -4,5 +4,5 @@ if (1, 2):
|
|||
for _ in range(5):
|
||||
if True:
|
||||
pass
|
||||
elif (1, 2):
|
||||
elif (3, 4):
|
||||
pass
|
1
resources/test/src/import_star_usage.py
Normal file
1
resources/test/src/import_star_usage.py
Normal file
|
@ -0,0 +1 @@
|
|||
from if_tuple import *
|
|
@ -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")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue