121 lines
5.3 KiB
Rust
121 lines
5.3 KiB
Rust
//! Standalone actual-core falsifier. Not compiled or executed by its author.
|
|
//! Root must select a matching oa_core rlib and serialize compilation with gates.
|
|
use oa_core::{projection::*, validation, *};
|
|
|
|
fn pos(x: f32, y: f32) -> Position { Position { x, y } }
|
|
fn size(width: f32, height: f32) -> Size { Size { width, height } }
|
|
|
|
fn valid(label: &str, p: &Project) {
|
|
let issues = validation::validate(p);
|
|
for issue in &issues { println!("{label}: {issue:?}"); }
|
|
assert!(!issues.iter().any(|i| i.severity == validation::Severity::Error),
|
|
"Fixture/candidate must be model-valid: {label}");
|
|
}
|
|
|
|
fn standard(p: &mut Project, owner: Id, name: &str) -> Id {
|
|
let id = Id::new_v4();
|
|
let port = make_port(p, id, owner, name, PortContract::Component {
|
|
kind: ComponentPortKind::Standard,
|
|
orientation: ComponentPortOrientation::Unset,
|
|
}).unwrap();
|
|
p.elements.insert(id, port);
|
|
id
|
|
}
|
|
|
|
fn fixture(manual: bool) -> (Project, Id, Id) {
|
|
let mut p = Project::empty();
|
|
let a = p.add_element(Kind::System, Layer::Sa, "Owner", None).unwrap();
|
|
let b = p.add_element(Kind::SystemActor, Layer::Sa, "Above", None).unwrap();
|
|
let c = p.add_element(Kind::SystemActor, Layer::Sa, "Below", None).unwrap();
|
|
let pb = standard(&mut p, b, "Above interface");
|
|
let pc = standard(&mut p, c, "Below interface");
|
|
let mut ports = Vec::new();
|
|
for i in 0..8 {
|
|
let pa = standard(&mut p, a, &format!("Owner interface {i}"));
|
|
p.relate(RelationKind::BoundaryExchange, &format!("Above exchange {i}"), pa, pb);
|
|
p.relate(RelationKind::BoundaryExchange, &format!("Below exchange {i}"), pa, pc);
|
|
ports.push(pa);
|
|
}
|
|
let d = p.ensure_diagram(Layer::Sa);
|
|
let na = p.place(d, a, pos(0., 0.));
|
|
// Normal-sized separated peers have centers (130,-930) and (130,1070).
|
|
// Each Owner port sees the same average peer center (130,70).
|
|
let nb = p.place(d, b, pos(38., -996.));
|
|
let nc = p.place(d, c, pos(38., 1004.));
|
|
let diagram = p.diagrams.get_mut(&d).unwrap();
|
|
diagram.nodes.get_mut(&na).unwrap().size = size(224., 160.);
|
|
for n in [nb, nc] { diagram.nodes.get_mut(&n).unwrap().size = size(184., 132.); }
|
|
if manual {
|
|
diagram.nodes.get_mut(&na).unwrap().port_anchors = ports.into_iter()
|
|
.enumerate().map(|(i, port)| PortAnchor {
|
|
port, side: PortAnchorSide::Right, offset: (i + 1) as f32 / 9.,
|
|
}).collect();
|
|
}
|
|
valid("baseline", &p);
|
|
(p, d, na)
|
|
}
|
|
|
|
fn projected(p: &Project, d: Id, n: Id) -> ProjectedNode {
|
|
project_diagram(p, &p.diagrams[&d]).nodes.into_iter().find(|v| v.id == n).unwrap()
|
|
}
|
|
|
|
fn edit(p: &Project, d: Id, n: Id, dimensions: Size) -> Project {
|
|
let mut node = p.diagrams[&d].nodes[&n].clone();
|
|
node.size = dimensions;
|
|
let next = prepare_command(p, &Command::EditNode { diagram: d, original: n, node }).unwrap().project;
|
|
valid("candidate", &next);
|
|
next
|
|
}
|
|
|
|
fn normalization_falsifier(manual: bool) {
|
|
let (p, d, n) = fixture(manual);
|
|
let baseline = projected(&p, d, n);
|
|
println!("manual={manual}, baseline {baseline:?}");
|
|
assert_eq!(baseline.position, pos(0., 0.));
|
|
assert_eq!(baseline.size, size(224., 232.));
|
|
let normalized = edit(&p, d, n, baseline.size);
|
|
let normalized_view = projected(&normalized, d, n);
|
|
println!("normalized {normalized_view:?}");
|
|
assert_eq!(normalized_view.size, size(232., 232.), "Visible-size normalization changes projection");
|
|
|
|
// Same East edge target x214, same fixed x0/y0/bottom232.
|
|
// Preserve the authored inactive dimension versus normalize it.
|
|
let minimal = edit(&p, d, n, size(214., 160.));
|
|
let minimal_view = projected(&minimal, d, n);
|
|
let normalized_shrink = edit(&p, d, n, size(214., 232.));
|
|
let normalized_shrink_view = projected(&normalized_shrink, d, n);
|
|
println!("minimal shrink {minimal_view:?}");
|
|
println!("normalized shrink {normalized_shrink_view:?}");
|
|
assert_eq!(minimal_view.size, size(214., 232.));
|
|
assert_eq!(normalized_shrink_view.size, size(232., 232.));
|
|
assert_eq!(minimal_view.position, baseline.position);
|
|
let mut restored = minimal.clone();
|
|
restored.diagrams.get_mut(&d).unwrap().nodes.insert(n, p.diagrams[&d].nodes[&n].clone());
|
|
assert_eq!(restored, p, "Only selected placement changed");
|
|
for view in [project_diagram(&p, &p.diagrams[&d]), project_diagram(&minimal, &minimal.diagrams[&d])] {
|
|
for port in view.ports.iter().filter(|v| v.owner == n) {
|
|
assert_eq!(port.side, PortAnchorSide::Right);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn grandfather_floor_falsifier() {
|
|
let mut p = Project::empty();
|
|
let a = p.add_element(Kind::Entity, Layer::Oa, "Small valid card", None).unwrap();
|
|
let d = p.ensure_diagram(Layer::Oa);
|
|
let n = p.place(d, a, pos(0., 0.));
|
|
p.diagrams.get_mut(&d).unwrap().nodes.get_mut(&n).unwrap().size = size(100., 50.);
|
|
valid("small baseline", &p);
|
|
assert_eq!(projected(&p, d, n).size, size(100., 50.));
|
|
let grown = edit(&p, d, n, size(110., 50.));
|
|
assert_eq!(projected(&grown, d, n).size, size(110., 50.));
|
|
println!("Valid E enlargement 100x50 -> 110x50 exists; global 184x94 pointer floor plus fixed inactive height rejects it.");
|
|
}
|
|
|
|
fn main() {
|
|
normalization_falsifier(false);
|
|
normalization_falsifier(true);
|
|
grandfather_floor_falsifier();
|
|
println!("PASS: actual-core normalization and minimum-policy falsifiers");
|
|
}
|