diff --git a/crates/engine/src/cmd/array.rs b/crates/engine/src/cmd/array.rs index 255555a28..da96ccfed 100644 --- a/crates/engine/src/cmd/array.rs +++ b/crates/engine/src/cmd/array.rs @@ -374,10 +374,14 @@ fn run_arraypolar(s: &mut Session, p: &Value) -> Result { check_size(s, n.saturating_mul(rows).saturating_mul(levels), hs.len())?; let base = point_param(p, "base").or_else(|| s.doc().ok().and_then(|d| first_center(d, &hs))).unwrap_or(c); let row_spacing = f64_or(p, "rowSpacing", 1.0); + let fill = f64_or(p, "angle", 360.0); + if !(fill.abs() >= 1e-9 && fill.abs() <= 360.0 + 1e-9) { + return Err(other("Requires a fill angle between -360 and 360 degrees (not 0).")); + } let kind = ArrayKind::Polar(PolarArray { center: c - base, items: count32(n), - fill: f64_or(p, "angle", 360.0), + fill: fill.clamp(-360.0, 360.0), rotate: bool_or(p, "rotate", true), rows: count32(rows), row_spacing, diff --git a/crates/engine/tests/it/array_commands.rs b/crates/engine/tests/it/array_commands.rs index d420c36d6..61d5a0d02 100644 --- a/crates/engine/tests/it/array_commands.rs +++ b/crates/engine/tests/it/array_commands.rs @@ -212,3 +212,20 @@ fn arrays_over_maxarray_are_refused_not_shrunk() { assert!(s.current_prompt().is_none(), "{}", prompt(&s)); assert_eq!(circle_centers(&s).len(), 2000); } + +#[test] +fn json_arraypolar_rejects_bad_fill_angles() { + let mut s = Session::new(); + let h = s.execute("circle", &json!({"center": [5, 0], "radius": 1})).unwrap()["handle"].clone(); + let before = s.doc().unwrap().model.iter().count(); + for bad in [0.0, 720.0, -400.0, 360.5] { + let p = json!({"handles": [h], "center": [0, 0], "count": 4, "angle": bad, "associative": false}); + let e = s.execute("arraypolar", &p).unwrap_err(); + assert!(e.to_string().contains("Requires a fill angle between -360 and 360 degrees"), "{bad}: {e}"); + assert_eq!(s.doc().unwrap().model.iter().count(), before, "{bad}"); + } + for ok in [360.0, -360.0] { + let p = json!({"handles": [h], "center": [0, 0], "count": 4, "angle": ok, "associative": false}); + s.execute("arraypolar", &p).unwrap(); + } +}