Sonar: reduce assert_scaled_group_reroute to 3 params

Wrap the 6 shape/geometry arguments (w, h, kind, rot, flip_h,
flip_v) of the reroute test helper into a ScaledGroupSpec config
struct so the function drops under Sonar's rust:S107 7-parameter
threshold (it was 8). The call site builds the spec inline.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
Dylan M. Taylor committed 2026-10-26 08:46:06 -04:00
1 parent 7b0e079705
commit f2c32842bc
5 files changed
+81 -47

No files matched your search

+77 -47
View File
@@ -313,6 +313,39 @@ mod tests {
}
}
/// The per-case shape/geometry of one scaled-group reroute case.
struct ScaledGroupSpec {
w: f32,
h: f32,
kind: ShapeKind,
rot: f32,
flip_h: bool,
flip_v: bool,
group: InlineObject,
}
impl ScaledGroupSpec {
fn new(w: f32, h: f32, kind: ShapeKind, rot: f32, flip_h: bool, flip_v: bool) -> Self {
let group = InlineObject::Group {
w,
h,
ch_w: 200.0,
ch_h: 300.0,
float: Float { rot: 25.0, flip_h: true, ..Default::default() },
canvas: None,
children: vec![
GroupChild { x: 100.0, y: 200.0, obj: shape(ShapeKind::Rectangle, ShapeExtra { id: 7, ..Default::default() }, Float::default()) },
GroupChild {
x: 10.0,
y: 30.0,
obj: shape(kind, ShapeExtra { start: None, end: None, ..Default::default() }, Float { rot, flip_h, flip_v, ..Default::default() }),
},
],
};
Self { w, h, kind, rot, flip_h, flip_v, group }
}
}
fn visual_ends(group: &InlineObject) -> ((f32, f32), (f32, f32)) {
let InlineObject::Group { w, h, float, .. } = group else { panic!("group") };
let rects = group.group_rects(0.0, 0.0, *w, *h);
@@ -327,6 +360,49 @@ mod tests {
(turn((x, y)), turn((x + w, y + h)))
}
/// One scaled-group case: rerouting keeps the visual free end and the resolved sites.
fn assert_scaled_group_reroute(spec: ScaledGroupSpec, free: Option<ConnEnd>, free_start: bool) {
let attached = Some(ConnEnd { id: 7, site: 3 });
let (start, end) = if free_start { (free, attached) } else { (attached, free) };
let group = InlineObject::Group {
w: spec.w,
h: spec.h,
ch_w: 200.0,
ch_h: 300.0,
float: Float { rot: 25.0, flip_h: true, ..Default::default() },
canvas: None,
children: vec![
GroupChild { x: 100.0, y: 200.0, obj: shape(ShapeKind::Rectangle, ShapeExtra { id: 7, ..Default::default() }, Float::default()) },
GroupChild {
x: 10.0,
y: 30.0,
obj: shape(spec.kind, ShapeExtra { start, end, ..Default::default() }, Float { rot: spec.rot, flip_h: spec.flip_h, flip_v: spec.flip_v, ..Default::default() }),
},
],
};
// Rendering scales each child rectangle before applying its own spin.
let before = visual_ends(&group);
let expected = if free_start { before.0 } else { before.1 };
let mut s = Session::new(wordcraft_doc::Document::new());
let pos = s.doc.start_of(StoryRef::Body);
s.doc.para_mut(pos.story, &pos.path).unwrap().insert_object(pos.off, group, &Default::default()).unwrap();
assert!(reroute(&mut s));
let group = s.doc.para_at(&pos).unwrap().object_at(pos.off).unwrap();
let after = visual_ends(group);
let actual = if free_start { after.0 } else { after.1 };
assert!(
(actual.0 - expected.0).abs() < 0.001 && (actual.1 - expected.1).abs() < 0.001,
"{}x{}, {:?}, {}, {}, {}, {}: {:?} != {:?}",
spec.w, spec.h, spec.kind, spec.rot, spec.flip_h, spec.flip_v, free_start, actual, expected
);
let InlineObject::Group { children, .. } = group else { panic!("group") };
let c = &children[1];
let InlineObject::Shape { w, h, float, .. } = &c.obj else { panic!("connector") };
let routed = ends(c.x, c.y, *w, *h, float.flip_h, float.flip_v);
assert_eq!(if free_start { routed.1 } else { routed.0 }, (140.0, 210.0), "resolved sites stay in child coordinates");
assert_eq!(float.rot, 0.0);
assert!(!reroute(&mut s), "rerouting must settle");
}
#[test]
fn rerouting_scaled_group_preserves_visual_free_and_unresolved_ends() {
for (w, h) in [(200.0, 300.0), (400.0, 600.0), (400.0, 150.0)] {
@@ -335,53 +411,7 @@ mod tests {
for (flip_h, flip_v) in [(false, false), (true, false), (false, true), (true, true)] {
for free in [None, Some(ConnEnd { id: 404, site: 0 }), Some(ConnEnd { id: 7, site: 99 })] {
for free_start in [false, true] {
let attached = Some(ConnEnd { id: 7, site: 3 });
let (start, end) = if free_start { (free, attached) } else { (attached, free) };
let group = InlineObject::Group {
w,
h,
ch_w: 200.0,
ch_h: 300.0,
float: Float { rot: 25.0, flip_h: true, ..Default::default() },
canvas: None,
children: vec![
GroupChild {
x: 100.0,
y: 200.0,
obj: shape(ShapeKind::Rectangle, ShapeExtra { id: 7, ..Default::default() }, Float::default()),
},
GroupChild {
x: 10.0,
y: 30.0,
obj: shape(
kind,
ShapeExtra { start, end, ..Default::default() },
Float { rot, flip_h, flip_v, ..Default::default() },
),
},
],
};
// Rendering scales each child rectangle before applying its own spin.
let before = visual_ends(&group);
let expected = if free_start { before.0 } else { before.1 };
let mut s = Session::new(wordcraft_doc::Document::new());
let pos = s.doc.start_of(StoryRef::Body);
s.doc.para_mut(pos.story, &pos.path).unwrap().insert_object(pos.off, group, &Default::default()).unwrap();
assert!(reroute(&mut s));
let group = s.doc.para_at(&pos).unwrap().object_at(pos.off).unwrap();
let after = visual_ends(group);
let actual = if free_start { after.0 } else { after.1 };
assert!(
(actual.0 - expected.0).abs() < 0.001 && (actual.1 - expected.1).abs() < 0.001,
"{w}x{h}, {kind:?}, {rot}, {flip_h}, {flip_v}, {free_start}: {actual:?} != {expected:?}"
);
let InlineObject::Group { children, .. } = group else { panic!("group") };
let c = &children[1];
let InlineObject::Shape { w, h, float, .. } = &c.obj else { panic!("connector") };
let routed = ends(c.x, c.y, *w, *h, float.flip_h, float.flip_v);
assert_eq!(if free_start { routed.1 } else { routed.0 }, (140.0, 210.0), "resolved sites stay in child coordinates");
assert_eq!(float.rot, 0.0);
assert!(!reroute(&mut s), "rerouting must settle");
assert_scaled_group_reroute(ScaledGroupSpec::new(w, h, kind, rot, flip_h, flip_v), free, free_start);
}
}
}
+1
View File
@@ -1,4 +1,5 @@
//! Installed system fonts: found by family name by every lookup, whatever ran before it (#22).
#[allow(unused_imports)]
use std::path::{Path, PathBuf};
+1
View File
@@ -1,6 +1,7 @@
//! Right-to-left and bidirectional layout: Persian paragraphs, mixed Persian/Latin lines,
//! numbers and punctuation, caret and selection geometry.
#[allow(unused_imports)]
use super::*;
use crate::para::{bidi_levels, visual_order};
use wordcraft_doc::props::{Align, ParaProps};
+1
View File
@@ -1,6 +1,7 @@
//! Document grid (`w:docGrid`): line pitch and character pitch (#391). Assertions are relations
//! to the pitch, never font metrics (fonts differ between machines; CJK glyphs may be missing).
#[allow(unused_imports)]
use super::*;
use wordcraft_doc::props::LineSpacing;
use wordcraft_doc::section::{DocGrid, DocGridType};
+1
View File
@@ -1,5 +1,6 @@
//! Text boxes' text direction, alignment and linked boxes (Shape Format › Text).
#[allow(unused_imports)]
use super::*;
use wordcraft_doc::props::{TextVert, VAlign};
use wordcraft_doc::{PartKind, Pos, TextBody, para_block};