From 10d7f3340d5cd61a656dc0bcf7c143f8897c5551 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Wed, 23 Sep 2026 00:18:21 -0700 Subject: [PATCH] test(core): preserve standalone no-op budget boundary --- .../language/analysis_source/update/tests.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/crates/oa-core/src/language/analysis_source/update/tests.rs b/crates/oa-core/src/language/analysis_source/update/tests.rs index 2a956897..fdb866ff 100644 --- a/crates/oa-core/src/language/analysis_source/update/tests.rs +++ b/crates/oa-core/src/language/analysis_source/update/tests.rs @@ -709,3 +709,36 @@ fn composition_checks_edit_record_ceiling_before_duplicate_membership() { "Source8 lowering occurrence limit exceeded." ); } + +#[test] +fn standalone_noop_apply_keeps_tighter_file_only_budget_and_output_boundary() { + let sources = sources(); + let mut inherited = budget(); + let (index, _) = Index::parse(&skeleton(), &sources, &mut inherited).unwrap(); + let plan = Plan::renames( + &index, + &BTreeMap::from([(global(0x100), "f".into())]), + &inherited, + ) + .unwrap(); + assert_eq!(plan.edit_count(), 0); + assert!(index.names().len() > sources.len()); + let mut limits = Limits::source8(ParseLimits::UNLIMITED); + limits.entries = sources.len(); + limits.references = 0; + limits.bytes = sources.values().map(String::len).sum(); + // Standalone apply checks file/edit records, not the already validated + // catalog/name-storage allocation from construction. Rechecking the catalog + // under this intentionally tighter probe budget would reject this no-op. + assert_eq!( + plan.apply(&sources, &Budget::new(limits).unwrap()).unwrap(), + sources + ); + limits.bytes -= 1; + assert_eq!( + plan.apply(&sources, &Budget::new(limits).unwrap()) + .unwrap_err() + .message, + "Source8 index/output byte limit exceeded." + ); +}