From 9fab267da18f6e7c8e424a2c1b074cfd562db405 Mon Sep 17 00:00:00 2001 From: Michael Bryan Date: Sun, 9 Jul 2017 04:31:30 +0800 Subject: [PATCH] Added some end-user "sanity" tests --- tests/integration_tests.rs | 197 +++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 tests/integration_tests.rs diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs new file mode 100644 index 00000000..66911e16 --- /dev/null +++ b/tests/integration_tests.rs @@ -0,0 +1,197 @@ +/// Tests which exercise the overall application, in particular the `MDBook` +/// initialization and build/rendering process. +/// +/// This will create an entire book in a temporary directory using some +/// dummy content. + +extern crate mdbook; +extern crate tempdir; +extern crate env_logger; + +use std::path::Path; +use std::fs::{self, File}; +use std::io::{Read, Write}; + +use tempdir::TempDir; +use mdbook::MDBook; + + +const SUMMARY_MD: &'static str = "# Summary + +[Introduction](intro.md) + +- [First Chapter](./first/index.md) + - [Nested Chapter](./first/nested.md) +- [Second Chapter](./second.md) + +[Conclusion](./conclusion.md) +"; + +const INTRO: &'static str = "# Introduction + +Here's some interesting text..."; + +const FIRST: &'static str = "# First Chapter + +more text."; + +const NESTED: &'static str = r#"# Nested Chapter + +This file has some testable code. + +```rust +assert!($TEST_STATUS); +```"#; + +const SECOND: &'static str = "# Second Chapter"; + +const CONCLUSION: &'static str = "# Conclusion"; + +#[test] +fn build_the_dummy_book() { + let temp = create_book(true); + let mut md = MDBook::new(temp.path()); + + md.build().unwrap(); +} + +#[test] +fn mdbook_can_correctly_test_a_passing_book() { + let temp = create_book(true); + let mut md = MDBook::new(temp.path()); + + assert!(md.test().is_ok()); +} + +#[test] +fn mdbook_detects_book_with_failing_tests() { + let temp = create_book(false); + let mut md = MDBook::new(temp.path()); + + assert!(md.test().is_err()); +} + +#[test] +fn by_default_mdbook_generates_rendered_content_in_the_book_directory() { + let temp = create_book(false); + let mut md = MDBook::new(temp.path()); + + assert!(!temp.path().join("book").exists()); + md.build().unwrap(); + + assert!(temp.path().join("book").exists()); + assert!(temp.path().join("book").join("index.html").exists()); +} + +#[test] +fn make_sure_bottom_level_files_contain_links_to_chapters() { + let temp = create_book(false); + let mut md = MDBook::new(temp.path()); + md.build().unwrap(); + + let dest = temp.path().join("book"); + let links = vec![ + "intro.html", + "first/index.html", + "first/nested.html", + "second.html", + "conclusion.html", + ]; + + let files_in_bottom_dir = vec!["index.html", "intro.html", "second.html", "conclusion.html"]; + + for filename in files_in_bottom_dir { + assert_contains_strings(dest.join(filename), &links); + } +} + +#[test] +fn check_correct_cross_links_in_nested_dir() { + let temp = create_book(false); + let mut md = MDBook::new(temp.path()); + md.build().unwrap(); + + let first = temp.path().join("book").join("first"); + let links = vec![ + r#""#, + "intro.html", + "first/index.html", + "first/nested.html", + "second.html", + "conclusion.html", + ]; + + let files_in_nested_dir = vec!["index.html", "nested.html"]; + + for filename in files_in_nested_dir { + assert_contains_strings(first.join(filename), &links); + } +} + +/// Create a dummy book in a temporary directory, using the contents of +/// `SUMMARY_MD` as a guide. +/// +/// The "Nested Chapter" file contains a code block with a single +/// `assert!($TEST_STATUS)`. If you want to check MDBook's testing +/// functionality, `$TEST_STATUS` can be substitute for either `true` or +/// `false`. This is done using the `passing_test` parameter. +fn create_book(passing_test: bool) -> TempDir { + let temp = TempDir::new("dummy_book").unwrap(); + + let src = temp.path().join("src"); + fs::create_dir_all(&src).unwrap(); + + File::create(src.join("SUMMARY.md")) + .unwrap() + .write_all(SUMMARY_MD.as_bytes()) + .unwrap(); + File::create(src.join("intro.md")) + .unwrap() + .write_all(INTRO.as_bytes()) + .unwrap(); + + let first = src.join("first"); + fs::create_dir_all(&first).unwrap(); + File::create(first.join("index.md")) + .unwrap() + .write_all(FIRST.as_bytes()) + .unwrap(); + + let to_substitute = if passing_test { "true" } else { "false" }; + let nested_text = NESTED.replace("$TEST_STATUS", to_substitute); + File::create(first.join("nested.md")) + .unwrap() + .write_all(nested_text.as_bytes()) + .unwrap(); + + File::create(src.join("second.md")) + .unwrap() + .write_all(SECOND.as_bytes()) + .unwrap(); + File::create(src.join("conclusion.md")) + .unwrap() + .write_all(CONCLUSION.as_bytes()) + .unwrap(); + + temp +} + +fn assert_contains_strings>(filename: P, strings: &[&str]) { + println!("Checking {}", filename.as_ref().display()); + println!(); + + let mut content = String::new(); + File::open(filename) + .expect("Couldn't open the provided file") + .read_to_string(&mut content) + .unwrap(); + + println!("{}", content); + println!(); + println!(); + + for s in strings { + println!("Checking for {:?}", s); + assert!(content.contains(s)); + } +} \ No newline at end of file