From 10d30a2dc051db8aa32a21d607ca2dd5826ad8f9 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 13 Jul 2021 16:03:07 -0700 Subject: [PATCH 1/3] Add CLI tests Part of #1568 --- Cargo.lock | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + tests/cli.rs | 61 ++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 tests/cli.rs 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()); +} From 11b1e86187d90266255411f2601a30607e2e94cf Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 13 Jul 2021 17:09:49 -0700 Subject: [PATCH 2/3] Fix path dumps under windows --- tests/cli.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index c400ff11..9fc8b498 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -12,10 +12,10 @@ fn mdbook_cli_can_correctly_test_a_passing_book() { 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##"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##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap().not()); } @@ -27,10 +27,10 @@ fn mdbook_cli_detects_book_with_failing_tests() { 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##"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##"Nested_Chapter::Rustdoc_include_works_with_anchors_too \(line \d+\) ... FAILED"##).unwrap()); } @@ -46,9 +46,10 @@ fn mdbook_cli_dummy_book_generates_index_html() { 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::is_match(r##"Stack depth exceeded in first[\\/]recursive.md."##) + .unwrap(), + ) .stderr(predicates::str::contains( r##"[INFO] (mdbook::book): Running the html backend"##, )); From 9bede85efabf246e46f228ffa3c6adda3c67705e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 29 Jul 2021 14:42:54 -0700 Subject: [PATCH 3/3] Move cli tests to their own subdir --- tests/cli/build.rs | 29 +++++++++++++++++++++++++++++ tests/cli/mod.rs | 2 ++ tests/{cli.rs => cli/test.rs} | 28 ---------------------------- tests/cli_tests.rs | 2 ++ 4 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 tests/cli/build.rs create mode 100644 tests/cli/mod.rs rename tests/{cli.rs => cli/test.rs} (70%) create mode 100644 tests/cli_tests.rs diff --git a/tests/cli/build.rs b/tests/cli/build.rs new file mode 100644 index 00000000..16b6b79b --- /dev/null +++ b/tests/cli/build.rs @@ -0,0 +1,29 @@ +use crate::dummy_book::DummyBook; + +use assert_cmd::Command; + +#[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::is_match(r##"Stack depth exceeded in first[\\/]recursive.md."##) + .unwrap(), + ) + .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()); +} diff --git a/tests/cli/mod.rs b/tests/cli/mod.rs new file mode 100644 index 00000000..a73a4031 --- /dev/null +++ b/tests/cli/mod.rs @@ -0,0 +1,2 @@ +mod build; +mod test; diff --git a/tests/cli.rs b/tests/cli/test.rs similarity index 70% rename from tests/cli.rs rename to tests/cli/test.rs index 9fc8b498..d974654d 100644 --- a/tests/cli.rs +++ b/tests/cli/test.rs @@ -1,5 +1,3 @@ -mod dummy_book; - use crate::dummy_book::DummyBook; use assert_cmd::Command; @@ -34,29 +32,3 @@ fn mdbook_cli_detects_book_with_failing_tests() { .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::is_match(r##"Stack depth exceeded in first[\\/]recursive.md."##) - .unwrap(), - ) - .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()); -} diff --git a/tests/cli_tests.rs b/tests/cli_tests.rs new file mode 100644 index 00000000..0b005d01 --- /dev/null +++ b/tests/cli_tests.rs @@ -0,0 +1,2 @@ +mod cli; +mod dummy_book;