Skip to content

Commit

Permalink
Rollup merge of #41678 - GuillaumeGomez:rustdoc-test-warnings, r=alex…
Browse files Browse the repository at this point in the history
…crichton

Add option to display warnings in rustdoc

Part of #41574.

r? @alexcrichton

The output for this file:

```rust
/// ```
/// fn foo(x: u32) {}
///
/// foo(2);
/// let x = 1;
/// panic!();
/// ```
fn foo() {}

/// ```
/// fn foo(x: u32) {}
///
/// foo(2);
/// let x = 1;
/// ```
fn foo2() {}

/// ```
/// fn foo(x: u32) {}
///
/// foo(2);
/// let x = 1;
/// panic!();
/// ```
fn foo3() {}

fn main() {
}
```

is the following:

```
> ./build/x86_64-apple-darwin/stage1/bin/rustdoc -Z unstable-options --display-warnings --test test.rs

running 3 tests
test test.rs - foo (line 1) ... FAILED
test test.rs - foo3 (line 18) ... FAILED
test test.rs - foo2 (line 10) ... ok

successes:

---- test.rs - foo2 (line 10) stdout ----
	warning: unused variable: `x`
 --> <anon>:2:8
  |
2 | fn foo(x: u32) {}
  |        ^
  |
  = note: #[warn(unused_variables)] on by default

warning: unused variable: `x`
 --> <anon>:5:5
  |
5 | let x = 1;
  |     ^
  |
  = note: #[warn(unused_variables)] on by default

successes:
    test.rs - foo2 (line 10)

failures:

---- test.rs - foo (line 1) stdout ----
	warning: unused variable: `x`
 --> <anon>:2:8
  |
2 | fn foo(x: u32) {}
  |        ^
  |
  = note: #[warn(unused_variables)] on by default

warning: unused variable: `x`
 --> <anon>:5:5
  |
5 | let x = 1;
  |     ^
  |
  = note: #[warn(unused_variables)] on by default

thread 'rustc' panicked at 'test executable failed:

thread 'main' panicked at 'explicit panic', <anon>:6
note: Run with `RUST_BACKTRACE=1` for a backtrace.

', src/librustdoc/test.rs:317
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- test.rs - foo3 (line 18) stdout ----
	warning: unused variable: `x`
 --> <anon>:2:8
  |
2 | fn foo(x: u32) {}
  |        ^
  |
  = note: #[warn(unused_variables)] on by default

warning: unused variable: `x`
 --> <anon>:5:5
  |
5 | let x = 1;
  |     ^
  |
  = note: #[warn(unused_variables)] on by default

thread 'rustc' panicked at 'test executable failed:

thread 'main' panicked at 'explicit panic', <anon>:6
note: Run with `RUST_BACKTRACE=1` for a backtrace.

', src/librustdoc/test.rs:317

failures:
    test.rs - foo (line 1)
    test.rs - foo3 (line 18)

test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured
```
  • Loading branch information
frewsxcv authored May 5, 2017
2 parents b091d6e + d5863e9 commit ecd7b48
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 17 deletions.
5 changes: 3 additions & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ pub fn run_core(search_paths: SearchPaths,
externs: config::Externs,
input: Input,
triple: Option<String>,
maybe_sysroot: Option<PathBuf>) -> (clean::Crate, RenderInfo)
maybe_sysroot: Option<PathBuf>,
allow_warnings: bool) -> (clean::Crate, RenderInfo)
{
// Parse, resolve, and typecheck the given crate.

Expand All @@ -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()),
Expand Down
11 changes: 8 additions & 3 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ pub fn opts() -> Vec<RustcOptGroup> {
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")),
]
}

Expand Down Expand Up @@ -280,14 +281,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")),
Expand Down Expand Up @@ -389,13 +392,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");

Expand Down
5 changes: 3 additions & 2 deletions src/librustdoc/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>, libs: SearchPaths, externs: Externs,
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
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,
Expand All @@ -166,6 +166,7 @@ pub fn test(input: &str, cfgs: Vec<String>, 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());
testing::test_main(&test_args, collector.tests);
testing::test_main(&test_args, collector.tests,
testing::Options::new().display_output(display_warnings));
0
}
6 changes: 4 additions & 2 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub fn run(input: &str,
mut test_args: Vec<String>,
crate_name: Option<String>,
maybe_sysroot: Option<PathBuf>,
render_type: RenderType)
render_type: RenderType,
display_warnings: bool)
-> isize {
let input_path = PathBuf::from(input);
let input = config::Input::File(input_path.clone());
Expand Down Expand Up @@ -127,7 +128,8 @@ pub fn run(input: &str,
test_args.insert(0, "rustdoctest".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
}

Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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] = &[
Expand Down Expand Up @@ -478,7 +478,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
// 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);
Expand Down
74 changes: 68 additions & 6 deletions src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<TestDescAndFn>) {
let opts = match parse_opts(args) {
pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, 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);
Expand Down Expand Up @@ -301,16 +321,17 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
}
})
.collect();
test_main(&args, owned_tests)
test_main(&args, owned_tests, Options::new())
}

#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub enum ColorConfig {
AutoColor,
AlwaysColor,
NeverColor,
}

#[derive(Debug)]
pub struct TestOpts {
pub list: bool,
pub filter: Option<String>,
Expand All @@ -324,6 +345,7 @@ pub struct TestOpts {
pub quiet: bool,
pub test_threads: Option<usize>,
pub skip: Vec<String>,
pub options: Options,
}

impl TestOpts {
Expand All @@ -342,6 +364,7 @@ impl TestOpts {
quiet: false,
test_threads: None,
skip: vec![],
options: Options::new(),
}
}
}
Expand Down Expand Up @@ -481,6 +504,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
quiet: quiet,
test_threads: test_threads,
skip: matches.opt_strs("skip"),
options: Options::new(),
};

Some(Ok(test_opts))
Expand Down Expand Up @@ -521,7 +545,9 @@ struct ConsoleTestState<T> {
measured: usize,
metrics: MetricMap,
failures: Vec<(TestDesc, Vec<u8>)>,
not_failures: Vec<(TestDesc, Vec<u8>)>,
max_name_len: usize, // number of columns to fill when aligning names
options: Options,
}

impl<T: Write> ConsoleTestState<T> {
Expand All @@ -547,7 +573,9 @@ impl<T: Write> ConsoleTestState<T> {
measured: 0,
metrics: MetricMap::new(),
failures: Vec::new(),
not_failures: Vec::new(),
max_name_len: 0,
options: opts.options,
})
}

Expand Down Expand Up @@ -703,9 +731,38 @@ impl<T: Write> ConsoleTestState<T> {
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<bool> {
assert!(self.passed + self.failed + self.ignored + self.measured == self.total);

if self.options.display_output {
self.write_outputs()?;
}
let success = self.failed == 0;
if !success {
self.write_failures()?;
Expand Down Expand Up @@ -824,7 +881,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> 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;
Expand Down Expand Up @@ -901,6 +961,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())],
options: Options::new(),
not_failures: Vec::new(),
};

st.write_failures().unwrap();
Expand Down
1 change: 1 addition & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
test_threads: None,
skip: vec![],
list: false,
options: test::Options::new(),
}
}

Expand Down

0 comments on commit ecd7b48

Please sign in to comment.