diff --git a/Cargo.lock b/Cargo.lock index 1f723808..f1992bc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,20 @@ version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +[[package]] +name = "assert_cmd" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d20831bd004dda4c7c372c19cdabff369f794a95e955b3f13fe460e3e1ae95f" +dependencies = [ + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "atty" version = "0.2.14" @@ -115,6 +129,17 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "bstr" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + [[package]] name = "byte-tools" version = "0.3.1" @@ -198,6 +223,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.8.1" @@ -216,6 +247,18 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "elasticlunr-rs" version = "2.3.13" @@ -262,6 +305,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" @@ -689,6 +741,15 @@ dependencies = [ "libc", ] +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -782,6 +843,7 @@ version = "0.4.12" dependencies = [ "ammonia", "anyhow", + "assert_cmd", "chrono", "clap", "elasticlunr-rs", @@ -794,6 +856,7 @@ dependencies = [ "memchr", "notify", "open", + "predicates", "pretty_assertions", "pulldown-cmark", "regex", @@ -914,6 +977,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "notify" version = "4.0.17" @@ -1138,6 +1207,36 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "predicates" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc3d91237f5de3bcd9d927e24d03b495adb6135097b001cea7403e2d573d00a9" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" + +[[package]] +name = "predicates-tree" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2" +dependencies = [ + "predicates-core", + "treeline", +] + [[package]] name = "pretty_assertions" version = "0.6.1" @@ -1315,6 +1414,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.25" @@ -1703,6 +1808,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" + [[package]] name = "try-lock" version = "0.2.3" @@ -1812,6 +1923,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index 3646a7ea..79ae2878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,8 @@ elasticlunr-rs = { version = "2.3", optional = true, default-features = false } ammonia = { version = "3", optional = true } [dev-dependencies] +assert_cmd = "1" +predicates = "2" select = "0.5" semver = "0.11.0" pretty_assertions = "0.6" diff --git a/tests/cli.rs b/tests/cli.rs new file mode 100644 index 00000000..c400ff11 --- /dev/null +++ b/tests/cli.rs @@ -0,0 +1,61 @@ +mod dummy_book; + +use crate::dummy_book::DummyBook; + +use assert_cmd::Command; +use predicates::boolean::PredicateBooleanExt; + +#[test] +fn mdbook_cli_can_correctly_test_a_passing_book() { + let temp = DummyBook::new().with_passing_test(true).build().unwrap(); + + let mut cmd = Command::cargo_bin("mdbook").unwrap(); + cmd.arg("test").current_dir(temp.path()); + cmd.assert().success() + .stderr(predicates::str::is_match(r##"Testing file: "([^"]+)/src/README.md""##).unwrap()) + .stderr(predicates::str::is_match(r##"Testing file: "([^"]+)/src/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##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap().not()); +} + +#[test] +fn mdbook_cli_detects_book_with_failing_tests() { + let temp = DummyBook::new().with_passing_test(false).build().unwrap(); + + let mut cmd = Command::cargo_bin("mdbook").unwrap(); + cmd.arg("test").current_dir(temp.path()); + cmd.assert().failure() + .stderr(predicates::str::is_match(r##"Testing file: "([^"]+)/src/README.md""##).unwrap()) + .stderr(predicates::str::is_match(r##"Testing file: "([^"]+)/src/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##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap()); +} + +#[test] +fn mdbook_cli_dummy_book_generates_index_html() { + let temp = DummyBook::new().build().unwrap(); + + // doesn't exist before + assert!(!temp.path().join("book").exists()); + + let mut cmd = Command::cargo_bin("mdbook").unwrap(); + cmd.arg("build").current_dir(temp.path()); + cmd.assert() + .success() + .stderr(predicates::str::contains( + r##"[ERROR] (mdbook::preprocess::links): Stack depth exceeded in first/recursive.md."##, + )) + .stderr(predicates::str::contains( + r##"[INFO] (mdbook::book): Running the html backend"##, + )); + + // exists afterward + assert!(temp.path().join("book").exists()); + + let index_file = temp.path().join("book/index.html"); + assert!(index_file.exists()); +}