use super::*;
fn drift_test_config() -> crate::core::config::ResolvedCrateConfig {
let cfg: crate::core::config::NewAlefConfig = toml::from_str(
r#"
[workspace]
languages = ["rust"]
[[crates]]
name = "sample"
sources = ["src/lib.rs"]
"#,
)
.expect("valid config");
cfg.resolve().expect("resolvable").remove(0)
}
fn real_formatter_drift(
candidates: Vec<RealFormatCandidate>,
base_dir: &std::path::Path,
) -> (Vec<String>, FormatDriftStats) {
real_formatter_drift_with(candidates, base_dir, &crate::cli::pipeline::is_tool_available)
}
fn candidate(full_path: &std::path::Path, disk_content: &str, rendered_content: &str) -> RealFormatCandidate {
RealFormatCandidate {
full_path: full_path.to_path_buf(),
disk_content: disk_content.to_string(),
rendered_content: rendered_content.to_string(),
}
}
#[test]
fn skips_and_counts_every_candidate_when_poly_is_unavailable() {
let dir = tempfile::tempdir().expect("tempdir");
let candidates = vec![
candidate(&dir.path().join("a.toml"), "[a]\nx = 1\n", "[a]\nx=1\n"),
candidate(&dir.path().join("b.py"), "x = 1\n", "x=1\n"),
];
let (drifted, stats) = real_formatter_drift_with(candidates, dir.path(), &|_tool| false);
assert!(
drifted.is_empty(),
"a skipped comparison must never manufacture a drift finding: {drifted:?}"
);
assert_eq!(
stats,
FormatDriftStats {
compared: 0,
skipped_missing_formatter: 2,
skipped_staging_error: 0,
skipped_no_faithful_prediction: 0,
matched_render_exactly: 0,
},
"every candidate must be counted as skipped, never silently dropped, when poly is absent"
);
}
#[test]
fn is_a_trivial_no_op_on_an_empty_candidate_list() {
let dir = tempfile::tempdir().expect("tempdir");
let (drifted, stats) = real_formatter_drift_with(Vec::new(), dir.path(), &|_tool| true);
assert!(drifted.is_empty());
assert_eq!(stats, FormatDriftStats::default());
}
#[test]
fn catches_a_toml_file_whose_rendered_value_genuinely_differs_from_disk() {
let Some(_poly) = crate::test_support::tool_available_with_stable_path("poly") else {
return;
};
let dir = tempfile::tempdir().expect("tempdir");
let real_path = dir.path().join("pyproject.toml");
std::fs::write(&real_path, "[project]\nname = \"old\"\n").unwrap();
let candidates = vec![candidate(
&real_path,
"[project]\nname = \"old\"\n",
"[project]\nname=\"new\"\n",
)];
let (drifted, stats) = real_formatter_drift(candidates, dir.path());
assert_eq!(drifted, vec![real_path.display().to_string()]);
assert_eq!(
stats,
FormatDriftStats {
compared: 1,
skipped_missing_formatter: 0,
skipped_staging_error: 0,
skipped_no_faithful_prediction: 0,
matched_render_exactly: 0,
}
);
}
#[test]
fn is_silent_once_poly_fmt_converges_the_render_to_match_disk() {
let Some(_poly) = crate::test_support::tool_available_with_stable_path("poly") else {
return;
};
let dir = tempfile::tempdir().expect("tempdir");
let real_path = dir.path().join("pyproject.toml");
let rendered = "[project]\nname=\"same\"\n";
let (_drifted, _stats) = real_formatter_drift(
vec![candidate(&real_path, "placeholder -- overwritten below", rendered)],
dir.path(),
);
let formatted_once = format_once_for_test(rendered, dir.path());
std::fs::write(&real_path, &formatted_once).unwrap();
let (drifted, stats) = real_formatter_drift(vec![candidate(&real_path, &formatted_once, rendered)], dir.path());
assert!(
drifted.is_empty(),
"an already-converged file must not be reported drifted: {drifted:?}"
);
assert_eq!(stats.compared, 1);
}
#[test]
fn formatter_managed_e2e_manifests_verify_after_generation_formatting() {
let dir = tempfile::tempdir().expect("tempdir");
let cases = [
"test_apps/csharp/Xberg.E2eTests.csproj",
"test_apps/java/pom.xml",
"test_apps/zig/build.zig.zon",
];
let mut candidates = Vec::new();
for relative in cases {
let path = dir.path().join(relative);
std::fs::create_dir_all(path.parent().expect("manifest parent")).expect("create manifest parent");
std::fs::write(&path, "formatted\n").expect("write formatted manifest");
candidates.push(candidate(&path, "formatted\n", "raw render\n"));
}
let run_filename_keyed_formatter = |paths: &[std::path::PathBuf], _base: &std::path::Path| {
let mut formatted = 0usize;
for path in paths {
let name = path.file_name().and_then(|name| name.to_str()).unwrap_or_default();
if matches!(name, "Xberg.E2eTests.csproj" | "pom.xml" | "build.zig.zon") {
std::fs::write(path, "formatted\n")?;
formatted += 1;
}
}
anyhow::ensure!(
formatted == 3,
"formatter reached {formatted} of 3 canonical manifest names"
);
Ok(())
};
let (drifted, stats) = real_formatter_drift_with_runner(
candidates,
dir.path(),
&|tool| tool == "poly",
&run_filename_keyed_formatter,
);
assert!(
drifted.is_empty(),
"freshly generated and formatted E2E manifests must verify without false drift: {drifted:?}"
);
assert_eq!(
stats.compared, 3,
"all three formatter-managed manifests must be compared"
);
}
fn format_once_for_test(content: &str, base_dir: &std::path::Path) -> String {
let scratch = base_dir.join("scratch.toml");
std::fs::write(&scratch, content).unwrap();
crate::cli::pipeline::poly_format_strict(std::slice::from_ref(&scratch), base_dir).expect("poly fmt must succeed");
let formatted = std::fs::read_to_string(&scratch).unwrap();
std::fs::remove_file(&scratch).ok();
formatted
}
#[test]
fn leaves_no_temp_file_behind_after_comparing() {
let Some(_poly) = crate::test_support::tool_available_with_stable_path("poly") else {
return;
};
let dir = tempfile::tempdir().expect("tempdir");
let real_path = dir.path().join("pyproject.toml");
std::fs::write(&real_path, "[project]\nname = \"old\"\n").unwrap();
let candidates = vec![candidate(
&real_path,
"[project]\nname = \"old\"\n",
"[project]\nname=\"new\"\n",
)];
let _ = real_formatter_drift(candidates, dir.path());
let leftovers: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(Result::ok)
.map(|entry| entry.file_name())
.filter(|name| name != "pyproject.toml")
.collect();
assert!(
leftovers.is_empty(),
"no temp file may survive a comparison call, found: {leftovers:?}"
);
}
#[test]
fn render_predicts_final_bytes_clears_rust_and_markdown_only_without_poly() {
let cases = [
("lib.rs", false, true),
("reference.md", false, true),
("pyproject.toml", false, false),
("bindings.go", false, false),
("noextension", false, false),
];
for (name, with_poly, without_poly) in cases {
assert_eq!(
render_predicts_final_bytes(std::path::Path::new(name), true),
with_poly,
"render_predicts_final_bytes({name:?}) with poly present must be {with_poly}"
);
assert_eq!(
render_predicts_final_bytes(std::path::Path::new(name), false),
without_poly,
"render_predicts_final_bytes({name:?}) with poly absent must be {without_poly}"
);
}
}
#[test]
fn managed_toml_drift_preview_preserves_the_existing_provenance_header() {
let dir = tempfile::tempdir().expect("tempdir");
let existing = "# This file is auto-generated by alef — DO NOT EDIT.\n\
# alef:hash:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\
# To regenerate: alef generate\n\
# To verify freshness: alef verify --exit-code\n\n\
[discovery]\nexclude = [\"generated/**\", \"consumer/**\"]\n";
let file = crate::core::backend::GeneratedFile {
path: std::path::PathBuf::from("poly.toml"),
content: "[discovery]\nexclude = [\"generated/**\"]\n".to_string(),
generated_header: true,
};
let output = managed_output_for_drift(&file, existing, dir.path())
.into_iter()
.next()
.expect("managed output");
assert!(
output
.content
.contains("# To verify freshness: alef verify --exit-code")
);
assert!(output.content.contains("\"consumer/**\""));
assert!(
crate::cli::pipeline::matches_alef_output(&dir.path().join("poly.toml"), existing, &output.content),
"verification must predict the merge writer's fixed point, including its preserved header"
);
}
#[test]
fn ordinary_generated_toml_uses_the_fresh_render_without_merge_semantics() {
let dir = tempfile::tempdir().expect("tempdir");
let existing = "# This file is auto-generated by alef — DO NOT EDIT.\n\
# alef:hash:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\
# To regenerate: alef generate\n\
# To verify freshness: alef verify\n\n\
[build]\ntarget-dir = \"consumer-target\"\n";
let file = crate::core::backend::GeneratedFile {
path: std::path::PathBuf::from(".cargo/config.toml"),
content: "[build]\ntarget-dir = \"generated-target\"\n".to_string(),
generated_header: true,
};
let output = managed_output_for_drift(&file, existing, dir.path())
.into_iter()
.next()
.expect("managed output");
assert!(output.content.contains("generated-target"));
assert!(!output.content.contains("consumer-target"));
}
#[test]
fn drift_preview_preserves_an_existing_marker_for_an_unheadered_render() {
let dir = tempfile::tempdir().expect("tempdir");
let cases = [
("test_apps/csharp/Xberg.E2eTests.csproj", "<Project />\n"),
(
"test_apps/java/pom.xml",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project />\n",
),
("test_apps/zig/build.zig.zon", ".{ .name = .e2e }\n"),
];
for (relative, raw) in cases {
let path = dir.path().join(relative);
let marked = crate::cli::pipeline::ensure_generated_header(&path, raw);
let file_hash = crate::core::hash::compute_file_hash(&marked);
let existing = crate::core::hash::inject_hash_line(&marked, &file_hash);
let file = crate::core::backend::GeneratedFile {
path: std::path::PathBuf::from(relative),
content: raw.to_owned(),
generated_header: false,
};
let output = managed_output_for_drift(&file, &existing, dir.path())
.into_iter()
.next()
.expect("managed output");
assert!(
crate::cli::pipeline::matches_alef_output(&path, &existing, &output.content),
"{relative}: verify must mirror the writer's disk-aware header preservation"
);
}
}
#[test]
fn drifted_marked_paths_compares_an_rs_candidate_on_the_fast_path_when_poly_is_unavailable() {
let dir = tempfile::tempdir().expect("tempdir");
let file = crate::core::backend::GeneratedFile {
path: std::path::PathBuf::from("lib.rs"),
content: "pub fn greet() -> &'static str { \"old\" }\n".to_string(),
generated_header: true,
};
let rendered = crate::cli::commands::adopt::managed_outputs(std::slice::from_ref(&file), dir.path());
std::fs::write(dir.path().join("lib.rs"), &rendered[0].content).unwrap();
let (drifted, stats) = drifted_marked_paths_with(
std::slice::from_ref(&file),
dir.path(),
&drift_test_config(),
&|_tool| false,
);
assert!(
drifted.is_empty(),
"an up-to-date .rs file must be compared and found clean without poly, not reported: {drifted:?}"
);
assert_eq!(
stats,
FormatDriftStats {
matched_render_exactly: 1,
..FormatDriftStats::default()
},
"a fast-path file must be counted as settled against the render, never as a real-formatter \
skip just because poly is absent"
);
let changed = vec![crate::core::backend::GeneratedFile {
path: std::path::PathBuf::from("lib.rs"),
content: "pub fn greet() -> &'static str { \"new\" }\n".to_string(),
generated_header: true,
}];
let (drifted, stats) = drifted_marked_paths_with(&changed, dir.path(), &drift_test_config(), &|_tool| false);
assert_eq!(
drifted,
vec![dir.path().join("lib.rs").display().to_string()],
"a genuinely stale .rs file must be REPORTED with poly absent -- this is the finding the \
alef#458 gate suppressed on the no-poly CI leg"
);
assert_eq!(stats, FormatDriftStats::default());
}
#[test]
fn rust_binding_bytes_on_disk_match_a_fresh_render_with_no_poly() {
if !crate::cli::pipeline::is_tool_available("rustfmt") {
return;
}
let temp = tempfile::tempdir().expect("tempdir");
let root = temp.path().canonicalize().unwrap_or_else(|_| temp.path().to_path_buf());
write_first_run_fixture(&root);
assert!(
!root.join("rustfmt.toml").exists(),
"fixture setup: this run must start with no committed rustfmt.toml, or it is not \
exercising a project's first `alef all` run at all"
);
let _cargo_guard = crate::test_support::RealCargoGuard::acquire();
let _no_poly = crate::test_support::PathWithoutToolGuard::exclude("poly");
let _cwd = crate::test_support::CwdGuard::enter(&root);
let context = crate::bin_cli::dispatch::DispatchContext {
config_path: root.join("alef.toml"),
crate_filter: Vec::new(),
};
crate::bin_cli::all_commands::handle(first_run_all_command(), &context)
.expect("alef all must succeed against a plain python fixture");
let mut compared = 0usize;
let mut mismatches = Vec::new();
for entry in walkdir::WalkDir::new(&root).into_iter().filter_map(Result::ok) {
let path = entry.path();
if !path.is_file() || path.extension().and_then(|extension| extension.to_str()) != Some("rs") {
continue;
}
let Ok(disk) = std::fs::read_to_string(path) else {
continue;
};
if !crate::core::hash::content_has_alef_marker(&disk) {
continue;
}
compared += 1;
let rerendered = crate::cli::pipeline::normalize_content(&root, path, &disk);
if rerendered != disk {
mismatches.push(format!(
"{}\n--- on disk ---\n{}\n--- fresh render ---\n{}",
path.display(),
first_differing_lines(&disk, &rerendered),
first_differing_lines(&rerendered, &disk)
));
}
}
assert!(
compared > 0,
"no marked .rs file was produced by this run, so every byte comparison above was \
vacuous -- this check examined nothing"
);
assert!(
mismatches.is_empty(),
"{compared} marked .rs file(s) compared; {} differ from a fresh in-memory render on a \
first run with no poly, so the .rs fast-path prediction is still unsound:\n{}",
mismatches.len(),
mismatches.join("\n\n")
);
}
fn first_differing_lines(left: &str, right: &str) -> String {
let start = left
.lines()
.zip(right.lines())
.position(|(l, r)| l != r)
.unwrap_or_else(|| left.lines().count().min(right.lines().count()));
left.lines().skip(start).take(6).collect::<Vec<_>>().join("\n")
}
const FIRST_RUN_FIXTURE_SOURCE: &str = "pub fn compute_widget_totals(\n \
alpha: String,\n bravo: String,\n charlie: String,\n delta: String,\n echo: String,\n \
foxtrot: String,\n golf: String,\n hotel: String,\n india: String,\n juliett: String,\n\
) -> String {\n \
format!(\"{alpha}{bravo}{charlie}{delta}{echo}{foxtrot}{golf}{hotel}{india}{juliett}\")\n\
}\n";
const FIRST_RUN_FIXTURE_CARGO_TOML: &str = "[package]\nname = \"test-lib\"\nversion = \"0.1.0\"\nedition = \"2024\"\n";
const FIRST_RUN_FIXTURE_ALEF_TOML: &str = r#"
[workspace]
languages = ["python"]
[[crates]]
name = "test-lib"
sources = ["src/lib.rs"]
version_from = "Cargo.toml"
[crates.python]
module_name = "test_lib"
[crates.python.stubs]
output = "packages/python/test_lib"
"#;
fn write_first_run_fixture(root: &std::path::Path) {
std::fs::create_dir_all(root.join("src")).expect("create fixture src directory");
std::fs::write(root.join("src/lib.rs"), FIRST_RUN_FIXTURE_SOURCE).expect("write fixture source");
std::fs::write(root.join("Cargo.toml"), FIRST_RUN_FIXTURE_CARGO_TOML).expect("write fixture Cargo.toml");
std::fs::write(root.join("alef.toml"), FIRST_RUN_FIXTURE_ALEF_TOML).expect("write fixture alef.toml");
}
fn first_run_all_command() -> crate::bin_cli::args::Commands {
crate::bin_cli::args::Commands::All {
clean: false,
clobber_create_once_seeds: false,
strict: false,
skip_frb: false,
skip_snippet_validation: false,
skip_compile: true,
}
}