Migrate frozen data contracts and authored source to schema 4

This commit is contained in:
2026-09-06 03:39:02 +03:00
parent c5276b1943
commit 1230ab8a3e
21 changed files with 2006 additions and 126 deletions
+35 -33
View File
@@ -30,7 +30,7 @@ fn id(project: &Project, alias: &str) -> Id {
#[test]
fn route_edits_keep_diagram_file_ownership_and_comments_with_edge_identity() {
let input = bundle(
"arcadia 3; project p \"Routing\" { include \"views.arcadia\"; include \"work.arcadia\"; }",
"arcadia 4; project p \"Routing\" { include \"views.arcadia\"; include \"work.arcadia\"; }",
&[
(
"work.arcadia",
@@ -95,7 +95,7 @@ diagram review "Review" {
#[test]
fn invalid_cross_file_route_references_and_geometry_locate_the_authored_view() {
let mut input = bundle(
"arcadia 3; project p \"Routing\" { include \"views.arcadia\"; include \"work.arcadia\"; }",
"arcadia 4; project p \"Routing\" { include \"views.arcadia\"; include \"work.arcadia\"; }",
&[
(
"work.arcadia",
@@ -127,7 +127,7 @@ fn invalid_cross_file_route_references_and_geometry_locate_the_authored_view() {
fn typed() -> SourceBundle {
bundle(
"arcadia 3; project test_model \"航海\" {\n include \"exchanges.arcadia\";\n include \"work/send.arcadia\";\n include \"work/receive.arcadia\";\n include \"types.arcadia\";\n}",
"arcadia 4; project test_model \"航海\" {\n include \"exchanges.arcadia\";\n include \"work/send.arcadia\";\n include \"work/receive.arcadia\";\n include \"types.arcadia\";\n}",
&[
(
"exchanges.arcadia",
@@ -194,7 +194,7 @@ fn cross_file_typed_ports_global_forward_references_and_stable_ids() {
#[test]
fn advisory_lint_locations_refer_to_raw_drafts_before_identity_stabilization() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"work.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"work.arcadia\"; }",
&[(
"work.arcadia",
"sa_function first \"First\" {}\nsa_function second \"Second\" {}\n",
@@ -228,7 +228,7 @@ fn advisory_lint_locations_refer_to_raw_drafts_before_identity_stabilization() {
#[test]
fn source_errors_keep_exact_fragment_unicode_positions() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"child.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"child.arcadia\"; }",
&[(
"child.arcadia",
"// Пример\nsa_function child \"航海\" { parent @missing; }",
@@ -274,7 +274,7 @@ fn duplicate_alias_and_identity_report_both_files_including_project_identity() {
),
] {
let input = bundle(
"arcadia 3; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
&[("a.arcadia", left), ("b.arcadia", right)],
);
let error = compile_bundle(&input, ProjectLimits::default())
@@ -285,7 +285,7 @@ fn duplicate_alias_and_identity_report_both_files_including_project_identity() {
assert_eq!(error.related[0].path, "a.arcadia");
}
let input = bundle(
"arcadia 3; project p \"P\" { include \"child.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"child.arcadia\"; }",
&[("child.arcadia", "oa_activity p \"Collision\" {}")],
);
let error = compile_bundle(&input, ProjectLimits::default())
@@ -297,7 +297,7 @@ fn duplicate_alias_and_identity_report_both_files_including_project_identity() {
#[test]
fn includes_are_once_only_and_cycles_missing_and_unreachable_files_are_located() {
let mut input = bundle(
"arcadia 3; project p \"P\" { include \"sub/a.arcadia\"; include \"sub/b.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"sub/a.arcadia\"; include \"sub/b.arcadia\"; }",
&[
("sub/a.arcadia", "include \"../shared.arcadia\";"),
("sub/b.arcadia", "include \"../shared.arcadia\";"),
@@ -356,7 +356,7 @@ fn portable_paths_reject_escapes_devices_urls_and_case_collisions() {
);
assert!(resolve_include("../bad.arcadia", "a.arcadia").is_err());
let input = bundle(
"arcadia 3; project p \"P\" {}",
"arcadia 4; project p \"P\" {}",
&[("A.arcadia", ""), ("a.arcadia", "")],
);
assert_eq!(
@@ -370,7 +370,7 @@ fn portable_paths_reject_escapes_devices_urls_and_case_collisions() {
#[test]
fn project_admission_is_aggregate_and_precedes_global_resolution() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
&[
("a.arcadia", "oa_activity one \"One\" { parent @missing; }"),
("b.arcadia", "oa_activity two \"Two\" {}"),
@@ -591,7 +591,7 @@ fn failed_update_preserves_candidate_and_rejects_stale_index() {
#[test]
fn single_string_and_legacy_apis_remain_explicit_and_filesystem_free() {
let source = "arcadia 3; project p \"P\" { include \"missing.arcadia\"; }";
let source = "arcadia 4; project p \"P\" { include \"missing.arcadia\"; }";
assert!(
language::parse(source).unwrap_err()[0]
.message
@@ -681,7 +681,7 @@ fn json_bundle_rejects_duplicate_file_keys_and_unknown_fields() {
#[test]
fn generated_id_insertion_handles_adjacent_header_tokens_and_remains_exactly_indexed() {
let input = bundle(
"arcadia 3;project p\"P\"{include \"child.arcadia\";}",
"arcadia 4;project p\"P\"{include \"child.arcadia\";}",
&[(
"child.arcadia",
"oa_activity a\"A\"{}diagram d\"D\"{}node n{diagram @d;element @a;}",
@@ -703,7 +703,7 @@ fn generated_id_insertion_handles_adjacent_header_tokens_and_remains_exactly_ind
#[test]
fn duplicate_include_edges_count_toward_admission_and_ordered_references_are_aggregate() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"a.arcadia\"; include \"a.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"a.arcadia\"; include \"a.arcadia\"; }",
&[("a.arcadia", "")],
);
assert_eq!(
@@ -720,7 +720,7 @@ fn duplicate_include_edges_count_toward_admission_and_ordered_references_are_agg
"project_limit"
);
let input = bundle(
"arcadia 3; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"a.arcadia\"; include \"b.arcadia\"; }",
&[
(
"a.arcadia",
@@ -763,7 +763,7 @@ fn include_inspection_reuses_strict_entry_fragment_syntax_and_real_spans() {
&source[span.start..span.end],
"include \"../shared.arcadia\";"
);
let entry = "arcadia 3; project p \"P\" { include \"sub/work.arcadia\"; }";
let entry = "arcadia 4; project p \"P\" { include \"sub/work.arcadia\"; }";
assert_eq!(
inspect_includes("project.arcadia", entry, true, ProjectLimits::default()).unwrap()[0]
.target,
@@ -829,7 +829,7 @@ fn comments(source: &str) -> Vec<String> {
#[test]
fn scalar_header_guard_and_project_edits_preserve_exact_crlf_trivia_and_escape_spelling() {
let entry = "arcadia 3;\r\nproject p // project title\r\n \"Original project\" {\r\n description // project reason\r\n \"Before\";\r\n include \"behavior.arcadia\";\r\n}\r\n";
let entry = "arcadia 4;\r\nproject p // project title\r\n \"Original project\" {\r\n description // project reason\r\n \"Before\";\r\n include \"behavior.arcadia\";\r\n}\r\n";
let source = "oa_state_machine machine \"Machine\" {}\r\noa_region region_one \"Region\" { parent @machine; }\r\noa_state first \"First\" { parent @region_one; }\r\noa_state second \"Second\" { parent @region_one; }\r\nstate_transition route // route title\r\n \"Original transition\" {\r\n\tguard // feasibility\r\n\t \"old guard\"; // retain explanation\r\n\tdescription \"Keep\\u0020spelling\";\r\n\tsource @ // endpoint proof\r\n first; target @second;\r\n}\r\n";
let current = compile(&bundle(entry, &[("behavior.arcadia", source)]));
let mut project = current.decoded.project.clone();
@@ -864,7 +864,7 @@ fn scalar_header_guard_and_project_edits_preserve_exact_crlf_trivia_and_escape_s
#[test]
fn alias_updates_touch_only_header_and_reference_tokens_even_with_comments_after_at() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"work.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"work.arcadia\"; }",
&[(
"work.arcadia",
"oa_activity root_work // root rationale\n \"Root\\u0020name\" { description \"root_work is prose\"; }\noa_activity child \"Child\" { parent @ // parent proof\n root_work; }\n",
@@ -887,7 +887,7 @@ fn alias_updates_touch_only_header_and_reference_tokens_even_with_comments_after
#[test]
fn omitted_defaults_stay_omitted_and_new_fields_do_not_reformat_surviving_fields() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"work.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"work.arcadia\"; }",
&[(
"work.arcadia",
"oa_activity work \"Work\" {\r\n\t// owner rationale\r\n\tparent none ; // preserve spacing\r\n}\r\n",
@@ -913,7 +913,7 @@ fn omitted_defaults_stay_omitted_and_new_fields_do_not_reformat_surviving_fields
#[test]
fn kind_change_removes_field_syntax_but_keeps_its_comments_and_other_fields() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"item.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"item.arcadia\"; }",
&[(
"item.arcadia",
"oa_exchange_item item \"Item\" {\n description \"Keep\\u0020this\" ; // description note\n kind // classification rationale\n Information ;\n parent none;\n}\n",
@@ -953,7 +953,7 @@ fn significant_words(source: &str) -> Vec<String> {
#[test]
fn constructor_tag_changes_retain_shared_nested_fields_and_removed_field_comments() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"event.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"event.arcadia\"; }",
&[(
"event.arcadia",
"oa_event timer \"Timer\" { body { Time // time rationale\n { expression // expression rationale\n \"before\" ; kind After; // clock rationale\n }; }; }\n",
@@ -986,7 +986,7 @@ fn constructor_tag_changes_retain_shared_nested_fields_and_removed_field_comment
#[test]
fn scalar_record_constructor_changes_keep_comments_inside_removed_values() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"ports.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"ports.arcadia\"; }",
&[(
"ports.arcadia",
"sa_function work \"Work\" {}\nsa_port input \"Input\" { parent @work; contract Legacy; // contract rationale\n legacy { direction In; // direction rationale\n interface none; // interface rationale\n }; }\n",
@@ -1017,10 +1017,10 @@ fn scalar_record_constructor_changes_keep_comments_inside_removed_values() {
#[test]
fn reference_list_reordering_carries_item_comments_and_alias_spelling_with_identity() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"types.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"types.arcadia\"; }",
&[(
"types.arcadia",
"sa_exchange_item a \"A\" {} sa_exchange_item b \"B\" {}\nsa_interface service \"Service\" { items [\n // before A\n @ // A reference rationale\n a // after A\n ,\n // before B\n @b // after B\n ]; }\n",
"sa_exchange_item a \"A\" {} sa_exchange_item b \"B\" {}\nsa_event service \"Service\" { body { Signal { items [\n // before A\n @ // A reference rationale\n a // after A\n ,\n // before B\n @b // after B\n ]; }; }; }\n",
)],
);
let current = compile(&input);
@@ -1029,8 +1029,9 @@ fn reference_list_reordering_carries_item_comments_and_alias_spelling_with_ident
let b = id(&project, "b");
let service = id(&project, "service");
project.elements.get_mut(&a).unwrap().alias = "renamed_a".into();
if let Some(SharedBody::Interface { items }) =
project.elements.get_mut(&service).unwrap().shared_mut()
if let Some(SharedBody::Event {
body: EventBody::Signal { items },
}) = project.elements.get_mut(&service).unwrap().shared_mut()
{
*items = vec![b, a];
} else {
@@ -1051,10 +1052,10 @@ fn reference_list_reordering_carries_item_comments_and_alias_spelling_with_ident
#[test]
fn removed_list_items_and_declarations_keep_comments_as_enclosing_annotations() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"types.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"types.arcadia\"; }",
&[(
"types.arcadia",
"sa_exchange_item a \"A\" { // declaration explanation\n } sa_exchange_item b \"B\" {}\nsa_interface service \"Service\" { items [\n // explanation for removed A\n @a,\n // explanation for retained B\n @b ]; }\n",
"sa_exchange_item a \"A\" { // declaration explanation\n } sa_exchange_item b \"B\" {}\nsa_event service \"Service\" { body { Signal { items [\n // explanation for removed A\n @a,\n // explanation for retained B\n @b ]; }; }; }\n",
)],
);
let current = compile(&input);
@@ -1063,8 +1064,9 @@ fn removed_list_items_and_declarations_keep_comments_as_enclosing_annotations()
let b = id(&project, "b");
let service = id(&project, "service");
project.elements.remove(&a);
if let Some(SharedBody::Interface { items }) =
project.elements.get_mut(&service).unwrap().shared_mut()
if let Some(SharedBody::Event {
body: EventBody::Signal { items },
}) = project.elements.get_mut(&service).unwrap().shared_mut()
{
*items = vec![b];
} else {
@@ -1102,7 +1104,7 @@ oa_occurrence message "Message" { parent @conversation; body { Exchange {
}; }; }
"#;
let current = compile(&bundle(
"arcadia 3; project p \"P\" { include \"conversation.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"conversation.arcadia\"; }",
&[("conversation.arcadia", source)],
));
let mut project = current.decoded.project.clone();
@@ -1151,7 +1153,7 @@ oa_occurrence message "Message" { parent @conversation; body { Exchange {
#[test]
fn added_list_items_empty_lists_and_literal_changes_preserve_existing_annotations() {
let input = bundle(
"arcadia 3; project p \"P\" { include \"types.arcadia\"; }",
"arcadia 4; project p \"P\" { include \"types.arcadia\"; }",
&[(
"types.arcadia",
"oa_data_type values \"Values\" { definition { Enumeration { literals [ // enumeration rationale\n ]; }; }; }\n",
@@ -1160,7 +1162,7 @@ fn added_list_items_empty_lists_and_literal_changes_preserve_existing_annotation
let empty = compile(&input);
let mut project = empty.decoded.project.clone();
let values = id(&project, "values");
if let Some(SharedBody::DataType { definition }) =
if let Some(SharedBody::DataType { definition, .. }) =
project.elements.get_mut(&values).unwrap().shared_mut()
{
*definition = DataTypeDefinition::Enumeration {
@@ -1185,7 +1187,7 @@ fn added_list_items_empty_lists_and_literal_changes_preserve_existing_annotation
.replace("\"Beta\"", "\"Beta\" // beta explanation\n"),
);
let annotated = compile(&annotated);
if let Some(SharedBody::DataType { definition }) =
if let Some(SharedBody::DataType { definition, .. }) =
project.elements.get_mut(&values).unwrap().shared_mut()
{
*definition = DataTypeDefinition::Enumeration {