Strengthen mixed Project public-wrapper and storage oracles
This commit is contained in:
@@ -578,6 +578,35 @@ fn complete_static_architecture_and_unicode_warning_mapping() {
|
||||
let warning = &resolved.warnings()[0].diagnostic;
|
||||
assert_eq!(warning.line, 6);
|
||||
assert_eq!(warning.column, 1);
|
||||
// Same physical line: the two header-name scalars occupy seven UTF-8
|
||||
// bytes. Independently authored coordinates distinguish column60 from
|
||||
// byte-column65; the warning covers the complete Work declaration.
|
||||
let inline = SourceBundle {
|
||||
entry: "main.arcadia".into(),
|
||||
files: BTreeMap::from([(
|
||||
"main.arcadia".into(),
|
||||
format!(
|
||||
"arcadia 8;\r\nproject p \"港🌊\" id \"{}\" {{ oa_activity w \"Work\" id \"{}\" {{}} }}\r\n",
|
||||
id(1),
|
||||
id(2)
|
||||
),
|
||||
)]),
|
||||
};
|
||||
let inline_value = accepted(&inline);
|
||||
assert_eq!(inline_value.warnings().len(), 1);
|
||||
let inline_warning = &inline_value.warnings()[0];
|
||||
assert_eq!(inline_warning.path, "main.arcadia");
|
||||
assert_eq!(inline_warning.diagnostic.code, "unallocated_leaf");
|
||||
assert_eq!(inline_warning.diagnostic.object_id, Some(id(2)));
|
||||
assert_eq!(inline_warning.diagnostic.line, 2);
|
||||
assert_eq!(inline_warning.diagnostic.column, 60);
|
||||
assert_eq!(
|
||||
inline_warning.diagnostic.span,
|
||||
Span {
|
||||
start: 76,
|
||||
end: 141
|
||||
}
|
||||
);
|
||||
let mut bad = bundle.clone();
|
||||
*bad.files.get_mut("main.arcadia").unwrap() =
|
||||
bad.files["main.arcadia"].replace("base 1;", "base true + 1;");
|
||||
@@ -646,19 +675,32 @@ fn mapped_warning_path_copies_are_admitted_before_retention() {
|
||||
assert_eq!(roomy.warnings().len(), 1);
|
||||
assert_eq!(roomy.warnings()[0].diagnostic.code, "unnamed");
|
||||
assert_eq!(roomy.warnings()[0].path, bundle.entry);
|
||||
let profile = super::super::super::budget::Limits {
|
||||
bytes: source.len(),
|
||||
..super::super::super::budget::Limits::source8(language::ParseLimits::UNLIMITED)
|
||||
};
|
||||
let parsed = parse_with_profile(&bundle, ProjectLimits::default(), profile).unwrap();
|
||||
let failure = match resolve(parsed) {
|
||||
Ok(_) => panic!("truncated warnings or uncharged copied path"),
|
||||
Err(e) => e,
|
||||
};
|
||||
assert_eq!(
|
||||
failure.diagnostics[0].diagnostic.message,
|
||||
"Source8 index/output byte limit exceeded."
|
||||
);
|
||||
// Retained syntax owns alias "p" (1 byte). The mapped warning owns path188
|
||||
// + code "unnamed"7 + field "name"4 + message36 =235 additional bytes.
|
||||
// A per-producer cap would accept235; their simultaneous live total is236.
|
||||
assert_eq!(bundle.entry.len(), 188);
|
||||
assert_eq!("Give the project a descriptive name.".len(), 36);
|
||||
for (bytes, fits) in [(source.len(), false), (235, false), (236, true)] {
|
||||
let profile = super::super::super::budget::Limits {
|
||||
bytes,
|
||||
..super::super::super::budget::Limits::source8(language::ParseLimits::UNLIMITED)
|
||||
};
|
||||
let parsed = parse_with_profile(&bundle, ProjectLimits::default(), profile).unwrap();
|
||||
match resolve(parsed) {
|
||||
Ok(value) => {
|
||||
assert!(fits, "mapped diagnostics lost their live syntax overlap");
|
||||
assert_eq!(value.warnings(), roomy.warnings());
|
||||
assert_eq!(value.storage.live.text, 236);
|
||||
}
|
||||
Err(failure) => {
|
||||
assert!(!fits, "exact total must fit: {failure:?}");
|
||||
assert_eq!(
|
||||
failure.diagnostics[0].diagnostic.message,
|
||||
"Source8 index/output byte limit exceeded."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -796,20 +838,13 @@ fn retained_nested_record_policy_cannot_be_replaced_at_resolution() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_ordinary_construction_preserves_legacy_scratch_and_existing_errors() {
|
||||
fn public_source3_and_source7_preserve_legacy_scratch_defaults_and_errors() {
|
||||
let bundle = single(&format!("oa_activity w \"Work\" id \"{}\" {{}}", id(2)));
|
||||
let parsed = parse(&bundle, ProjectLimits::default()).unwrap();
|
||||
let file = &parsed.files[0];
|
||||
let mut old = file.ordinary.header.as_ref().unwrap().project.clone();
|
||||
old.schema_version = 3;
|
||||
let aliases = BTreeMap::from([("p".into(), id(1)), ("w".into(), id(2))]);
|
||||
let migrated = language::resolve_declarations(
|
||||
old,
|
||||
&file.ordinary.declarations,
|
||||
&aliases,
|
||||
language::ParseLimits::UNLIMITED,
|
||||
)
|
||||
.unwrap();
|
||||
// Existing source3_bridge tests compare complete public source3/JSON3
|
||||
// migration. This small shared-decoder regression uses that public wrapper
|
||||
// too, retaining the independent exact Activity expectation below.
|
||||
let old_source = bundle.files["main.arcadia"].replacen("arcadia 8;", "arcadia 3;", 1);
|
||||
let migrated = language::parse_with_report(&old_source).unwrap();
|
||||
assert_eq!(migrated.project.schema_version, SCHEMA_VERSION);
|
||||
assert_eq!(
|
||||
migrated.project.elements[&id(2)],
|
||||
@@ -823,9 +858,11 @@ fn shared_ordinary_construction_preserves_legacy_scratch_and_existing_errors() {
|
||||
}
|
||||
);
|
||||
let scenario = single(&format!("oa_scenario q \"Scenario\" id \"{}\" {{}}", id(2)));
|
||||
let value = accepted(&scenario);
|
||||
let scenario_source = scenario.files["main.arcadia"].replacen("arcadia 8;", "arcadia 7;", 1);
|
||||
let value =
|
||||
language::parse_limited(&scenario_source, language::ParseLimits::UNLIMITED).unwrap();
|
||||
assert!(
|
||||
matches!(value.project.elements[&id(2)].shared(), Some(SharedBody::Scenario { viewpoint: ScenarioViewpoint::MixedLegacy, steps, .. }) if steps.is_empty())
|
||||
matches!(value.elements[&id(2)].shared(), Some(SharedBody::Scenario { viewpoint: ScenarioViewpoint::MixedLegacy, steps, .. }) if steps.is_empty())
|
||||
);
|
||||
let missing = single(&format!(
|
||||
"node n id \"{}\" {{ diagram @d; }} diagram d \"D\" id \"{}\" {{}}",
|
||||
@@ -833,7 +870,9 @@ fn shared_ordinary_construction_preserves_legacy_scratch_and_existing_errors() {
|
||||
id(3)
|
||||
));
|
||||
assert_eq!(
|
||||
rejected(&missing).diagnostics[0].diagnostic.message,
|
||||
language::parse(&missing.files["main.arcadia"].replacen("arcadia 8;", "arcadia 7;", 1))
|
||||
.unwrap_err()[0]
|
||||
.message,
|
||||
"Missing required field 'element'."
|
||||
);
|
||||
let conflict = single(&format!(
|
||||
@@ -842,7 +881,9 @@ fn shared_ordinary_construction_preserves_legacy_scratch_and_existing_errors() {
|
||||
id(3)
|
||||
));
|
||||
assert_eq!(
|
||||
rejected(&conflict).diagnostics[0].diagnostic.code,
|
||||
language::parse(&conflict.files["main.arcadia"].replacen("arcadia 8;", "arcadia 7;", 1))
|
||||
.unwrap_err()[0]
|
||||
.code,
|
||||
"conflicting_parent"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user