M4: Boolean groups: test the one-radius panel through corner smoothing (#2222)

The field test's "no field per corner" check passed for any shape, since corner fields are built
only while the individual-corners popover is open. A boolean group's button now has its own test
beside the polygons' (shared helper): it is named Corner smoothing, opens no corner fields, and
sets the smoothing in one undo step. ROADMAP's status line reads minor, as the other docs do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote; Fable 5.1 reviewed
This commit is contained in:
Trevor Brown
2026-11-10 13:53:13 -05:00
co-authored by Claude Opus 5.5
parent 529134b850
commit bae366ba51
3 changed files with 34 additions and 18 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+33 -16
View File
@@ -166,25 +166,42 @@ fn polygons_and_stars_take_corner_smoothing() {
for cmd in ["shape.polygon", "shape.star"] {
let mut s = Session::new();
let id = NodeId(s.execute(cmd, &json!({"x": 0, "y": 0, "width": 120, "height": 120})).unwrap()["id"].as_u64().unwrap());
s.execute("node.set", &json!({"ids": [id], "props": {"cornerRadius": 8}})).unwrap();
s.execute("select.set", &json!({"ids": [id]})).unwrap();
let mut u = Ui::new(s);
// With no corners of their own, the button is named for what it opens.
let t = named_button(&mut u, "Corner smoothing");
click(&mut u, t);
assert!((0..4).all(|k| u.ctx.read_response(Id::unique(("corner", k)).with("field")).is_none()), "{cmd}: one radius, no corner fields");
let smoothing = u.ctx.read_response(Id::unique("smoothing").with("field")).expect("the smoothing field shows").rect.center();
let history = u.app.session.undo_depth().0;
click(&mut u, smoothing);
u.frame(vec![Event::Text("60".into())]);
enter(&mut u);
u.frame(vec![]);
let n = u.app.session.doc().unwrap().node(id).unwrap().clone();
assert!((n.corners.smoothing - 0.6).abs() < 1e-9, "{cmd}: {}", n.corners.smoothing);
assert_eq!(u.app.session.undo_depth().0, history + 1, "{cmd}: one undo step");
takes_corner_smoothing(s, id, cmd);
}
}
/// A boolean group has one radius for its whole result (#2222): like a polygon, its button opens
/// corner smoothing, with no field per corner.
#[test]
fn a_boolean_group_opens_corner_smoothing_and_has_no_corner_fields() {
let mut s = Session::new();
let rect = |s: &mut Session, x: i32| s.execute("shape.rectangle", &json!({"x": x, "y": 0, "width": 100, "height": 100})).unwrap()["id"].clone();
let (a, b) = (rect(&mut s, 0), rect(&mut s, 60));
let g = NodeId(s.execute("bool.union", &json!({"ids": [a, b]})).unwrap()["id"].as_u64().unwrap());
takes_corner_smoothing(s, g, "bool.union");
}
/// With `id` rounded at 8 and selected: the panel's button is named Corner smoothing and opens
/// the smoothing field with no field per corner, and typing 60 sets the smoothing in one undo step.
fn takes_corner_smoothing(mut s: Session, id: NodeId, what: &str) {
s.execute("node.set", &json!({"ids": [id], "props": {"cornerRadius": 8}})).unwrap();
s.execute("select.set", &json!({"ids": [id]})).unwrap();
let mut u = Ui::new(s);
// With no corners of their own, the button is named for what it opens.
let t = named_button(&mut u, "Corner smoothing");
click(&mut u, t);
assert!((0..4).all(|k| u.ctx.read_response(Id::unique(("corner", k)).with("field")).is_none()), "{what}: one radius, no corner fields");
let smoothing = u.ctx.read_response(Id::unique("smoothing").with("field")).expect("the smoothing field shows").rect.center();
let history = u.app.session.undo_depth().0;
click(&mut u, smoothing);
u.frame(vec![Event::Text("60".into())]);
enter(&mut u);
u.frame(vec![]);
let n = u.app.session.doc().unwrap().node(id).unwrap().clone();
assert!((n.corners.smoothing - 0.6).abs() < 1e-9, "{what}: {}", n.corners.smoothing);
assert_eq!(u.app.session.undo_depth().0, history + 1, "{what}: one undo step");
}
/// A closed vector shows the same Corner smoothing control, and its iOS button sets 60% in one
/// undo step; an open vector, which has no closed shape to smooth, shows no smoothing control.
#[test]
-1
View File
@@ -1416,7 +1416,6 @@ fn a_boolean_group_has_one_corner_radius_field_and_a_mixed_selection_reads_mixed
let radii = |u: &Ui, n: NodeId| u.app.session.doc().unwrap().node(n).unwrap().corners.radii;
assert_eq!(radii(&u, g), [20.0; 4]);
assert_eq!(undo_steps(&u), steps + 1, "one undo step");
assert!((0..4).all(|k| u.ctx.read_response(Id::unique(("corner", k)).with("field")).is_none()), "no field per corner");
u.app.run("select.set", json!({"ids": [g, r]}));
assert_eq!(field(&mut u, "Corner radius").1, "Mixed");
type_into(&mut u, "Corner radius", "8", Key::Enter);