diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 6f126a1ed6306..08258489a2ec2 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(), ¯o_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)); + } +}