#![cfg(unix)]
#![allow(clippy::missing_panics_doc, clippy::missing_errors_doc)]
use std::fs;
use std::path::PathBuf;
use std::process::Command;
const README: &str = include_str!("../../../README.md");
fn first_rust_block(src: &str) -> Option<String> {
let mut lines = src.lines();
let mut body = String::new();
let mut inside = false;
for line in &mut lines {
if !inside {
let trimmed = line.trim_start();
if let Some(rest) = trimmed.strip_prefix("```") {
let lang = rest.split(|c: char| c.is_whitespace() || c == ',').next()?;
if lang == "rust" {
inside = true;
}
}
} else if line.trim_start().starts_with("```") {
return Some(body);
} else {
body.push_str(line);
body.push('\n');
}
}
None
}
#[test]
#[cfg(unix)]
fn readme_quickstart_compiles() {
let snippet = first_rust_block(README).expect("README must contain a ```rust block");
assert!(
snippet.contains("fn main"),
"quickstart snippet must declare its own fn main; got: {snippet}"
);
let tmp = tempfile::tempdir().expect("tempdir");
let crate_dir: PathBuf = tmp.path().to_path_buf();
fs::create_dir_all(crate_dir.join("src")).expect("mkdir src");
let obj_crate_path = workspace_relative("crates/obj");
let manifest = format!(
r#"[package]
name = "obj_readme_compile_test"
version = "0.0.0"
edition = "2021"
publish = false
[dependencies]
obj-db = {{ path = "{obj}" }}
serde = {{ version = "1", features = ["derive"] }}
tempfile = "3"
[workspace]
"#,
obj = obj_crate_path.display(),
);
fs::write(crate_dir.join("Cargo.toml"), manifest).expect("write manifest");
fs::write(crate_dir.join("src").join("main.rs"), &snippet).expect("write snippet");
let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
let status = Command::new(&cargo)
.arg("build")
.arg("--quiet")
.current_dir(&crate_dir)
.env_remove("RUSTFLAGS") .status()
.expect("invoke cargo build");
assert!(
status.success(),
"README quickstart failed to compile; snippet was:\n---\n{snippet}\n---"
);
}
fn workspace_relative(child: &str) -> PathBuf {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut cur: PathBuf = manifest_dir;
for _ in 0..8 {
let candidate = cur.join("Cargo.toml");
if let Ok(text) = fs::read_to_string(&candidate) {
if text.contains("[workspace]") {
return cur.join(child);
}
}
if !cur.pop() {
break;
}
}
panic!(
"could not locate workspace root from {}",
env!("CARGO_MANIFEST_DIR")
);
}