Repository: xd009642/tarpaulin
Pull request #1233 (2023-03-09 13:37:55)

Added filtering of attributes that end with 'test' like tokio::test
Addressing https://github.com/xd009642/tarpaulin/issues/1220

Added the ability to ignore functions that are prefixed with an attribute ending with `test`.
Added matching automated tests.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index a5b8d8c..7f668fd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -929,18 +929,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.153"
+version = "1.0.154"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a382c72b4ba118526e187430bb4963cd6d55051ebf13d9b25574d379cc98d20"
+checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.153"
+version = "1.0.154"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ef476a5790f0f6decbc66726b6e5d63680ed518283e64c7df415989d880954f"
+checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/src/source_analysis/attributes.rs b/src/source_analysis/attributes.rs
index c282baf..130e38a 100644
--- a/src/source_analysis/attributes.rs
+++ b/src/source_analysis/attributes.rs
@@ -1,6 +1,17 @@
 use crate::source_analysis::prelude::*;
 use syn::*;
 
+mod predicates {
+    pub fn is_test_attribute(id: &syn::Path) -> bool {
+        id.segments
+            .last()
+            .unwrap()
+            .ident
+            .to_string()
+            .ends_with("test")
+    }
+}
+
 impl SourceAnalysis {
     pub(crate) fn check_attr_list(&mut self, attrs: &[Attribute], ctx: &Context) -> bool {
         let analysis = self.get_line_analysis(ctx.file.to_path_buf());
@@ -71,6 +82,8 @@ pub(crate) fn check_cfg_attr(attr: &Meta) -> bool {
                 }
             }
         }
+    } else if predicates::is_test_attribute(id) {
+        ignore_span = true;
     } else {
         let skip_attrs = &["tarpaulin", "skip"];
         let mut n = 0;


Test patch:
diff --git a/src/source_analysis/tests.rs b/src/source_analysis/tests.rs
index dd89cb1..b95c39d 100644
--- a/src/source_analysis/tests.rs
+++ b/src/source_analysis/tests.rs
@@ -8,7 +8,7 @@ fn logical_lines_let_bindings() {
     let ctx = Context {
         config: &config,
         file_contents: "fn foo() {
-            let x 
+            let x
                   =
                     5;
         }",
@@ -60,12 +60,12 @@ fn match_pattern_logical_lines() {
         config: &config,
         file_contents: "fn foo(num: i32) -> bool {
             match num {
-            1 
+            1
             | 3
             | 5
             | 7
             | 9 => {
-                true 
+                true
                 },
             _ => false,
             }
@@ -413,8 +413,7 @@ fn filter_tests() {
             mod tests {
                 fn boo(){
                     assert!(true);
-                }
-            }",
+                }\n}",
         file: Path::new(""),
         ignore_mods: RefCell::new(HashSet::new()),
     };
@@ -450,6 +449,75 @@ fn filter_tests() {
     assert!(lines.ignore.contains(&Lines::Line(3)));
 }
 
+#[test]
+fn filter_nonstd_tests() {
+    let mut igconfig = Config::default();
+    igconfig.set_ignore_tests(true);
+
+    let ctx = Context {
+        config: &igconfig,
+        file_contents: "#[cfg(test)]
+            mod tests {
+                #[tokio::test(worker_threads = 1)]
+                fn boo(){
+                    assert!(true);
+                }
+            }",
+        file: Path::new(""),
+        ignore_mods: RefCell::new(HashSet::new()),
+    };
+    let parser = parse_file(ctx.file_contents).unwrap();
+    let mut analysis = SourceAnalysis::new();
+    analysis.process_items(&parser.items, &ctx);
+    let lines = analysis.get_line_analysis(ctx.file.to_path_buf());
+    assert!(lines.ignore.contains(&Lines::Line(5)));
+
+    let ctx = Context {
+        config: &igconfig,
+        file_contents: "#[tokio::test(worker_threads = 1)]
+                fn boo(){
+                    assert!(true);
+                }",
+        file: Path::new(""),
+        ignore_mods: RefCell::new(HashSet::new()),
+    };
+    let parser = parse_file(ctx.file_contents).unwrap();
+    let mut analysis = SourceAnalysis::new();
+    analysis.process_items(&parser.items, &ctx);
+    let lines = analysis.get_line_analysis(ctx.file.to_path_buf());
+    assert!(lines.ignore.contains(&Lines::Line(3)));
+
+    let ctx = Context {
+        config: &igconfig,
+        file_contents: "#[some_fancy_crate::test]
+                fn boo(){
+                    assert!(true);
+                }",
+        file: Path::new(""),
+        ignore_mods: RefCell::new(HashSet::new()),
+    };
+    let parser = parse_file(ctx.file_contents).unwrap();
+    let mut analysis = SourceAnalysis::new();
+    analysis.process_items(&parser.items, &ctx);
+    let lines = analysis.get_line_analysis(ctx.file.to_path_buf());
+    assert!(lines.ignore.contains(&Lines::Line(3)));
+
+    let ctx = Context {
+        config: &igconfig,
+        file_contents: "#[some_fancy_crate::marker_test]
+                fn boo(){
+                    assert!(true);
+                }",
+        file: Path::new(""),
+        ignore_mods: RefCell::new(HashSet::new()),
+    };
+    let parser = parse_file(ctx.file_contents).unwrap();
+    let mut analysis = SourceAnalysis::new();
+    analysis.process_items(&parser.items, &ctx);
+    let lines = analysis.get_line_analysis(ctx.file.to_path_buf());
+    assert!(lines.ignore.contains(&Lines::Line(3)));
+}
+
 #[test]
 fn filter_test_utilities() {
     let mut config = Config::default();
@@ -1408,14 +1476,14 @@ fn visit_generics() {
     let config = Config::default();
     let ctx = Context {
         config: &config,
-        file_contents: "fn blah<T>(t: T)  
+        file_contents: "fn blah<T>(t: T)
         where
             T: Clone,
             T: Eq
         {
             println!(\"{:?}\", t.clone());
         }
-        
+
         pub trait Foo<T> // 9
         where
             T: Clone