1 //! This will create an entire book in a temporary directory using some
2 //! dummy contents from the `tests/dummy-book/` directory.
4 // Not all features are used in all test crates, so...
5 #![allow(dead_code, unused_variables, unused_imports, unused_extern_crates)]
10 use mdbook
::errors
::*;
11 use mdbook
::utils
::fs
::file_to_string
;
12 use std
::fs
::{self, File}
;
13 use std
::io
::{Read, Write}
;
16 // The funny `self::` here is because we've got an `extern crate ...` and are
18 use self::mdbook
::MDBook
;
19 use self::tempfile
::{Builder as TempFileBuilder, TempDir}
;
20 use self::walkdir
::WalkDir
;
22 /// Create a dummy book in a temporary directory, using the contents of
23 /// `SUMMARY_MD` as a guide.
25 /// The "Nested Chapter" file contains a code block with a single
26 /// `assert!($TEST_STATUS)`. If you want to check MDBook's testing
27 /// functionality, `$TEST_STATUS` can be substitute for either `true` or
28 /// `false`. This is done using the `passing_test` parameter.
29 #[derive(Clone, Debug, PartialEq)]
30 pub struct DummyBook
{
35 /// Create a new `DummyBook` with all the defaults.
36 pub fn new() -> DummyBook
{
37 DummyBook { passing_test: true }
40 /// Whether the doc-test included in the "Nested Chapter" should pass or
41 /// fail (it passes by default).
42 pub fn with_passing_test(&mut self, test_passes
: bool
) -> &mut DummyBook
{
43 self.passing_test
= test_passes
;
47 /// Write a book to a temporary directory using the provided settings.
48 pub fn build(&self) -> Result
<TempDir
> {
49 let temp
= TempFileBuilder
::new()
50 .prefix("dummy_book-")
52 .chain_err(|| "Unable to create temp directory")?
;
54 let dummy_book_root
= Path
::new(env
!("CARGO_MANIFEST_DIR")).join("tests/dummy_book");
55 recursive_copy(&dummy_book_root
, temp
.path()).chain_err(|| {
56 "Couldn't copy files into a \
60 let sub_pattern
= if self.passing_test { "true" }
else { "false" }
;
61 let file_containing_test
= temp
.path().join("src/first/nested.md");
62 replace_pattern_in_file(&file_containing_test
, "$TEST_STATUS", sub_pattern
)?
;
68 fn replace_pattern_in_file(filename
: &Path
, from
: &str, to
: &str) -> Result
<()> {
69 let contents
= file_to_string(filename
)?
;
70 File
::create(filename
)?
.write_all(contents
.replace(from
, to
).as_bytes())?
;
75 /// Read the contents of the provided file into memory and then iterate through
76 /// the list of strings asserting that the file contains all of them.
77 pub fn assert_contains_strings
<P
: AsRef
<Path
>>(filename
: P
, strings
: &[&str]) {
78 let filename
= filename
.as_ref();
79 let content
= file_to_string(filename
).expect("Couldn't read the file's contents");
84 "Searching for {:?} in {}\n\n{}",
92 pub fn assert_doesnt_contain_strings
<P
: AsRef
<Path
>>(filename
: P
, strings
: &[&str]) {
93 let filename
= filename
.as_ref();
94 let content
= file_to_string(filename
).expect("Couldn't read the file's contents");
99 "Found {:?} in {}\n\n{}",
107 /// Recursively copy an entire directory tree to somewhere else (a la `cp -r`).
108 fn recursive_copy
<A
: AsRef
<Path
>, B
: AsRef
<Path
>>(from
: A
, to
: B
) -> Result
<()> {
109 let from
= from
.as_ref();
110 let to
= to
.as_ref();
112 for entry
in WalkDir
::new(&from
) {
113 let entry
= entry
.chain_err(|| "Unable to inspect directory entry")?
;
115 let original_location
= entry
.path();
116 let relative
= original_location
118 .expect("`original_location` is inside the `from` directory");
119 let new_location
= to
.join(relative
);
121 if original_location
.is_file() {
122 if let Some(parent
) = new_location
.parent() {
123 fs
::create_dir_all(parent
).chain_err(|| "Couldn't create directory")?
;
126 fs
::copy(&original_location
, &new_location
)
127 .chain_err(|| "Unable to copy file contents")?
;
134 pub fn new_copy_of_example_book() -> Result
<TempDir
> {
135 let temp
= TempFileBuilder
::new().prefix("book-example").tempdir()?
;
137 let book_example
= Path
::new(env
!("CARGO_MANIFEST_DIR")).join("book-example");
139 recursive_copy(book_example
, temp
.path())?
;