add a --chapter option to mdbook test. (#1741)
Sometimes when working on large books it is handy to be able to run mdbook on a single chapter of a book.
This commit is contained in:
parent
13f53eb64f
commit
74eb4059d6
|
@ -43,7 +43,7 @@ mdbook test path/to/book
|
|||
The `--library-path` (`-L`) option allows you to add directories to the library
|
||||
search path used by `rustdoc` when it builds and tests the examples. Multiple
|
||||
directories can be specified with multiple options (`-L foo -L bar`) or with a
|
||||
comma-delimited list (`-L foo,bar`). The path should point to the Cargo
|
||||
comma-delimited list (`-L foo,bar`). The path should point to the Cargo
|
||||
[build cache](https://doc.rust-lang.org/cargo/guide/build-cache.html) `deps` directory that
|
||||
contains the build output of your project. For example, if your Rust project's book is in a directory
|
||||
named `my-book`, the following command would include the crate's dependencies when running `test`:
|
||||
|
@ -61,3 +61,8 @@ The `--dest-dir` (`-d`) option allows you to change the output directory for the
|
|||
book. Relative paths are interpreted relative to the book's root directory. If
|
||||
not specified it will default to the value of the `build.build-dir` key in
|
||||
`book.toml`, or to `./book`.
|
||||
|
||||
#### --chapter
|
||||
|
||||
The `--chapter` (`-c`) option allows you to test a specific chapter of the
|
||||
book using the chapter name or the relative path to the chapter.
|
|
@ -246,6 +246,13 @@ impl MDBook {
|
|||
|
||||
/// Run `rustdoc` tests on the book, linking against the provided libraries.
|
||||
pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> {
|
||||
// test_chapter with chapter:None will run all tests.
|
||||
self.test_chapter(library_paths, None)
|
||||
}
|
||||
|
||||
/// Run `rustdoc` tests on a specific chapter of the book, linking against the provided libraries.
|
||||
/// If `chapter` is `None`, all tests will be run.
|
||||
pub fn test_chapter(&mut self, library_paths: Vec<&str>, chapter: Option<&str>) -> Result<()> {
|
||||
let library_args: Vec<&str> = (0..library_paths.len())
|
||||
.map(|_| "-L")
|
||||
.zip(library_paths.into_iter())
|
||||
|
@ -254,6 +261,8 @@ impl MDBook {
|
|||
|
||||
let temp_dir = TempFileBuilder::new().prefix("mdbook-").tempdir()?;
|
||||
|
||||
let mut chapter_found = false;
|
||||
|
||||
// FIXME: Is "test" the proper renderer name to use here?
|
||||
let preprocess_context =
|
||||
PreprocessorContext::new(self.root.clone(), self.config.clone(), "test".to_string());
|
||||
|
@ -270,8 +279,16 @@ impl MDBook {
|
|||
_ => continue,
|
||||
};
|
||||
|
||||
let path = self.source_dir().join(&chapter_path);
|
||||
info!("Testing file: {:?}", path);
|
||||
if let Some(chapter) = chapter {
|
||||
if ch.name != chapter && chapter_path.to_str() != Some(chapter) {
|
||||
if chapter == "?" {
|
||||
info!("Skipping chapter '{}'...", ch.name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
chapter_found = true;
|
||||
info!("Testing chapter '{}': {:?}", ch.name, chapter_path);
|
||||
|
||||
// write preprocessed file to tempdir
|
||||
let path = temp_dir.path().join(&chapter_path);
|
||||
|
@ -311,6 +328,11 @@ impl MDBook {
|
|||
if failed {
|
||||
bail!("One or more tests failed");
|
||||
}
|
||||
if let Some(chapter) = chapter {
|
||||
if !chapter_found {
|
||||
bail!("Chapter not found: {}", chapter);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,16 @@ pub fn make_subcommand<'help>() -> App<'help> {
|
|||
Relative paths are interpreted relative to the book's root directory.{n}\
|
||||
If omitted, mdBook uses build.build-dir from book.toml or defaults to `./book`.",
|
||||
),
|
||||
).arg(
|
||||
Arg::new("chapter")
|
||||
.short('c')
|
||||
.long("chapter")
|
||||
.value_name("chapter")
|
||||
.help(
|
||||
"Only test the specified chapter{n}\
|
||||
Where the name of the chapter is defined in the SUMMARY.md file.{n}\
|
||||
Use the special name \"?\" to the list of chapter names."
|
||||
)
|
||||
)
|
||||
.arg(arg!([dir]
|
||||
"Root directory for the book{n}\
|
||||
|
@ -41,14 +51,18 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
|||
.values_of("library-path")
|
||||
.map(std::iter::Iterator::collect)
|
||||
.unwrap_or_default();
|
||||
let chapter: Option<&str> = args.value_of("chapter");
|
||||
|
||||
let book_dir = get_book_dir(args);
|
||||
let mut book = MDBook::load(&book_dir)?;
|
||||
|
||||
if let Some(dest_dir) = args.value_of("dest-dir") {
|
||||
book.config.build.build_dir = dest_dir.into();
|
||||
}
|
||||
|
||||
book.test(library_paths)?;
|
||||
match chapter {
|
||||
Some(_) => book.test_chapter(library_paths, chapter),
|
||||
None => book.test(library_paths),
|
||||
}?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ fn mdbook_cli_can_correctly_test_a_passing_book() {
|
|||
let mut cmd = mdbook_cmd();
|
||||
cmd.arg("test").current_dir(temp.path());
|
||||
cmd.assert().success()
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]README.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]intro.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]first[\\/]index.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]first[\\/]nested.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"rustdoc returned an error:\n\n"##).unwrap().not())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "README.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "intro.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "first[\\/]index.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "first[\\/]nested.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"returned an error:\n\n"##).unwrap().not())
|
||||
.stderr(predicates::str::is_match(r##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap().not());
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,10 @@ fn mdbook_cli_detects_book_with_failing_tests() {
|
|||
let mut cmd = mdbook_cmd();
|
||||
cmd.arg("test").current_dir(temp.path());
|
||||
cmd.assert().failure()
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]README.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]intro.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]first[\\/]index.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing file: "([^"]+)[\\/]first[\\/]nested.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"rustdoc returned an error:\n\n"##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "README.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "intro.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "first[\\/]index.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Testing chapter [^:]*: "first[\\/]nested.md""##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"returned an error:\n\n"##).unwrap())
|
||||
.stderr(predicates::str::is_match(r##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap());
|
||||
}
|
||||
|
|
|
@ -24,3 +24,24 @@ fn mdbook_detects_book_with_failing_tests() {
|
|||
|
||||
assert!(md.test(vec![]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mdbook_test_chapter() {
|
||||
let temp = DummyBook::new().with_passing_test(true).build().unwrap();
|
||||
let mut md = MDBook::load(temp.path()).unwrap();
|
||||
|
||||
let result = md.test_chapter(vec![], Some("Introduction"));
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"test_chapter failed with {}",
|
||||
result.err().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mdbook_test_chapter_not_found() {
|
||||
let temp = DummyBook::new().with_passing_test(true).build().unwrap();
|
||||
let mut md = MDBook::load(temp.path()).unwrap();
|
||||
|
||||
assert!(md.test_chapter(vec![], Some("Bogus Chapter Name")).is_err());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue