use super::RustTestFramework;
use syn::ItemFn;
pub struct FrameworkDetector;
impl FrameworkDetector {
pub fn new() -> Self {
Self
}
pub fn detect_framework(&self, func: &ItemFn) -> RustTestFramework {
for attr in &func.attrs {
if attr.path().is_ident("bench") {
return RustTestFramework::Criterion;
}
let path_str = attr
.path()
.segments
.iter()
.map(|seg| seg.ident.to_string())
.collect::<Vec<_>>()
.join("::");
if path_str.contains("proptest") {
return RustTestFramework::Proptest;
}
if path_str.contains("quickcheck") {
return RustTestFramework::Quickcheck;
}
if path_str.contains("rstest") {
return RustTestFramework::Rstest;
}
}
let tokens = quote::quote!(#func).to_string();
if tokens.contains("proptest!") {
return RustTestFramework::Proptest;
}
if tokens.contains("quickcheck!") {
return RustTestFramework::Quickcheck;
}
if self.has_criterion_signature(func) {
return RustTestFramework::Criterion;
}
RustTestFramework::Std
}
fn has_criterion_signature(&self, func: &ItemFn) -> bool {
func.sig.inputs.iter().any(|arg| {
if let syn::FnArg::Typed(pat_type) = arg {
let type_str = quote::quote!(#pat_type.ty).to_string();
type_str.contains("Bencher") || type_str.contains("Criterion")
} else {
false
}
})
}
pub fn is_property_testing(&self, framework: &RustTestFramework) -> bool {
matches!(
framework,
RustTestFramework::Proptest | RustTestFramework::Quickcheck
)
}
pub fn is_benchmarking(&self, framework: &RustTestFramework) -> bool {
matches!(framework, RustTestFramework::Criterion)
}
}
impl Default for FrameworkDetector {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use syn::parse_quote;
#[test]
fn test_detect_std_test() {
let detector = FrameworkDetector::new();
let func: ItemFn = parse_quote! {
#[test]
fn test_something() {
assert_eq!(1, 1);
}
};
assert_eq!(detector.detect_framework(&func), RustTestFramework::Std);
}
#[test]
fn test_detect_criterion() {
let detector = FrameworkDetector::new();
let func: ItemFn = parse_quote! {
#[bench]
fn bench_something(b: &mut Bencher) {
b.iter(|| 2 + 2);
}
};
assert_eq!(
detector.detect_framework(&func),
RustTestFramework::Criterion
);
}
#[test]
fn test_is_property_testing() {
let detector = FrameworkDetector::new();
assert!(detector.is_property_testing(&RustTestFramework::Proptest));
assert!(detector.is_property_testing(&RustTestFramework::Quickcheck));
assert!(!detector.is_property_testing(&RustTestFramework::Std));
}
#[test]
fn test_is_benchmarking() {
let detector = FrameworkDetector::new();
assert!(detector.is_benchmarking(&RustTestFramework::Criterion));
assert!(!detector.is_benchmarking(&RustTestFramework::Std));
}
}