Skip to content
This repository was archived by the owner on Dec 1, 2022. It is now read-only.

Allow passing arguments to the rustdoc command #2

Merged
merged 4 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "docmatic"
version = "0.1.1"
authors = ["Ed Page <[email protected]>"]
authors = ["Ed Page <[email protected]>", "Martin Larralde <[email protected]>"]
description = "Test Rust examples in your documentation."
repository = "https://github.com/assert-rs/docmatic"
documentation = "https://docs.rs/docmatic"
Expand All @@ -15,5 +15,4 @@ travis-ci = { repository = "assert-rs/docmatic" }
appveyor = { repository = "epage/docmatic" }

[dependencies]
glob = "0.2"
which = "2.0"
111 changes: 88 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,101 @@
//! }
//! ```

extern crate glob;
extern crate which;

use std::path;
use std::ffi::OsStr;

pub fn assert_file<P>(documentation: P)
where
P: AsRef<path::Path>,
{
assert_file_impl(documentation.as_ref())
}
/// 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
}

fn assert_file_impl(documentation: &path::Path) {
let rustdoc = which::which("rustdoc").expect("run with rust toolchain available");
/// 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
}

let current_exe = std::path::Path::new(&std::env::current_exe().unwrap())
.canonicalize()
.unwrap();
let deps = current_exe.parent().unwrap();
/// 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 mut cmd = std::process::Command::new(rustdoc);
cmd.arg("--verbose")
.args(&["--library-path", deps.to_str().unwrap()])
.arg("--test")
.arg(documentation);
let result = process
.expect("rustdoc is runnable")
.wait()
.expect("rustdoc can run");

let result = cmd.spawn()
.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
}
}

assert!(result.success(), "Failed to run rustdoc tests on README.md");
/// Test a single file with default parameters.
pub fn assert_file<P>(documentation: P)
where
P: AsRef<path::Path>,
{
Assert::default().test_file(documentation);
}
6 changes: 6 additions & 0 deletions tests/test_readme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern crate docmatic;

#[test]
fn test_readme() {
docmatic::assert_file("README.md");
}