use super::*;
use crate::cli::cache::stamped_outputs_agree_with_disk;
use crate::cli::pipeline::generate::ensure_generated_header;
use crate::core::hash::{compute_file_hash, content_has_alef_marker, inject_hash_line};
fn written_but_unstamped(file: &GeneratedFile) -> String {
if file.generated_header {
ensure_generated_header(&file.path, &file.content)
} else {
file.content.clone()
}
}
fn cache_agrees_for(body: &str, relative_path: &std::path::Path) -> bool {
let root = tempfile::tempdir().expect("scratch tree");
let output = root.path().join(relative_path);
std::fs::create_dir_all(output.parent().expect("output path has a parent")).expect("output parent");
std::fs::write(&output, body).expect("write manifested output");
let manifest = root.path().join("stage.manifest");
std::fs::write(&manifest, format!("{}\n", output.display())).expect("write manifest");
stamped_outputs_agree_with_disk(&manifest)
}
fn marker_rail_files() -> Vec<GeneratedFile> {
let api = test_api();
let config = test_config();
let mut by_path: std::collections::BTreeMap<String, GeneratedFile> = std::collections::BTreeMap::new();
for language in Language::ALL {
let Ok(files) = scaffold(&api, &config, &[language]) else {
continue;
};
for file in files {
if !content_has_alef_marker(&written_but_unstamped(&file)) {
continue;
}
by_path.insert(file.path.to_string_lossy().into_owned(), file);
}
}
for seed in [
rust_toolchain_file(&[Language::Wasm]),
wasm_cargo_config_file(),
GeneratedFile {
path: std::path::PathBuf::from(".cargo/config.toml"),
content: render_cargo_config(&crate::core::config::ScaffoldCargo::default()),
generated_header: true,
},
] {
assert!(
content_has_alef_marker(&written_but_unstamped(&seed)),
"{}: CWD-gated seed no longer carries an alef marker, so the sweep below would drop it \
and this test would stop covering the file it exists for",
seed.path.display()
);
by_path.insert(seed.path.to_string_lossy().into_owned(), seed);
}
by_path.into_values().collect()
}
const MINIMUM_MARKER_RAIL_FILES: usize = 10;
const ROOT_SCAFFOLD_FILES: &[&str] = &[".cargo/config.toml", "rust-toolchain.toml", "poly.toml", "rustfmt.toml"];
#[test]
fn a_claimed_but_unstamped_scaffold_output_is_never_read_as_cached() {
let files = marker_rail_files();
assert!(
files.len() >= MINIMUM_MARKER_RAIL_FILES,
"the emitter table holds only {} marker-rail scaffold file(s), below the \
{MINIMUM_MARKER_RAIL_FILES} floor -- it has gone vacuous and would pass no matter what the \
cache does. Found: {:?}",
files.len(),
files.iter().map(|f| f.path.display().to_string()).collect::<Vec<_>>()
);
let found: std::collections::BTreeSet<String> =
files.iter().map(|f| f.path.to_string_lossy().into_owned()).collect();
for expected in ROOT_SCAFFOLD_FILES {
assert!(
found.contains(*expected),
"{expected} is a repo-root marker-rail scaffold file with no sweep-root self-heal, but \
the emitter table never produced it, so this test does not cover it. Found: {found:?}"
);
}
for file in &files {
let unstamped = written_but_unstamped(file);
assert!(
crate::core::hash::extract_hash(&unstamped).is_none(),
"{}: the pre-`finalize_hashes` bytes already carry an `alef:hash:` line, so this row \
is not the unstamped state it is supposed to stand for and asserts nothing",
file.path.display()
);
assert!(
!cache_agrees_for(&unstamped, &file.path),
"{}: alef claims this file (its prose marker is on disk) but has not stamped it, and \
the stage cache still reports agreement. That verdict skips the `finalize_hashes` \
pass that would add the `alef:hash:` line, so the file stays outside poly's \
hash-keyed skip: `poly fmt` reformats it, the next alef run writes its own bytes \
back, and neither tool yields. Header written was:\n{}",
file.path.display(),
unstamped.lines().take(3).collect::<Vec<_>>().join("\n")
);
}
}
#[test]
fn a_stamped_scaffold_output_still_reads_as_cached() {
let files = marker_rail_files();
assert!(
!files.is_empty(),
"the emitter table is empty, so this control examines nothing"
);
for file in &files {
let unstamped = written_but_unstamped(file);
let stamped = inject_hash_line(&unstamped, &compute_file_hash(&unstamped));
assert!(
stamped.contains("alef:hash:"),
"{}: control setup failed -- `inject_hash_line` produced no stamp, so the assertion \
below would be checking an unstamped file and could not distinguish the two cases",
file.path.display()
);
assert!(
cache_agrees_for(&stamped, &file.path),
"{}: a freshly stamped output must read as cached; if it does not, every stage would \
regenerate on every run",
file.path.display()
);
}
}
#[test]
fn an_unmarked_create_once_seed_still_reads_as_cached() {
for (relative_path, body) in [
("packages/php/composer.json", "{\n \"name\": \"vendor/sample\"\n}\n"),
("packages/zig/build.zig", "pub fn build() void {}\n"),
] {
let path = std::path::Path::new(relative_path);
assert!(
!content_has_alef_marker(body),
"{relative_path}: control fixture accidentally carries an alef marker, so it no longer \
stands for the unmarked-seed case"
);
assert!(
cache_agrees_for(body, path),
"{relative_path}: an unmarked create-once seed has no stamp to compare and must keep \
the existence-only rule, or its stage never hits the cache again"
);
}
}