From f30ed77f0d7bb4be308454d8522b389e0f9ce4f5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 May 2017 17:47:39 +0200 Subject: [PATCH 1/2] Add option to display warnings in rustdoc --- src/librustdoc/core.rs | 5 ++-- src/librustdoc/lib.rs | 11 +++++-- src/librustdoc/markdown.rs | 5 +++- src/librustdoc/test.rs | 6 +++- src/libtest/lib.rs | 49 +++++++++++++++++++++++++++++-- src/tools/compiletest/src/main.rs | 1 + 6 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6417270b9c73b..32fbc7633b927 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -104,7 +104,8 @@ pub fn run_core(search_paths: SearchPaths, externs: config::Externs, input: Input, triple: Option, - maybe_sysroot: Option) -> (clean::Crate, RenderInfo) + maybe_sysroot: Option, + allow_warnings: bool) -> (clean::Crate, RenderInfo) { // Parse, resolve, and typecheck the given crate. @@ -119,7 +120,7 @@ pub fn run_core(search_paths: SearchPaths, maybe_sysroot: maybe_sysroot, search_paths: search_paths, crate_types: vec![config::CrateTypeRlib], - lint_opts: vec![(warning_lint, lint::Allow)], + lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] }, lint_cap: Some(lint::Allow), externs: externs, target_triple: triple.unwrap_or(config::host_triple().to_string()), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2a6134fde5c3d..37440e303a469 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -172,6 +172,7 @@ pub fn opts() -> Vec { or `#![doc(html_playground_url=...)]`", "URL")), unstable(optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing")), + unstable(optflag("", "display-warnings", "to print code warnings when testing doc")), ] } @@ -279,14 +280,16 @@ pub fn main_args(args: &[String]) -> isize { let crate_name = matches.opt_str("crate-name"); let playground_url = matches.opt_str("playground-url"); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); + let display_warnings = matches.opt_present("display-warnings"); match (should_test, markdown_input) { (true, true) => { - return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type) + return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type, + display_warnings) } (true, false) => { return test::run(input, cfgs, libs, externs, test_args, crate_name, maybe_sysroot, - render_type) + render_type, display_warnings) } (false, true) => return markdown::render(input, output.unwrap_or(PathBuf::from("doc")), @@ -388,13 +391,15 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { let cr = PathBuf::from(cratefile); info!("starting to run rustc"); + let display_warnings = matches.opt_present("display-warnings"); let (tx, rx) = channel(); rustc_driver::monitor(move || { use rustc::session::config::Input; let (mut krate, renderinfo) = - core::run_core(paths, cfgs, externs, Input::File(cr), triple, maybe_sysroot); + core::run_core(paths, cfgs, externs, Input::File(cr), triple, maybe_sysroot, + display_warnings); info!("finished with rustc"); diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index b9ed0eeaef736..efeb8ea72ba6c 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -150,7 +150,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, /// Run any tests/code examples in the markdown file `input`. pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, mut test_args: Vec, maybe_sysroot: Option, - render_type: RenderType) -> isize { + render_type: RenderType, display_warnings: bool) -> isize { let input_str = match load_string(input) { Ok(s) => s, Err(LoadStringError::ReadFail) => return 1, @@ -166,6 +166,9 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, old_find_testable_code(&input_str, &mut collector, DUMMY_SP); find_testable_code(&input_str, &mut collector, DUMMY_SP); test_args.insert(0, "rustdoctest".to_string()); + if display_warnings { + test_args.insert(1, "--display-stdout".to_string()); + } testing::test_main(&test_args, collector.tests); 0 } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5428b0663f368..23462443eff65 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -58,7 +58,8 @@ pub fn run(input: &str, mut test_args: Vec, crate_name: Option, maybe_sysroot: Option, - render_type: RenderType) + render_type: RenderType, + display_warnings: bool) -> isize { let input_path = PathBuf::from(input); let input = config::Input::File(input_path.clone()); @@ -125,6 +126,9 @@ pub fn run(input: &str, } test_args.insert(0, "rustdoctest".to_string()); + if display_warnings { + test_args.insert(1, "--display-stdout".to_string()); + } testing::test_main(&test_args, collector.tests.into_iter().collect()); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 5fdb0aa0641a0..23c0c6065a8a1 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -304,13 +304,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) { test_main(&args, owned_tests) } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum ColorConfig { AutoColor, AlwaysColor, NeverColor, } +#[derive(Debug)] pub struct TestOpts { pub list: bool, pub filter: Option, @@ -324,6 +325,7 @@ pub struct TestOpts { pub quiet: bool, pub test_threads: Option, pub skip: Vec, + pub display_stdout: bool, } impl TestOpts { @@ -342,6 +344,7 @@ impl TestOpts { quiet: false, test_threads: None, skip: vec![], + display_stdout: false, } } } @@ -369,7 +372,8 @@ fn optgroups() -> Vec { getopts::optopt("", "color", "Configure coloring of output: auto = colorize if stdout is a tty and tests are run on serially (default); always = always colorize output; - never = never colorize output;", "auto|always|never")] + never = never colorize output;", "auto|always|never"), + getopts::optflag("", "display-stdout", "to print stdout even if the test succeeds")] } fn usage(binary: &str) { @@ -481,6 +485,7 @@ pub fn parse_opts(args: &[String]) -> Option { quiet: quiet, test_threads: test_threads, skip: matches.opt_strs("skip"), + display_stdout: matches.opt_present("display-stdout"), }; Some(Ok(test_opts)) @@ -521,7 +526,9 @@ struct ConsoleTestState { measured: usize, metrics: MetricMap, failures: Vec<(TestDesc, Vec)>, + not_failures: Vec<(TestDesc, Vec)>, max_name_len: usize, // number of columns to fill when aligning names + display_stdout: bool, } impl ConsoleTestState { @@ -547,7 +554,9 @@ impl ConsoleTestState { measured: 0, metrics: MetricMap::new(), failures: Vec::new(), + not_failures: Vec::new(), max_name_len: 0, + display_stdout: opts.display_stdout, }) } @@ -703,9 +712,38 @@ impl ConsoleTestState { Ok(()) } + pub fn write_outputs(&mut self) -> io::Result<()> { + self.write_plain("\nsuccesses:\n")?; + let mut successes = Vec::new(); + let mut stdouts = String::new(); + for &(ref f, ref stdout) in &self.not_failures { + successes.push(f.name.to_string()); + if !stdout.is_empty() { + stdouts.push_str(&format!("---- {} stdout ----\n\t", f.name)); + let output = String::from_utf8_lossy(stdout); + stdouts.push_str(&output); + stdouts.push_str("\n"); + } + } + if !stdouts.is_empty() { + self.write_plain("\n")?; + self.write_plain(&stdouts)?; + } + + self.write_plain("\nsuccesses:\n")?; + successes.sort(); + for name in &successes { + self.write_plain(&format!(" {}\n", name))?; + } + Ok(()) + } + pub fn write_run_finish(&mut self) -> io::Result { assert!(self.passed + self.failed + self.ignored + self.measured == self.total); + if self.display_stdout { + self.write_outputs()?; + } let success = self.failed == 0; if !success { self.write_failures()?; @@ -824,7 +862,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu st.write_log_result(&test, &result)?; st.write_result(&result)?; match result { - TrOk => st.passed += 1, + TrOk => { + st.passed += 1; + st.not_failures.push((test, stdout)); + } TrIgnored => st.ignored += 1, TrMetrics(mm) => { let tname = test.name; @@ -901,6 +942,8 @@ fn should_sort_failures_before_printing_them() { max_name_len: 10, metrics: MetricMap::new(), failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], + display_stdout: false, + not_failures: Vec::new(), }; st.write_failures().unwrap(); diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 4165ea685a5b2..0d1795a182cd8 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -336,6 +336,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { test_threads: None, skip: vec![], list: false, + display_stdout: false, } } From d5863e99853c22c649a1787f40c47b60795ea93d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 May 2017 23:53:48 +0200 Subject: [PATCH 2/2] Add Options type in libtest and remove argument --- src/librustdoc/markdown.rs | 6 ++--- src/librustdoc/test.rs | 6 ++--- src/libsyntax/test.rs | 4 +-- src/libtest/lib.rs | 45 ++++++++++++++++++++++--------- src/tools/compiletest/src/main.rs | 2 +- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index efeb8ea72ba6c..057ce69d9de8b 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -166,9 +166,7 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, old_find_testable_code(&input_str, &mut collector, DUMMY_SP); find_testable_code(&input_str, &mut collector, DUMMY_SP); test_args.insert(0, "rustdoctest".to_string()); - if display_warnings { - test_args.insert(1, "--display-stdout".to_string()); - } - testing::test_main(&test_args, collector.tests); + testing::test_main(&test_args, collector.tests, + testing::Options::new().display_output(display_warnings)); 0 } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 23462443eff65..d5237d629cfc1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -126,12 +126,10 @@ pub fn run(input: &str, } test_args.insert(0, "rustdoctest".to_string()); - if display_warnings { - test_args.insert(1, "--display-stdout".to_string()); - } testing::test_main(&test_args, - collector.tests.into_iter().collect()); + collector.tests.into_iter().collect(), + testing::Options::new().display_output(display_warnings)); 0 } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 50380626d7f0d..91746a2edd9b2 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -442,7 +442,7 @@ We're going to be building a module that looks more or less like: mod __test { extern crate test (name = "test", vers = "..."); fn main() { - test::test_main_static(&::os::args()[], tests) + test::test_main_static(&::os::args()[], tests, test::Options::new()) } static tests : &'static [test::TestDescAndFn] = &[ @@ -478,7 +478,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { // pub fn main() { // #![main] // use std::slice::AsSlice; - // test::test_main_static(::std::os::args().as_slice(), TESTS); + // test::test_main_static(::std::os::args().as_slice(), TESTS, test::Options::new()); // } let sp = ignored_span(cx, DUMMY_SP); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 23c0c6065a8a1..35f2fbca69f8d 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -76,7 +76,7 @@ pub mod test { pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName, DynTestName, DynTestFn, run_test, test_main, test_main_static, filter_tests, - parse_opts, StaticBenchFn, ShouldPanic}; + parse_opts, StaticBenchFn, ShouldPanic, Options}; } pub mod stats; @@ -252,14 +252,34 @@ impl Clone for MetricMap { } } +/// In case we want to add other options as well, just add them in this struct. +#[derive(Copy, Clone, Debug)] +pub struct Options { + display_output: bool, +} + +impl Options { + pub fn new() -> Options { + Options { + display_output: false, + } + } + + pub fn display_output(mut self, display_output: bool) -> Options { + self.display_output = display_output; + self + } +} + // The default console test runner. It accepts the command line // arguments and a vector of test_descs. -pub fn test_main(args: &[String], tests: Vec) { - let opts = match parse_opts(args) { +pub fn test_main(args: &[String], tests: Vec, options: Options) { + let mut opts = match parse_opts(args) { Some(Ok(o)) => o, Some(Err(msg)) => panic!("{:?}", msg), None => return, }; + opts.options = options; if opts.list { if let Err(e) = list_tests_console(&opts, tests) { panic!("io error when listing tests: {:?}", e); @@ -301,7 +321,7 @@ pub fn test_main_static(tests: &[TestDescAndFn]) { } }) .collect(); - test_main(&args, owned_tests) + test_main(&args, owned_tests, Options::new()) } #[derive(Copy, Clone, Debug)] @@ -325,7 +345,7 @@ pub struct TestOpts { pub quiet: bool, pub test_threads: Option, pub skip: Vec, - pub display_stdout: bool, + pub options: Options, } impl TestOpts { @@ -344,7 +364,7 @@ impl TestOpts { quiet: false, test_threads: None, skip: vec![], - display_stdout: false, + options: Options::new(), } } } @@ -372,8 +392,7 @@ fn optgroups() -> Vec { getopts::optopt("", "color", "Configure coloring of output: auto = colorize if stdout is a tty and tests are run on serially (default); always = always colorize output; - never = never colorize output;", "auto|always|never"), - getopts::optflag("", "display-stdout", "to print stdout even if the test succeeds")] + never = never colorize output;", "auto|always|never")] } fn usage(binary: &str) { @@ -485,7 +504,7 @@ pub fn parse_opts(args: &[String]) -> Option { quiet: quiet, test_threads: test_threads, skip: matches.opt_strs("skip"), - display_stdout: matches.opt_present("display-stdout"), + options: Options::new(), }; Some(Ok(test_opts)) @@ -528,7 +547,7 @@ struct ConsoleTestState { failures: Vec<(TestDesc, Vec)>, not_failures: Vec<(TestDesc, Vec)>, max_name_len: usize, // number of columns to fill when aligning names - display_stdout: bool, + options: Options, } impl ConsoleTestState { @@ -556,7 +575,7 @@ impl ConsoleTestState { failures: Vec::new(), not_failures: Vec::new(), max_name_len: 0, - display_stdout: opts.display_stdout, + options: opts.options, }) } @@ -741,7 +760,7 @@ impl ConsoleTestState { pub fn write_run_finish(&mut self) -> io::Result { assert!(self.passed + self.failed + self.ignored + self.measured == self.total); - if self.display_stdout { + if self.options.display_output { self.write_outputs()?; } let success = self.failed == 0; @@ -942,7 +961,7 @@ fn should_sort_failures_before_printing_them() { max_name_len: 10, metrics: MetricMap::new(), failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], - display_stdout: false, + options: Options::new(), not_failures: Vec::new(), }; diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 0d1795a182cd8..6fc7f9f07ac17 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -336,7 +336,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { test_threads: None, skip: vec![], list: false, - display_stdout: false, + options: test::Options::new(), } }