I'm trying to help a library use @alice's helpful post here to get some feature flags requirements to show up on docs.rs.
In working on this, I got wondering how to write some kind of regression test to ensure that the HTML output for the docs contained the feature flag notification. How might one go about this? Was just thinking of something that would run the RUSTFLAGS=... cargo doc ... and then search the output HTML.
I've seen approaches like assert_cmd - Rust for CLI apps -- is there a similar approach for the html output for docs?
Likely easier to just do this in GitHub Actions with some bash -- is there a pure Rust approach that people might recommend?
Then with doc_auto_cfg feature from rustdoc, you don't have to define docsrs cfg flag only for #[cfg_attr] and you don't need to write the second line for every #[cfg]:
#[cfg(feature = "rt")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt")))] // You don't have to write this line any more
fn f() {}
Each banner seems to have a class="stab xxx" attribute in its HTML tag, so you could write a shell script like:
# untested; replace PROJECT with the package name
doc_auto_cfg=$(grep -P 'class="stab \w+"' target/doc/PROJECT/* | wc -c)
if [ $doc_auto_cfg -ne 0 ]; then
echo "doc_auto_cfg works"
else
echo "Error: doc_auto_cfg is broken" 1>&2
fi
Definitely -- easily done in bash. But is this what people would recommend? Again, using CLI apps as an example, many people have found a good way to do integration tests in rust for command line apps. Is anyone doing anything analogous for the documentation output?
I don't have a suggestion for that. Just in case one wants to try testing in the Rust way:
#[test]
fn test_doc_auto_cfg() {
use std::process::Command;
const DOC_DIR: &str = concat!("target/doc/", env!("CARGO_PKG_NAME"));
// Run `cargo doc --all-features --no-deps`
assert!(
Command::new("cargo")
.args(["doc", "--all-features", "--no-deps"])
.output()
.expect("Can't run cargo doc")
.status
.success(),
"cargo doc doesn't exit successfully"
);
// Run grep to check the existence of tag property in HTMLs
let output = Command::new("grep")
.args(["-P", r#"class="stab \w+""#, DOC_DIR, "-d", "recurse"])
.output()
.expect("Failed to execute grep");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
if !stdout.starts_with(DOC_DIR) {
panic!("The result of grep is unusual:\n{}", &stdout[..100]);
}
} else {
panic!("{}", String::from_utf8_lossy(&output.stderr));
}
}
Thanks for the edit -- I was going to mention how CLI integration tests with assert_cmd mean that the cargo build step is assumed, and how cargo doc might not be run yet. But your edit cleans that up!
I was hoping there would be something cleaner, but that certainly seems like it would do the trick.
I wonder if there is space for a new crate here; perhaps I'll make a POC using this as a template? (With @vague's permission of course -- ?)