fix(properties): scope asym-scale opt-out per tab

props_asym_scale was app-global keyed by raw handle values, but fresh documents restart numbering at seed 1, leaking one tab's unchecked Uniform box into another tab reusing the value. The set moves to DocumentTab; all uses tab-scoped. Also removes a dead destructure left in overlay.rs. Test: asym_scale_opt_out_does_not_leak_across_tabs with handle-reuse premise assert (RED first). Full suite: 2025 passed / 0 failed / 25 ignored, zero warnings.
This commit is contained in:
Karim Jerbi committed 2026-10-10 16:14:22 +01:00
1 parent 6ad3183b3d
commit d1da26feb6
5 files changed
+50 -10

No files matched your search

+40 -1
View File
@@ -463,7 +463,7 @@ impl OpenCADStudio {
if let codec::EntityType::Insert(ins) = entity {
let eq = (ins.x_scale() - ins.y_scale()).abs() < 1e-12
&& (ins.x_scale() - ins.z_scale()).abs() < 1e-12;
let uniform = eq && !self.props_asym_scale.contains(&handle.value());
let uniform = eq && !self.tabs[i].props_asym_scale.contains(&handle.value());
for section in sections.iter_mut() {
let Some(xi) = section.props.iter().position(|p| p.field == "x_scale")
else {
@@ -4373,6 +4373,45 @@ fn apply_insert_unit_scale(ins: &mut codec::entities::Insert, ratio: f64) -> boo
true
}
#[cfg(test)]
mod asym_scale_tests {
// #47: the uniform-scale opt-out must be per-tab. Fresh documents restart
// handle numbering (seed 1), so two tabs hand out identical handles — an
// app-global set leaks one tab's opt-out into the other.
use crate::app::OpenCADStudio;
fn tab_with_insert(app: &mut OpenCADStudio) -> (usize, codec::Handle) {
app.tab_counter += 1;
let n = app.tab_counter;
app.tabs
.push(crate::app::document::DocumentTab::new_drawing(n));
let idx = app.tabs.len() - 1;
app.active_tab = idx;
let ins =
codec::entities::Insert::new("B", codec::types::Vector3::ZERO);
let h = app
.commit_entity_handle(codec::EntityType::Insert(ins))
.expect("insert commits");
(idx, h)
}
#[test]
fn asym_scale_opt_out_does_not_leak_across_tabs() {
let mut app = OpenCADStudio::new_for_test();
let (a, ha) = tab_with_insert(&mut app);
let (b, hb) = tab_with_insert(&mut app);
assert_eq!(
ha, hb,
"premise: identically built fresh docs reuse handle values"
);
app.tabs[a].props_asym_scale.insert(ha.value());
assert!(
!app.tabs[b].props_asym_scale.contains(&hb.value()),
"tab B must not see tab A's opt-out"
);
}
}
#[cfg(test)]
mod insert_unit_scale_tests {
use super::{apply_insert_unit_scale, format_unit_factor, insert_unit_scale, insunits_to_mm};