Files
ARCADIA-Studio/harness/experiments/lifecycle-fixture-preflight-20260913/fixture/strong-preflight-d61-r1/preflight-source.rs
T

117 lines
4.3 KiB
Rust

//! Source-only preflight; parent compiles/runs this against its exact oa-core.
//! Usage: preflight.exe PATH_TO_lifecycle-native.arcadia
use oa_core::{operations, source_project, validation, *};
use std::collections::BTreeMap;
fn id(n: u128) -> Id {
Id::from_u128(0x21c0fe00000040008000000000000000 + n)
}
fn main() {
let args: Vec<_> = std::env::args().collect();
assert_eq!(args.len(), 2, "Pass the prepared source file");
let source = std::fs::read_to_string(&args[1]).unwrap();
let p = language::parse(&source).expect("Prepared source must parse through actual core");
let issues = validation::validate(&p);
let errors: Vec<_> = issues
.iter()
.filter(|issue| issue.severity == validation::Severity::Error)
.collect();
assert!(errors.is_empty(), "Fixture admission failed: {errors:#?}");
validate_candidate(&p).expect("Ordinary command admission must accept the whole Project");
let bundle = source_project::SourceBundle {
entry: "lifecycle-native.arcadia".into(),
files: BTreeMap::from([("lifecycle-native.arcadia".into(), source.clone())]),
};
let compiled = source_project::compile_bundle(&bundle, Default::default())
.expect("Use the actual source-project admission path");
assert_eq!(
compiled.bundle, bundle,
"Keep comments, Unicode and all explicit IDs byte-for-byte"
);
assert_eq!(compiled.decoded.project, p);
let canonical = language::format(&p);
let reparsed = language::parse(&canonical).unwrap();
assert_eq!(
reparsed, p,
"Compare the entire Project, not selected elements"
);
assert_eq!(language::format(&reparsed), canonical);
assert_eq!(p.elements.len(), 61);
assert_eq!(p.relations.len(), 5);
for (owner, steps) in [
(1000, vec![1005, 1040, 1030, 1060, 1050, 1070]),
(2000, vec![2005, 2040, 2030, 2060, 2050, 2070]),
(3000, vec![3010, 3020, 3040, 3050, 3070]),
(4000, vec![4040, 4080]),
(5000, vec![5040, 5070, 5050]),
(6000, vec![6080]),
] {
assert_eq!(
p.elements[&id(owner)].steps().unwrap(),
&steps.into_iter().map(id).collect::<Vec<_>>()
);
}
for base in [1000, 2000] {
for (offset, call, expression) in [
(40, 40, "420.0"),
(30, 30, "380.0"),
(60, 30, "378.0"),
(50, 40, "418.0"),
] {
let occurrence = id(base + offset);
let Some(SharedBody::Occurrence {
body: OccurrenceBody::Exchange { values, .. },
..
}) = p.elements[&occurrence].shared()
else {
panic!("Expected an exchange occurrence")
};
assert_eq!(values.len(), 1);
assert_eq!(values[0].expression, expression);
if base == 2000 {
let operations::OperationResolution::Selected(proof) =
operations::resolve(&p, occurrence).unwrap()
else {
panic!("SA pressure operation must remain actually bound")
};
assert_eq!(proof.invocation, id(base + call));
assert_eq!(proof.allocation, id(220));
assert_eq!(proof.caller_port, id(202));
assert_eq!(proof.provider_port, id(203));
} else {
assert_eq!(
operations::resolve(&p, occurrence).unwrap(),
operations::OperationResolution::Ordinary
);
}
}
}
let Some(SharedBody::Occurrence {
body:
OccurrenceBody::Exchange {
sender,
receiver,
reply_to,
..
},
..
}) = p.elements[&id(5050)].shared()
else {
panic!("Expected incomplete reply")
};
assert_eq!(
(*sender, *receiver, *reply_to),
(None, Some(id(5001)), Some(id(5040)))
);
for issue in &issues {
println!(
"{:?} {} {:?}: {}",
issue.severity, issue.code, issue.element, issue.message
);
}
println!(
"PASS: six scenarios,61 elements,5 relations,zero Errors,{} warnings; exact source bundle and whole-Project roundtrip; bound OA values and SA operation proofs preserved",
issues.len()
);
}