Skip to content
This repository was archived by the owner on May 20, 2020. It is now read-only.

Commit a14a19a

Browse files
committed
Seperate doc tests into separate stages
When generating documentation tests, the following stages will happen: - tests will be gathered from the docs as a list of strings - tests will be saved to target/doc/tests as individual files - tests will be compiled into a single binary called "rustdoc-test" - tests will be run by executing the "rustdoc-test" binary Doc tests are now actual tests. This allows us to take advantage of the existing test infrastructure supplied by rustc. Fixes #32, #54
1 parent 4795623 commit a14a19a

File tree

4 files changed

+161
-160
lines changed

4 files changed

+161
-160
lines changed

example/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
//
1212
// @matches "included[?id=='nested_modules::example_module'] \
1313
// .relationships.parent" []
14+
/// An example module
15+
/// ```rust
16+
/// assert!(true);
17+
/// ```
1418
pub mod example_module {
1519

1620
// For the child:

src/error.rs

+8
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ pub struct Json {
2626
/// The location of the unexpected JSON
2727
pub location: String,
2828
}
29+
30+
/// Thrown whenever creation of documentation tests fail
31+
#[derive(Debug, Fail)]
32+
#[fail(display = "Unable to test documentation: \"{}\"", output)]
33+
pub struct DocTestErr {
34+
/// The output of the Command that failed
35+
pub output: String,
36+
}

src/lib.rs

+6-79
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ use std::env;
3434
use std::fs::{self, File};
3535
use std::io::prelude::*;
3636
use std::io;
37-
use std::iter;
3837
use std::path::{Path, PathBuf};
39-
use std::process::{self, Command, Stdio};
38+
use std::process::{Command, Stdio};
4039

4140
use cargo::Target;
4241
use json::Documentation;
43-
use test::TestResult;
4442
use ui::Ui;
4543

4644
pub use json::create_documentation;
@@ -213,82 +211,11 @@ pub fn test(config: &Config) -> Result<()> {
213211
})?;
214212
let docs: Documentation = serde_json::from_reader(doc_json)?;
215213

216-
let krate = docs.data.as_ref().unwrap();
217-
let tests: Vec<_> = iter::once(krate)
218-
.chain(docs.included.iter().flat_map(|data| data))
219-
.map(|data| (&data.id, test::gather_tests(&data)))
220-
.collect();
221-
222-
// Run the tests.
223-
static SUCCESS_MESSAGE: &str = "ok";
224-
static FAILURE_MESSAGE: &str = "FAILED";
225-
226-
let num_tests: usize = tests.iter().map(|&(_, ref tests)| tests.len()).sum();
227-
println!("running {} tests", num_tests);
228-
229-
let mut passed = 0;
230-
let mut failures = vec![];
231-
for (id, tests) in tests {
232-
for (number, test) in tests.iter().enumerate() {
233-
// FIXME: Make the name based off the file and line number.
234-
let name = format!("{} - {}", id, number);
235-
print!("test {} ... ", name);
236-
io::stdout().flush()?;
237-
238-
let message = match test::run_test(config, test)? {
239-
TestResult::Success => {
240-
passed += 1;
241-
SUCCESS_MESSAGE
242-
}
243-
TestResult::Failure(output) => {
244-
failures.push((name, output));
245-
FAILURE_MESSAGE
246-
}
247-
};
248-
249-
println!("{}", message);
250-
}
251-
}
252-
253-
if !failures.is_empty() {
254-
// Print the output of each failure.
255-
for &(ref name, ref output) in &failures {
256-
let stdout = String::from_utf8_lossy(&output.stdout);
257-
let stdout = stdout.trim();
258-
259-
if !stdout.is_empty() {
260-
println!("\n---- {} stdout ----\n{}", name, stdout);
261-
}
262-
263-
let stderr = String::from_utf8_lossy(&output.stderr);
264-
let stderr = stderr.trim();
265-
266-
if !stderr.is_empty() {
267-
println!("\n---- {} stderr ----\n{}", name, stderr);
268-
}
269-
}
270-
271-
// Print a summary of all failures at the bottom.
272-
println!("\nfailures:");
273-
for &(ref name, _) in &failures {
274-
println!(" {}", name);
275-
}
276-
}
277-
278-
println!(
279-
"\ntest result: {}. {} passed; {} failed; 0 ignored; 0 measured; 0 filtered out",
280-
if failures.is_empty() {
281-
SUCCESS_MESSAGE
282-
} else {
283-
FAILURE_MESSAGE
284-
},
285-
passed,
286-
failures.len()
287-
);
288-
289-
if !failures.is_empty() {
290-
process::exit(1);
291-
}
214+
let location = config.output_path().join("tests");
215+
let tests = test::find_tests(&docs);
216+
test::save_tests(&tests, &location)?;
217+
let binary = test::compile_tests(&config, &location)?;
218+
test::execute_tests(&binary)?;
292219

293220
Ok(())
294221
}

0 commit comments

Comments
 (0)