use std::fs;
use std::path::{Path, PathBuf};
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("spvirit-tools has a parent directory")
.to_path_buf()
}
fn read(rel: &str) -> String {
let path = repo_root().join(rel);
fs::read_to_string(&path).unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display()))
}
fn parse(rel: &str) -> toml::Value {
read(rel)
.parse::<toml::Value>()
.unwrap_or_else(|e| panic!("cannot parse {rel}: {e}"))
}
fn workspace_version() -> String {
parse("Cargo.toml")
.get("workspace")
.and_then(|w| w.get("package"))
.and_then(|p| p.get("version"))
.and_then(|v| v.as_str())
.expect("root Cargo.toml declares [workspace.package] version")
.to_string()
}
#[test]
fn members_inherit_the_workspace_version() {
let root = parse("Cargo.toml");
let members = root["workspace"]["members"]
.as_array()
.expect("[workspace] members is an array");
for member in members {
let name = member.as_str().expect("member entries are strings");
let manifest = parse(&format!("{name}/Cargo.toml"));
let version = &manifest["package"]["version"];
assert!(
version.get("workspace").and_then(|w| w.as_bool()) == Some(true),
"{name}/Cargo.toml sets an explicit version ({version}); \
use `version.workspace = true` so the workspace stays unified",
);
}
}
#[test]
fn python_bindings_pin_the_current_tools_version() {
let expected = workspace_version();
let pyproject = parse("spvirit-py/pyproject.toml");
let deps = pyproject["project"]["dependencies"]
.as_array()
.expect("spvirit-py/pyproject.toml declares [project] dependencies");
let pin = deps
.iter()
.filter_map(|d| d.as_str())
.find(|d| {
let name: String = d
.chars()
.take_while(|c| c.is_alphanumeric() || *c == '-' || *c == '_' || *c == '.')
.collect();
name.to_lowercase().replace(['_', '.'], "-") == "spvirit-tools"
})
.unwrap_or_else(|| {
panic!(
"spvirit-py/pyproject.toml has no spvirit-tools dependency; \
`pip install spvirit` would not install the command-line tools"
)
});
let actual = pin
.split_once("==")
.unwrap_or_else(|| {
panic!("spvirit-tools pin `{pin}` is not an exact `==` requirement")
})
.1
.trim();
assert_eq!(
actual, expected,
"spvirit-py/pyproject.toml pins spvirit-tools {actual}, but the \
workspace is at {expected}; update the pin in spvirit-py/pyproject.toml",
);
}
#[test]
fn tools_wheel_ships_binaries() {
let pyproject = parse("spvirit-tools/pyproject.toml");
assert_eq!(
pyproject["tool"]["maturin"]["bindings"].as_str(),
Some("bin"),
"spvirit-tools/pyproject.toml must set [tool.maturin] bindings = \"bin\"",
);
assert_eq!(
pyproject["project"]["name"].as_str(),
Some("spvirit-tools"),
"the wheel name must match the pin in spvirit-py/pyproject.toml",
);
}