#![allow(clippy::unwrap_used)]
use std::path::{Path, PathBuf};
use std::process::Command;
fn fixture_path(rel_to_workspace_root: &str) -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join(rel_to_workspace_root)
}
fn classify_verdict_lines(ofn: &Path, incremental: bool) -> Vec<String> {
let bin = env!("CARGO_BIN_EXE_rustdl");
let mut c = Command::new(bin);
c.arg("classify")
.arg(ofn)
.arg("--pair-timeout-ms")
.arg("1000");
c.env(
"RUSTDL_HYPER_INCREMENTAL_FIXPOINT",
if incremental { "1" } else { "0" },
);
let out = c.output().expect("run rustdl");
let stdout = String::from_utf8_lossy(&out.stdout);
let mut lines: Vec<String> = stdout
.lines()
.filter(|l| !l.starts_with('#'))
.map(str::to_owned)
.collect();
lines.sort_unstable();
lines
}
#[test]
fn incremental_matches_baseline_on_fixtures() {
let mut compared = 0usize;
for rel in [
"ontologies/regression/funcmerge-cyclic.ofn",
"ontologies/real/pizza.ofn",
"crates/owl-dl-bench/fixtures/27_eight_way_disjunction_sat.ofn",
"crates/owl-dl-bench/fixtures/18_diamond_subsumption_unsat.ofn",
"crates/owl-dl-cli/tests/fixtures/incremental/qualified-card-forall-union.ofn",
] {
let path = fixture_path(rel);
if !path.exists() {
if rel.starts_with("ontologies/") {
continue;
}
panic!("checked-in fixture missing: {rel} (resolved from {path:?})");
}
let off = classify_verdict_lines(&path, false);
let on = classify_verdict_lines(&path, true);
assert_eq!(off, on, "mismatch on {rel}");
compared += 1;
}
assert!(
compared >= 2,
"expected ≥2 fixtures compared (the checked-in bench fixtures); got {compared} \
— the incremental-fixpoint identity gate would be vacuous"
);
}