//! Isolated reader probe for root's build lease; no production dependencies added. //! Usage: probe.exe INPUT.arcadia OUTPUT_DIRECTORY use oa_core::{language, source_project::*, *}; use std::{collections::BTreeMap, path::PathBuf}; fn compile(bundle: &SourceBundle) -> CompiledSourceProject { compile_bundle(bundle, ProjectLimits::default()).unwrap_or_else(|issues| { panic!("source admission failed: {issues:#?}") }) } fn identity(project: &Project, alias: &str) -> Id { project.identities().into_iter().find(|(_, name)| *name == alias).unwrap().0 } fn main() { let arguments: Vec<_> = std::env::args_os().collect(); assert_eq!(arguments.len(), 3, "expected input and isolated output directory"); let input = std::fs::read_to_string(&arguments[1]).unwrap(); let output = PathBuf::from(&arguments[2]); std::fs::create_dir_all(&output).unwrap(); let bundle = SourceBundle { entry: "project.arcadia".into(), files: BTreeMap::from([("project.arcadia".into(), input.clone())]), }; let compiled = compile(&bundle); let project = &compiled.decoded.project; assert_eq!(project.schema_version, 7); assert_eq!(project.identities().len(), 40); assert_eq!(compile(&compiled.bundle).decoded.project, *project); assert_eq!(compile(&compiled.bundle).bundle, compiled.bundle); assert_ne!(compile(&bundle).decoded.project.id, project.id); let stable = &compiled.bundle.files["project.arcadia"]; let canonical = language::format(project); assert_eq!(language::parse(&canonical).unwrap(), *project); assert_eq!(language::format(&language::parse(&canonical).unwrap()), canonical); assert_eq!(stable.matches(" id \"").count(), 40); assert!(stable.contains("// Assessing the alarm is work decomposition")); let assess = identity(project, "assess_alarm"); let mut header_only = compiled.bundle.clone(); header_only.files.get_mut("project.arcadia").unwrap().replace_range( stable.find("oa_activity assess_alarm ").unwrap() ..stable.find("oa_activity assess_alarm ").unwrap() + "oa_activity assess_alarm ".len(), "oa_activity review_alarm ", ); assert!(compile_bundle(&header_only, ProjectLimits::default()).is_err()); let alias_plan = prepare_command(project, &Command::SetAlias(assess, "review_alarm".into())).unwrap(); let aliased = update_bundle_with_identity_map( &compiled, &alias_plan.project, &alias_plan.identity_map, ProjectLimits::default(), ).unwrap(); assert_eq!(identity(&aliased.decoded.project, "review_alarm"), assess); assert!(!aliased.bundle.files["project.arcadia"].contains("@assess_alarm")); assert!(aliased.bundle.files["project.arcadia"].contains("// Assessing the alarm is work decomposition")); let moved_plan = prepare_command(project, &Command::Reparent { element: assess, parent: None }).unwrap(); let moved = update_bundle_with_identity_map( &compiled, &moved_plan.project, &moved_plan.identity_map, ProjectLimits::default(), ).unwrap(); assert_eq!(moved.decoded.project.elements[&assess].parent, None); assert!(moved.bundle.files["project.arcadia"].contains("// Assessing the alarm is work decomposition")); let actor = identity(project, "plant_operator"); let location = &compiled.index.declarations[&actor]; let actor_text = &stable[location.span.start..location.span.end]; let mut split_entry = stable.replacen(actor_text, "", 1); let closing = split_entry.rfind('}').unwrap(); split_entry.insert_str(closing, " include \"participants.arcadia\";\n"); let split = SourceBundle { entry: "project.arcadia".into(), files: BTreeMap::from([ ("project.arcadia".into(), split_entry), ("participants.arcadia".into(), format!("{actor_text}\n")), ]), }; assert_eq!(compile(&split).decoded.project, *project); let mut missing_viewpoint = compiled.bundle.clone(); missing_viewpoint.files.insert("project.arcadia".into(), stable.replace("viewpoint OperationalActivity;", "")); let implicit = compile(&missing_viewpoint); let scenario = identity(project, "notification"); assert!(matches!(implicit.decoded.project.elements[&scenario].body.shared(), Some(SharedBody::Scenario { viewpoint: ScenarioViewpoint::MixedLegacy, .. }))); let mut reduced_message = compiled.bundle.clone(); reduced_message.files.insert("project.arcadia".into(), stable .replace("message_kind Asynchronous; reply_to none;", "") .replace("lifeline none;", "")); assert_eq!(compile(&reduced_message).decoded.project, *project); std::fs::write(output.join("stabilized.arcadia"), stable).unwrap(); std::fs::write(output.join("canonical.arcadia"), &canonical).unwrap(); std::fs::write(output.join("renamed.arcadia"), &aliased.bundle.files["project.arcadia"]).unwrap(); std::fs::write(output.join("reparented.arcadia"), &moved.bundle.files["project.arcadia"]).unwrap(); std::fs::write(output.join("split-entry.arcadia"), &split.files["project.arcadia"]).unwrap(); std::fs::write(output.join("participants.arcadia"), &split.files["participants.arcadia"]).unwrap(); println!("PASS: admission; stable and canonical round-trip; fresh/stable identity; raw alias rejection; command alias rewrite; nested reparent; cross-file move; source7 default probes"); println!("objects={} elements={} relations={} diagrams={} artifacts={} traces={}", project.identities().len(), project.elements.len(), project.relations.len(), project.diagrams.len(), project.artifact_links.len(), project.traces.len()); println!("authored_bytes={} stable_bytes={} canonical_bytes={} authored_lines={} stable_lines={} canonical_lines={}", input.len(), stable.len(), canonical.len(), input.lines().count(), stable.lines().count(), canonical.lines().count()); println!("warnings={:#?}", compiled.diagnostics); }