Migrate schema 2 ports through frozen readers and expose schema 3 source API
Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-09-05 18:23:33 +03:00
parent 0d14438b7b
commit b9f88ce1f3
21 changed files with 7513 additions and 152 deletions
+72 -3
View File
@@ -252,6 +252,63 @@ project mission "Harbor safety — 港 🌊" {
.unwrap()
.push(id);
}
let owner = p
.elements
.values()
.find(|e| e.alias == "safety_system")
.unwrap()
.id;
let function = p
.elements
.values()
.find(|e| e.alias == "detect")
.unwrap()
.id;
let component_port = Id::new_v4();
let function_port = Id::new_v4();
for (id, alias, parent, contract) in [
(
component_port,
"typed_component_port",
owner,
PortContract::Component {
kind: ComponentPortKind::Standard,
orientation: ComponentPortOrientation::Unset,
},
),
(
function_port,
"typed_function_output",
function,
PortContract::FunctionOutput {
outgoing_items: vec![],
},
),
] {
p.elements.insert(
id,
Element {
id,
alias: alias.into(),
name: alias.into(),
description: String::new(),
parent: Some(parent),
body: ElementBody::shared_in(
Layer::Sa,
SharedBody::Port {
contract,
legacy: None,
},
),
},
);
}
p.relate(
RelationKind::PortAllocation,
"Typed port allocation",
component_port,
function_port,
);
p
}
@@ -404,7 +461,7 @@ fn authoring_defaults_and_forward_references_remain_strict() {
#[test]
fn typed_unknown_fields_enums_duplicates_and_reference_spelling_are_rejected() {
for (source, expected) in [
("arcadia 3; project mission \"x\" {}", "Unsupported schema"),
("arcadia 4; project mission \"x\" {}", "Unsupported schema"),
(
"arcadia 2; project mission \"x\" { oa_activity a \"A\" { nonsense 1; } }",
"Unknown field",
@@ -708,6 +765,8 @@ fn original_v2_text_and_json_preserve_identity_and_mixed_scenarios_after_extensi
assert_eq!(from_source, from_json);
let original: serde_json::Value = serde_json::from_slice(old_json).unwrap();
let mut retained = serde_json::to_value(&from_json).unwrap();
assert_eq!(retained["schema_version"], 3);
retained["schema_version"] = 2.into();
for element in retained["elements"].as_object_mut().unwrap().values_mut() {
for layer in ["Oa", "Sa"] {
let Some(shared) = element["body"]
@@ -716,6 +775,10 @@ fn original_v2_text_and_json_preserve_identity_and_mixed_scenarios_after_extensi
else {
continue;
};
if let Some(port) = shared.get_mut("Port") {
assert_eq!(port["contract"], "Legacy");
*port = port["legacy"].clone();
}
if let Some(scenario) = shared
.get_mut("Scenario")
.and_then(serde_json::Value::as_object_mut)
@@ -735,6 +798,10 @@ fn original_v2_text_and_json_preserve_identity_and_mixed_scenarios_after_extensi
}
}
for relation in retained["relations"].as_object_mut().unwrap().values_mut() {
if let Some(boundary) = relation["body"].get_mut("BoundaryExchange") {
assert_eq!(boundary["oriented"], true);
boundary.as_object_mut().unwrap().remove("oriented");
}
if let Some(transition) = relation["body"]
.get_mut("StateTransition")
.and_then(serde_json::Value::as_object_mut)
@@ -828,7 +895,7 @@ fn v1_text_and_json_migrate_deterministically_without_losing_legacy_semantics()
assert_eq!(from_text, from_json);
assert_eq!(read(text), from_text);
assert_eq!(persistence::decode(json).unwrap(), from_json);
assert_eq!(from_text.schema_version, 2);
assert_eq!(from_text.schema_version, 3);
assert!(!from_text.elements.values().any(|e| e.layer() == Layer::Sa));
let raw: serde_json::Value = serde_json::from_slice(json).unwrap();
for (id, record) in raw["elements"].as_object().unwrap() {
@@ -1027,7 +1094,9 @@ fn complete_normative_examples_are_accepted_by_the_real_parser() {
break;
}
}
if code.trim_start().starts_with("arcadia 2;") {
if code.trim_start().starts_with("arcadia 2;")
|| code.trim_start().starts_with("arcadia 3;")
{
read(&code);
examples += 1;
}