From 8a730bab6b8b3e661111c696eecfb2e65cd16d59 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Thu, 5 Nov 2026 20:03:54 -0800 Subject: [PATCH] Reject invalid New Art Basic parameters --- crates/engine/src/cmd/newart.rs | 4 ++-- crates/engine/src/tests/newart.rs | 14 ++++++++++++++ docs/mcp.md | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/newart.rs b/crates/engine/src/cmd/newart.rs index 9401402c5..34db64081 100644 --- a/crates/engine/src/cmd/newart.rs +++ b/crates/engine/src/cmd/newart.rs @@ -16,7 +16,7 @@ use vectorcraft_doc::{Appearance, AppearanceItem, FillLayer, GraphicStyle, Node, use vectorcraft_tools::PaintDefaults; use super::gradient::unplaced; -use super::{CommandSpec, Result, Session, always, cmd}; +use super::{CommandSpec, Result, Session, always, cmd, switch_or}; pub fn specs() -> Vec { vec![ @@ -216,7 +216,7 @@ impl Session { } fn set_basic(s: &mut Session, p: &Value) -> Result { - let on = p.get("on").and_then(Value::as_bool).unwrap_or(!s.prefs.new_art_basic); + let on = switch_or(p, "on", !s.prefs.new_art_basic, "appearance.setNewArtBasic")?; s.prefs.new_art_basic = on; Ok(json!({ "on": on })) } diff --git a/crates/engine/src/tests/newart.rs b/crates/engine/src/tests/newart.rs index 6bc5eb48b..0f41a5b9d 100644 --- a/crates/engine/src/tests/newart.rs +++ b/crates/engine/src/tests/newart.rs @@ -29,6 +29,20 @@ fn undo_len(s: &Session) -> usize { s.doc().unwrap().history.undo.len() } +#[test] +fn invalid_new_art_basic_parameters_keep_the_preference_unchanged() { + let mut s = session(); + let undo = undo_len(&s); + for params in [json!({"on": "false"}), json!({"on": 1})] { + assert!(s.execute("appearance.setNewArtBasic", ¶ms).is_err(), "accepted {params}"); + assert!(s.prefs.new_art_basic, "changed the preference for {params}"); + assert_eq!(undo_len(&s), undo, "recorded undo for {params}"); + } + // Left out, or null as for every command, it toggles. + assert_eq!(s.execute("appearance.setNewArtBasic", &json!(null)).unwrap(), json!({"on": false})); + assert_eq!(s.execute("appearance.setNewArtBasic", &json!({"on": null})).unwrap(), json!({"on": true})); +} + #[test] fn stroke_options_set_with_nothing_selected_carry_to_the_next_object() { let mut s = session(); diff --git a/docs/mcp.md b/docs/mcp.md index 87ac5085c..26f38f758 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -3721,6 +3721,7 @@ style; `add: true` stacks it) set that template instead of editing art. With the Appearance off (`appearance.setNewArtBasic {on: false}`, the preference `newArtBasic`) new art takes the whole appearance of the last selected object. `appearance.newArt` reports what the next object gets; `paint.default` resets it. +`appearance.setNewArtBasic` rejects an `on` value that is not a boolean. Omitting `on` toggles the current preference. ```json {"name":"run_command","arguments":{"command":"select.none","params":{}}}