diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-21 15:55:11 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-21 15:55:11 +0800 |
| commit | 770d738829076e0be2152452ab68933a47a483e2 (patch) | |
| tree | 1d4ed37639ef4aca019c5139dfaa5cabec9976b8 /mingling_cli | |
| parent | 0056e1095e75b34f39cde7de87ce6be2cd301ff1 (diff) | |
feat: add testing macros and unit tests for linters
Add `assert_detected!` and `assert_not_detected!` macros to simplify
writing lint tests, along with initial test coverage for the
unnecessary render result creation linter.
Diffstat (limited to 'mingling_cli')
| -rw-r--r-- | mingling_cli/src/lints.rs | 18 | ||||
| -rw-r--r-- | mingling_cli/src/lints/template_linter.rs | 8 | ||||
| -rw-r--r-- | mingling_cli/src/lints/unnecessary_render_result_creation.rs | 85 | ||||
| -rw-r--r-- | mingling_cli/tmpls/lints.tmpl | 18 |
4 files changed, 129 insertions, 0 deletions
diff --git a/mingling_cli/src/lints.rs b/mingling_cli/src/lints.rs index 5bed483..8fab924 100644 --- a/mingling_cli/src/lints.rs +++ b/mingling_cli/src/lints.rs @@ -58,4 +58,22 @@ pub fn run_all_lints(file: &syn::File, source: &str) -> Vec<MlintReport> { // Remove allowed reports (sentinel = Help) reports.retain(|r| r.level != MlintLevel::Help); reports +} + +#[macro_export] +macro_rules! assert_detected { + ($linter:expr, $ast_type:ty => $code:tt) => { + // Parse the string into a syn::ItemFn + let ast: $ast_type = syn::parse_str(&stringify!($code)).unwrap(); + assert!(!$linter(ast, &stringify!($code).to_string()).is_empty()); + }; +} + +#[macro_export] +macro_rules! assert_not_detected { + ($linter:expr, $ast_type:ty => $code:tt) => { + // Parse the string into a syn::ItemFn + let ast: $ast_type = syn::parse_str(&stringify!($code)).unwrap(); + assert!($linter(ast, &stringify!($code).to_string()).is_empty()); + }; }
\ No newline at end of file diff --git a/mingling_cli/src/lints/template_linter.rs b/mingling_cli/src/lints/template_linter.rs index 4ea2f94..271aa0c 100644 --- a/mingling_cli/src/lints/template_linter.rs +++ b/mingling_cli/src/lints/template_linter.rs @@ -46,3 +46,11 @@ pub fn linter(_ast: syn::ItemFn, _source: &str) -> Vec<MlintReport> { // | syn::ItemUnion vec![] } + +#[cfg(test)] +mod lint_test { + use crate::{assert_detected, assert_not_detected}; + + #[test] + fn test() {} +} diff --git a/mingling_cli/src/lints/unnecessary_render_result_creation.rs b/mingling_cli/src/lints/unnecessary_render_result_creation.rs index aa0f4a6..06c47d9 100644 --- a/mingling_cli/src/lints/unnecessary_render_result_creation.rs +++ b/mingling_cli/src/lints/unnecessary_render_result_creation.rs @@ -172,3 +172,88 @@ fn check_stmt_usage(stmt: &syn::Stmt, r_name: &str, print_count: &mut usize) -> let s = format!("{stmt:#?}"); !s.contains(&format!("\"{r_name}\"")) } + +#[cfg(test)] +mod lint_test { + use crate::{assert_detected, assert_not_detected}; + + #[test] + fn test_detected_render_result_new() { + assert_detected!(super::linter, syn::ItemFn => { + #[renderer] + fn render_somesthing(_: Prev) -> RenderResult { + let mut r = RenderResult::new(); + r_println!(r, ""); + r + } + }); + } + + #[test] + fn test_detected_render_result_default() { + assert_detected!(super::linter, syn::ItemFn => { + #[renderer] + fn render_somesthing(_: Prev) -> RenderResult { + let mut r = RenderResult::default(); + r_println!(r, ""); + r + } + }); + } + + #[test] + fn test_detected_render_result_from() { + assert_detected!(super::linter, syn::ItemFn => { + #[renderer] + fn render_somesthing(_: Prev) -> RenderResult { + let mut r = RenderResult::from("Hello".to_string()); + r_println!(r, ""); + r + } + }); + } + + #[test] + fn test_not_detected_with_other_function_call() { + assert_not_detected!(super::linter, syn::ItemFn => { + #[renderer] + fn render_somesthing(_: Prev) -> RenderResult { + let mut r = RenderResult::new(); + r_println!(r, ""); + other(&mut r); + r + } + }); + } + + #[test] + fn test_not_detected_without_renderer_attr() { + assert_not_detected!(super::linter, syn::ItemFn => { + fn render_somesthing(_: Prev) -> RenderResult { + let mut r = RenderResult::new(); + r_println!(r, ""); + r + } + }); + } + + #[test] + fn test_not_detected_with_buffer_attr() { + assert_not_detected!(super::linter, syn::ItemFn => { + #[::mingling::macros::renderer(::mingling::macros::buffer)] + fn render_somesthing(_: Prev) { + r_println!(""); + } + }); + } + + #[test] + fn test_not_detected_with_buffer_attr_fully_qualified() { + assert_not_detected!(super::linter, syn::ItemFn => { + #[::mingling::macros::renderer(::mingling::macros::buffer)] + fn render_somesthing(_: Prev) { + r_println!(""); + } + }); + } +} diff --git a/mingling_cli/tmpls/lints.tmpl b/mingling_cli/tmpls/lints.tmpl index 7507f98..fae1126 100644 --- a/mingling_cli/tmpls/lints.tmpl +++ b/mingling_cli/tmpls/lints.tmpl @@ -50,6 +50,24 @@ pub fn run_all_lints(file: &syn::File, source: &str) -> Vec<MlintReport> { reports } +#[macro_export] +macro_rules! assert_detected { + ($linter:expr, $ast_type:ty => $code:tt) => { + // Parse the string into a syn::ItemFn + let ast: $ast_type = syn::parse_str(&stringify!($code)).unwrap(); + assert!(!$linter(ast, &stringify!($code).to_string()).is_empty()); + }; +} + +#[macro_export] +macro_rules! assert_not_detected { + ($linter:expr, $ast_type:ty => $code:tt) => { + // Parse the string into a syn::ItemFn + let ast: $ast_type = syn::parse_str(&stringify!($code)).unwrap(); + assert!($linter(ast, &stringify!($code).to_string()).is_empty()); + }; +} + @@@ >>> impls mod <<<mod_name>>>; pub use <<<mod_name>>>::linter as <<<mod_name>>>; |
