Repository: rust-analyzer/rust-analyzer
Pull request #606 (2019-01-23 12:40:19)

generalize marking infrastructure


Patch:
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 361d39f03e..33a9ba6059 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -8,7 +8,7 @@
 pub mod db;
 #[cfg(test)]
 mod mock;
-#[macro_use]
+#[cfg(test)]
 mod marks;
 mod query_definitions;
 mod path;
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs
index 05430b975c..6aff2c4e1e 100644
--- a/crates/ra_hir/src/marks.rs
+++ b/crates/ra_hir/src/marks.rs
@@ -1,82 +1,1 @@
-//! This module implements manually tracked test coverage, which useful for
-//! quickly finding a test responsible for testing a particular bit of code.
-//!
-//! See https://matklad.github.io/2018/06/18/a-trick-for-test-maintenance.html
-//! for details, but the TL;DR is that you write your test as
-//!
-//! ```no-run
-//! #[test]
-//! fn test_foo() {
-//!     covers!(test_foo);
-//! }
-//! ```
-//!
-//! and in the code under test you write
-//!
-//! ```no-run
-//! fn foo() {
-//!     if some_condition() {
-//!         tested_by!(test_foo);
-//!     }
-//! }
-//! ```
-//!
-//! This module then checks that executing the test indeed covers the specified
-//! function. This is useful if you come back to the `foo` function ten years
-//! later and wonder where the test are: now you can grep for `test_foo`.
-
-#[macro_export]
-macro_rules! tested_by {
-    ($ident:ident) => {
-        #[cfg(test)]
-        {
-            crate::marks::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
-        }
-    };
-}
-
-#[macro_export]
-macro_rules! covers {
-    ($ident:ident) => {
-        let _checker = crate::marks::marks::MarkChecker::new(&crate::marks::marks::$ident);
-    };
-}
-
-#[cfg(test)]
-pub(crate) mod marks {
-    use std::sync::atomic::{AtomicUsize, Ordering};
-
-    pub(crate) struct MarkChecker {
-        mark: &'static AtomicUsize,
-        value_on_entry: usize,
-    }
-
-    impl MarkChecker {
-        pub(crate) fn new(mark: &'static AtomicUsize) -> MarkChecker {
-            let value_on_entry = mark.load(Ordering::SeqCst);
-            MarkChecker {
-                mark,
-                value_on_entry,
-            }
-        }
-    }
-
-    impl Drop for MarkChecker {
-        fn drop(&mut self) {
-            if std::thread::panicking() {
-                return;
-            }
-            let value_on_exit = self.mark.load(Ordering::SeqCst);
-            assert!(value_on_exit > self.value_on_entry, "mark was not hit")
-        }
-    }
-
-    macro_rules! mark {
-        ($ident:ident) => {
-            #[allow(bad_style)]
-            pub(crate) static $ident: AtomicUsize = AtomicUsize::new(0);
-        };
-    }
-
-    mark!(name_res_works_for_broken_modules);
-}
+test_utils::mark!(name_res_works_for_broken_modules);
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs
index 0256d79968..47c14af35b 100644
--- a/crates/ra_hir/src/module_tree.rs
+++ b/crates/ra_hir/src/module_tree.rs
@@ -10,6 +10,7 @@ use ra_syntax::{
     ast::{self, AstNode, NameOwner},
 };
 use ra_arena::{Arena, RawId, impl_arena_id};
+use test_utils::tested_by;
 
 use crate::{Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource};
 


Test patch:
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 0ec11ec127..e920074533 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -2,7 +2,7 @@ use std::sync::Arc;
 
 use ra_db::{FilesDatabase, CrateGraph, SourceRootId, salsa::Database};
 use relative_path::RelativePath;
-use test_utils::assert_eq_text;
+use test_utils::{assert_eq_text, covers};
 
 use crate::{
     ItemMap, Resolution,
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 6489033dde..35a679aea5 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -1,5 +1,10 @@
-use std::fs;
-use std::path::{Path, PathBuf};
+#[macro_use]
+pub mod marks;
+
+use std::{
+    fs,
+    path::{Path, PathBuf}
+};
 
 use text_unit::{TextRange, TextUnit};
 use serde_json::Value;
diff --git a/crates/test_utils/src/marks.rs b/crates/test_utils/src/marks.rs
new file mode 100644
index 0000000000..79ffedf69b
--- /dev/null
+++ b/crates/test_utils/src/marks.rs
@@ -0,0 +1,80 @@
+//! This module implements manually tracked test coverage, which useful for
+//! quickly finding a test responsible for testing a particular bit of code.
+//!
+//! See https://matklad.github.io/2018/06/18/a-trick-for-test-maintenance.html
+//! for details, but the TL;DR is that you write your test as
+//!
+//! ```no-run
+//! #[test]
+//! fn test_foo() {
+//!     covers!(test_foo);
+//! }
+//! ```
+//!
+//! and in the code under test you write
+//!
+//! ```no-run
+//! fn foo() {
+//!     if some_condition() {
+//!         tested_by!(test_foo);
+//!     }
+//! }
+//! ```
+//!
+//! This module then checks that executing the test indeed covers the specified
+//! function. This is useful if you come back to the `foo` function ten years
+//! later and wonder where the test are: now you can grep for `test_foo`.
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+#[macro_export]
+macro_rules! tested_by {
+    ($ident:ident) => {
+        #[cfg(test)]
+        {
+            // sic! use call-site crate
+            crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! covers {
+    ($ident:ident) => {
+        // sic! use call-site crate
+        let _checker = $crate::marks::MarkChecker::new(&crate::marks::$ident);
+    };
+}
+
+#[macro_export]
+macro_rules! mark {
+    ($ident:ident) => {
+        #[allow(bad_style)]
+        pub(crate) static $ident: std::sync::atomic::AtomicUsize =
+            std::sync::atomic::AtomicUsize::new(0);
+    };
+}
+
+pub struct MarkChecker {
+    mark: &'static AtomicUsize,
+    value_on_entry: usize,
+}
+
+impl MarkChecker {
+    pub fn new(mark: &'static AtomicUsize) -> MarkChecker {
+        let value_on_entry = mark.load(Ordering::SeqCst);
+        MarkChecker {
+            mark,
+            value_on_entry,
+        }
+    }
+}
+
+impl Drop for MarkChecker {
+    fn drop(&mut self) {
+        if std::thread::panicking() {
+            return;
+        }
+        let value_on_exit = self.mark.load(Ordering::SeqCst);
+        assert!(value_on_exit > self.value_on_entry, "mark was not hit")
+    }
+}