use step_io::{DropKind, Report, read};
const HEADER: &str = "ISO-10303-21;\nHEADER;\n\
FILE_DESCRIPTION(('probe'),'2;1');\n\
FILE_NAME('','',(''),(''),'','','');\n\
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));\n\
ENDSEC;\nDATA;\n";
const FOOTER: &str = "ENDSEC;\nEND-ISO-10303-21;\n";
fn read_body(body: &str) -> Report {
let src = format!("{HEADER}{body}{FOOTER}");
let (_model, report) = read(src.as_bytes()).expect("source parses");
assert_eq!(
report.validated + report.dropped.len(),
report.n_in + report.n_synth,
"accounting invariant: validated + dropped == n_in + n_synth"
);
report
}
fn dropped_kind(r: &Report, id: u64) -> Option<&DropKind> {
r.dropped
.iter()
.find(|(i, _)| *i == id)
.map(|(_, d)| &d.kind)
}
#[test]
fn off_kind_scalar_drops_only_offender() {
let r =
read_body("#1=CARTESIAN_POINT('',(0.,0.,0.));\n#2=CARTESIAN_POINT('',('x','y','z'));\n");
assert_eq!(dropped_kind(&r, 2), Some(&DropKind::Unclassified));
assert!(dropped_kind(&r, 1).is_none(), "valid #1 must survive");
assert!(r.validated >= 1);
}
#[test]
fn short_arity_drops_only_offender() {
let r = read_body("#1=CARTESIAN_POINT('',(0.,0.,0.));\n#2=CARTESIAN_POINT('');\n");
assert_eq!(dropped_kind(&r, 2), Some(&DropKind::Unclassified));
assert!(dropped_kind(&r, 1).is_none());
}
#[test]
fn non_list_vec_drops_only_offender() {
let r = read_body("#1=CARTESIAN_POINT('',(0.,0.,0.));\n#2=CARTESIAN_POINT('',5.);\n");
assert_eq!(dropped_kind(&r, 2), Some(&DropKind::Unclassified));
assert!(dropped_kind(&r, 1).is_none());
}
#[test]
fn dangling_ref_cascades() {
let r = read_body("#1=CARTESIAN_POINT('',(0.,0.,0.));\n#2=VERTEX_POINT('',#999);\n");
assert_eq!(dropped_kind(&r, 2), Some(&DropKind::Cascade));
assert!(dropped_kind(&r, 1).is_none());
}
#[test]
fn wrong_type_ref_drops_only_offender() {
let r = read_body("#1=DIRECTION('',(1.,0.,0.));\n#2=VERTEX_POINT('',#1);\n");
let k = dropped_kind(&r, 2);
assert!(
matches!(
k,
Some(DropKind::NonstandardReference | DropKind::Unclassified)
),
"wrong-type ref dropped, got {k:?}"
);
assert!(
dropped_kind(&r, 1).is_none(),
"valid DIRECTION #1 must survive"
);
}
#[test]
fn valid_body_keeps_all() {
let r = read_body("#1=CARTESIAN_POINT('',(0.,0.,0.));\n#2=DIRECTION('',(1.,0.,0.));\n");
assert_eq!(r.dropped.len(), 0);
assert_eq!(r.validated, 2);
}