From 6ca0e5ed39dd9ff4661a0c99c15592da171bffcf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Jun 2021 16:53:32 +0200 Subject: [PATCH 1/5] Add --nocapture option to rustdoc --- src/librustdoc/config.rs | 5 +++++ src/librustdoc/doctest.rs | 7 +++++++ src/librustdoc/lib.rs | 3 +++ src/librustdoc/markdown.rs | 3 +++ 4 files changed, 18 insertions(+) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 4cf647a81ae4b..adbdde0d92cd6 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -156,6 +156,8 @@ crate struct Options { crate run_check: bool, /// Whether doctests should emit unused externs crate json_unused_externs: bool, + /// Whether to skip capturing stdout and stderr of tests. + crate nocapture: bool, } impl fmt::Debug for Options { @@ -199,6 +201,7 @@ impl fmt::Debug for Options { .field("enable-per-target-ignores", &self.enable_per_target_ignores) .field("run_check", &self.run_check) .field("no_run", &self.no_run) + .field("nocapture", &self.nocapture) .finish() } } @@ -627,6 +630,7 @@ impl Options { let run_check = matches.opt_present("check"); let generate_redirect_map = matches.opt_present("generate-redirect-map"); let show_type_layout = matches.opt_present("show-type-layout"); + let nocapture = matches.opt_present("nocapture"); let (lint_opts, describe_lints, lint_cap, _) = get_cmd_lint_options(matches, error_format, &debugging_opts); @@ -665,6 +669,7 @@ impl Options { test_builder, run_check, no_run, + nocapture, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c5ca396e72029..a9126049b58d4 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -107,6 +107,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { let mut test_args = options.test_args.clone(); let display_warnings = options.display_warnings; + let nocapture = options.nocapture; let externs = options.externs.clone(); let json_unused_externs = options.json_unused_externs; @@ -166,6 +167,9 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { }; test_args.insert(0, "rustdoctest".to_string()); + if nocapture { + test_args.push("--nocapture".to_string()); + } test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings))); @@ -463,6 +467,9 @@ fn run_test( return Err(TestFailure::UnexpectedRunPass); } else if !should_panic && !out.status.success() { return Err(TestFailure::ExecutionFailure(out)); + } else if options.nocapture { + io::stdout().write_all(&out.stdout).expect("failed to write stdout"); + io::stderr().write_all(&out.stderr).expect("failed to write stderr"); } } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d4d87819c0d7a..19deaa11388d8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -604,6 +604,9 @@ fn opts() -> Vec { unstable("show-type-layout", |o| { o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs") }), + unstable("nocapture", |o| { + o.optflag("", "nocapture", "Don't capture stdout and stderr of tests") + }), ] } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 45966c0058df4..6c8b95c04c9e4 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -136,6 +136,9 @@ crate fn test(mut options: Options) -> Result<(), String> { find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None); options.test_args.insert(0, "rustdoctest".to_string()); + if options.nocapture { + options.test_args.push("--nocapture".to_string()); + } test::test_main( &options.test_args, collector.tests, From 111cca1fa76e13956610cae02da13758daed8ddf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Jun 2021 22:11:35 +0200 Subject: [PATCH 2/5] Add test for rustdoc --nocapture option --- src/test/rustdoc-ui/nocapture.rs | 10 ++++++++++ src/test/rustdoc-ui/nocapture.stderr | 1 + src/test/rustdoc-ui/nocapture.stdout | 7 +++++++ 3 files changed, 18 insertions(+) create mode 100644 src/test/rustdoc-ui/nocapture.rs create mode 100644 src/test/rustdoc-ui/nocapture.stderr create mode 100644 src/test/rustdoc-ui/nocapture.stdout diff --git a/src/test/rustdoc-ui/nocapture.rs b/src/test/rustdoc-ui/nocapture.rs new file mode 100644 index 0000000000000..321f5ca08eded --- /dev/null +++ b/src/test/rustdoc-ui/nocapture.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags:--test -Zunstable-options --nocapture +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// println!("hello!"); +/// eprintln!("stderr"); +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/nocapture.stderr b/src/test/rustdoc-ui/nocapture.stderr new file mode 100644 index 0000000000000..af6415db3c724 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture.stderr @@ -0,0 +1 @@ +stderr diff --git a/src/test/rustdoc-ui/nocapture.stdout b/src/test/rustdoc-ui/nocapture.stdout new file mode 100644 index 0000000000000..4880e75da7062 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture.stdout @@ -0,0 +1,7 @@ + +running 1 test +hello! +test $DIR/nocapture.rs - Foo (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 893e07e1b0a93897bb931d8495f02ab731bd5a32 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Jun 2021 22:20:40 +0200 Subject: [PATCH 3/5] Add doc for --nocapture --- src/doc/rustdoc/src/command-line-arguments.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 2e4016e24bc3f..c8af369a9695e 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -417,3 +417,10 @@ This flag is **deprecated** and **has no effect**. Rustdoc only supports Rust source code and Markdown input formats. If the file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file. Otherwise, it assumes that the input file is Rust. + +## `--nocapture` + +When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be +captured by rustdoc. Instead, the output will be directed to your terminal, +as if you had run the test executable manually. This is especially useful +for debugging your tests! From 6461cde51f1885f3c5e96e26debcfc6d82285b7b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Jul 2021 10:58:02 +0200 Subject: [PATCH 4/5] Don't capture child process output at all when --no-capture is used --- src/librustdoc/doctest.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a9126049b58d4..5ce7c49278d23 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -460,16 +460,22 @@ fn run_test( cmd.current_dir(run_directory); } - match cmd.output() { + let result = if options.nocapture { + cmd.status().map(|status| process::Output { + status, + stdout: Vec::new(), + stderr: Vec::new(), + }) + } else { + cmd.output() + }; + match result { Err(e) => return Err(TestFailure::ExecutionError(e)), Ok(out) => { if should_panic && out.status.success() { return Err(TestFailure::UnexpectedRunPass); } else if !should_panic && !out.status.success() { return Err(TestFailure::ExecutionFailure(out)); - } else if options.nocapture { - io::stdout().write_all(&out.stdout).expect("failed to write stdout"); - io::stderr().write_all(&out.stderr).expect("failed to write stderr"); } } } From d5e32947344751a421c85aed2e4dd370160f5470 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Jul 2021 11:06:20 +0200 Subject: [PATCH 5/5] Add invalid rust code for test --- src/test/rustdoc-ui/nocapture-fail.rs | 12 ++++++++++++ src/test/rustdoc-ui/nocapture-fail.stderr | 18 ++++++++++++++++++ src/test/rustdoc-ui/nocapture-fail.stdout | 6 ++++++ 3 files changed, 36 insertions(+) create mode 100644 src/test/rustdoc-ui/nocapture-fail.rs create mode 100644 src/test/rustdoc-ui/nocapture-fail.stderr create mode 100644 src/test/rustdoc-ui/nocapture-fail.stdout diff --git a/src/test/rustdoc-ui/nocapture-fail.rs b/src/test/rustdoc-ui/nocapture-fail.rs new file mode 100644 index 0000000000000..7706bd1f3e39c --- /dev/null +++ b/src/test/rustdoc-ui/nocapture-fail.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags:--test -Zunstable-options --nocapture +// normalize-stderr-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ```compile_fail +/// fn foo() { +/// Input: 123 +/// } +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/nocapture-fail.stderr b/src/test/rustdoc-ui/nocapture-fail.stderr new file mode 100644 index 0000000000000..16a5ac47cd257 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture-fail.stderr @@ -0,0 +1,18 @@ +error: struct literal body without path + --> $DIR/nocapture-fail.rs:8:10 + | +LL | fn foo() { + | __________^ +LL | | Input: 123 +LL | | } + | |_^ + | +help: you might have forgotten to add the struct literal inside the block + | +LL | fn foo() { SomeStruct { +LL | Input: 123 +LL | } } + | + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/nocapture-fail.stdout b/src/test/rustdoc-ui/nocapture-fail.stdout new file mode 100644 index 0000000000000..754f77db53ca3 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture-fail.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/nocapture-fail.rs - Foo (line 7) - compile fail ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +