1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
//! docmatic: //! //! `docmatic` runs `rustdoc` on your documentation files. //! //! ## Writing code blocks //! //! See ["Documentation tests"](https://doc.rust-lang.org/beta/rustdoc/documentation-tests.html) //! for how to customize your code blocks being run as tests. //! //! ## Example //! //! First, add this to your `Cargo.toml`: //! //! ```toml //! [dev-dependencies] //! docmatic = "0.1" //! ``` //! //! Next, in your test file: //! //! ```rust //! extern crate docmatic; //! //! fn test_readme() { //! docmatic::assert_file("README.md"); //! } //! ``` extern crate which; use std::path; use std::ffi::OsStr; /// A specialized process builder managing a `rustdoc` test session. /// /// # Example /// /// The following code will test the crate README with the `docmatic` /// configuration set and a default library path: /// /// ```rust /// extern crate docmatic; /// /// use std::default::Default; /// /// fn test_readme() { /// docmatic::Assert::default() /// .cfg("docmatic") /// .test_file("README.md") /// } /// ``` pub struct Assert(std::process::Command); impl Assert { /// Construct a new `Assert` with no flags set. /// /// Will likely fail if you don't provide at least one library path /// containing the tested crate. Instead, you should probably use /// [`Assert::default`] /// /// [`Assert::default`]: #tymethod.default pub fn new() -> Self { let executable = which::which("rustdoc").expect("rustdoc not found"); Assert(std::process::Command::new(executable)) } /// Add a path to the library paths passed to `rustdoc`. pub fn library_path<S>(&mut self, path: S) -> &mut Self where S: AsRef<OsStr>, { self.0.arg("--library-path").arg(path); self } /// Add a *cfg* to the configuration passed to `rustdoc`. pub fn cfg<S>(&mut self, cfg: S) -> &mut Self where S: AsRef<OsStr>, { self.0.arg("--cfg").arg(cfg); self } /// Test the given file, and panics on failure. pub fn test_file<P>(&mut self, path: P) where P: AsRef<path::Path>, { let process = self.0.arg("--test").arg(path.as_ref()).spawn(); let result = process .expect("rustdoc is runnable") .wait() .expect("rustdoc can run"); assert!( result.success(), format!("Failed to run rustdoc tests on '{:?}'", path.as_ref()) ); } } impl Default for Assert { /// Create an `Assert` instance with the following default parameters: /// /// * `--library-path` set to the current *deps* directory (`target/debug/deps` or /// `target/release/deps` depending on the test compilation mode). /// fn default() -> Self { let mut assert = Self::new(); let current_exe = std::env::current_exe() .and_then(|p| p.canonicalize()) .expect("could not get path to test executable"); assert.library_path(current_exe.parent().expect("parent exists")); assert } } /// Test a single file with default parameters. pub fn assert_file<P>(documentation: P) where P: AsRef<path::Path>, { Assert::default().test_file(documentation); }