about summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuietMisdreavus <grey@quietmisdreavus.net>2018-02-09 10:40:27 -0600
committerQuietMisdreavus <grey@quietmisdreavus.net>2018-02-09 10:40:27 -0600
commit70b5c458e6cfdf7c9bcb45a24e1ac99f12d68dd5 (patch)
tree47d3d534713ebc04ec9a2db1eae3080aab955e89
parenta58d1b5346806ecfe53e27916792b13c2ac42e89 (diff)
downloadrust-70b5c458e6cfdf7c9bcb45a24e1ac99f12d68dd5.tar.gz
rust-70b5c458e6cfdf7c9bcb45a24e1ac99f12d68dd5.zip
add tests for the doctest construction functionality
-rw-r--r--src/librustdoc/test.rs214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 6f126a1ed63..08258489a2e 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -753,3 +753,217 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
         self.visit_testable(macro_def.name.to_string(), &macro_def.attrs, |_| ());
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::{TestOptions, make_test};
+
+    #[test]
+    fn make_test_basic() {
+        //basic use: wraps with `fn main`, adds `#![allow(unused)]`
+        let opts = TestOptions::default();
+        let input =
+"assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, None, false, &opts);
+        assert_eq!(output, (expected.clone(), 2));
+    }
+
+    #[test]
+    fn make_test_crate_name_no_use() {
+        //if you give a crate name but *don't* use it within the test, it won't bother inserting
+        //the `extern crate` statement
+        let opts = TestOptions::default();
+        let input =
+"assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
+    #[test]
+    fn make_test_crate_name() {
+        //if you give a crate name and use it within the test, it will insert an `extern crate`
+        //statement before `fn main`
+        let opts = TestOptions::default();
+        let input =
+"use asdf::qwop;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+extern crate asdf;
+fn main() {
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 3));
+    }
+
+    #[test]
+    fn make_test_no_crate_inject() {
+        //even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
+        //adding it anyway
+        let opts = TestOptions {
+            no_crate_inject: true,
+            attrs: vec![],
+        };
+        let input =
+"use asdf::qwop;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
+    #[test]
+    fn make_test_ignore_std() {
+        //even if you include a crate name, and use it in the doctest, we still won't include an
+        //`extern crate` statement if the crate is "std" - that's included already by the compiler!
+        let opts = TestOptions::default();
+        let input =
+"use std::*;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+use std::*;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("std"), false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
+    #[test]
+    fn make_test_manual_extern_crate() {
+        //when you manually include an `extern crate` statement in your doctest, make_test assumes
+        //you've included one for your own crate too
+        let opts = TestOptions::default();
+        let input =
+"extern crate asdf;
+use asdf::qwop;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+extern crate asdf;
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
+    #[test]
+    fn make_test_opts_attrs() {
+        //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those
+        //instead of the stock #![allow(unused)]
+        let mut opts = TestOptions::default();
+        opts.attrs.push("feature(sick_rad)".to_string());
+        let input =
+"use asdf::qwop;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![feature(sick_rad)]
+extern crate asdf;
+fn main() {
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 3));
+
+        //adding more will also bump the returned line offset
+        opts.attrs.push("feature(hella_dope)".to_string());
+        let expected =
+"#![feature(sick_rad)]
+#![feature(hella_dope)]
+extern crate asdf;
+fn main() {
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 4));
+    }
+
+    #[test]
+    fn make_test_crate_attrs() {
+        //including inner attributes in your doctest will apply them to the whole "crate", pasting
+        //them outside the generated main function
+        let opts = TestOptions::default();
+        let input =
+"#![feature(sick_rad)]
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+#![feature(sick_rad)]
+fn main() {
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, None, false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
+    #[test]
+    fn make_test_with_main() {
+        //including your own `fn main` wrapper lets the test use it verbatim
+        let opts = TestOptions::default();
+        let input =
+"fn main() {
+    assert_eq!(2+2, 4);
+}";
+        let expected =
+"#![allow(unused)]
+fn main() {
+    assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, None, false, &opts);
+        assert_eq!(output, (expected, 1));
+    }
+
+    #[test]
+    fn make_test_fake_main() {
+        //...but putting it in a comment will still provide a wrapper
+        let opts = TestOptions::default();
+        let input =
+"//Ceci n'est pas une `fn main`
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+fn main() {
+//Ceci n'est pas une `fn main`
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, None, false, &opts);
+        assert_eq!(output, (expected.clone(), 2));
+    }
+
+    #[test]
+    fn make_test_dont_insert_main() {
+        //even with that, if you set `dont_insert_main`, it won't create the `fn main` wrapper
+        let opts = TestOptions::default();
+        let input =
+"//Ceci n'est pas une `fn main`
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+//Ceci n'est pas une `fn main`
+assert_eq!(2+2, 4);".to_string();
+        let output = make_test(input, None, true, &opts);
+        assert_eq!(output, (expected.clone(), 1));
+    }
+}