use std::path::{Path, PathBuf};
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(2)
.expect("repository root above crates/alopex-sql")
.to_path_buf()
}
fn current_contract() -> String {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("nim-sql-parser")
.join("PARSER_CONTRACT_VERSION");
std::fs::read_to_string(&path)
.unwrap_or_else(|error| panic!("read {}: {error}", path.display()))
.trim()
.to_string()
}
#[test]
fn the_changelog_declares_the_current_parser_contract() {
let expected = current_contract();
let changelog_path = repo_root().join("CHANGELOG.md");
let changelog = std::fs::read_to_string(&changelog_path)
.unwrap_or_else(|error| panic!("read {}: {error}", changelog_path.display()));
const PREFIX: &str = "The Nim parser wire contract is `";
let declarations: Vec<&str> = changelog
.lines()
.filter_map(|line| line.trim_start_matches("- ").strip_prefix(PREFIX))
.filter_map(|rest| rest.split('`').next())
.collect();
let current = declarations
.first()
.unwrap_or_else(|| panic!("{PREFIX}...` is missing from {}", changelog_path.display()));
assert_eq!(
*current, expected,
"CHANGELOG.md declares parser contract `{current}` for the unreleased \
section while PARSER_CONTRACT_VERSION is `{expected}`"
);
}
#[test]
fn the_rust_consumer_pin_matches_the_parser_contract() {
let expected = current_contract();
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("build_support.rs");
let source = std::fs::read_to_string(&path)
.unwrap_or_else(|error| panic!("read {}: {error}", path.display()));
const PREFIX: &str = "pub(crate) const REQUIRED_CONTRACT_VERSION: &str = \"";
let declared = source
.lines()
.find_map(|line| line.trim_start().strip_prefix(PREFIX))
.and_then(|rest| rest.split('"').next())
.unwrap_or_else(|| {
panic!(
"REQUIRED_CONTRACT_VERSION is missing from {}",
path.display()
)
});
assert_eq!(
declared, expected,
"build_support.rs requires contract `{declared}` while \
PARSER_CONTRACT_VERSION is `{expected}`"
);
}