//! Enter submits only the focused Parameters editor row. use egui::{Event, Key, Modifiers}; use serde_json::json; use solvecraft_ui_egui::scenario::Harness; fn open() -> Harness { let mut h = Harness::new(); h.step(&json!({"widget":"Parameters"})).unwrap(); assert!(h.app.params.is_some()); h } fn fill(h: &mut Harness, field: &str, text: &str) { h.run(&json!([ {"click":{"handle":format!("param:new:{field}")}}, {"key":"A","cmd":true}, {"text":text} ])) .unwrap(); } fn enter(h: &mut Harness, repeat: bool) { h.app.synthetic.push(Event::Key { key: Key::Enter, physical_key: None, pressed: true, repeat, modifiers: Modifiers::NONE }); h.frame(); h.app.synthetic.push(Event::Key { key: Key::Enter, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::NONE }); h.frames(3); } #[test] fn parameter_enter_adds_once_and_focuses_next_name() { let mut h = open(); fill(&mut h, "name", "width"); fill(&mut h, "expression", "25 mm"); let undo = h.app.session.undo.len(); enter(&mut h, false); assert_eq!(h.app.session.undo.len(), undo + 1); assert!(h.app.params.as_ref().unwrap().new_name.is_empty()); assert!(h.app.params.as_ref().unwrap().error.is_none()); let saved = h.app.session.doc.to_json(); enter(&mut h, true); assert_eq!(h.app.session.doc.to_json(), saved); assert_eq!(h.app.session.undo.len(), undo + 1); // Name has focus after successful creation; no mouse needed for the next name. h.run(&json!([{"text":"height"}])).unwrap(); assert_eq!(h.app.params.as_ref().unwrap().new_name, "height"); enter(&mut h, false); assert_eq!(h.app.session.undo.len(), undo + 2); let result = h.app.session.execute("parameters.list", &json!({})).unwrap(); assert!(result["parameters"].as_array().unwrap().iter().any(|p| p["name"] == "height")); } #[test] fn parameter_enter_invalid_preserves_draft_and_other_rows() { let mut h = open(); h.app.session.execute("parameters.add", &json!({"name":"existing","expression":"10 mm"})).unwrap(); h.frames(3); fill(&mut h, "name", "bad"); fill(&mut h, "expression", "missing + 1 mm"); let saved = h.app.session.doc.to_json(); let undo = h.app.session.undo.len(); enter(&mut h, false); assert_eq!(h.app.session.doc.to_json(), saved); assert_eq!(h.app.session.undo.len(), undo); let d = h.app.params.as_ref().unwrap(); assert_eq!(d.new_name, "bad"); assert_eq!(d.new_expr, "missing + 1 mm"); assert!(d.error.is_some()); fill(&mut h, "expression", "15 mm"); fill(&mut h, "name", "existing"); enter(&mut h, false); assert_eq!(h.app.session.doc.to_json(), saved); assert!(h.app.params.as_ref().unwrap().error.is_some()); } #[test] fn parameter_enter_edits_expression_without_adding_draft() { let mut h = open(); h.app.session.execute("parameters.add", &json!({"name":"width","expression":"10 mm"})).unwrap(); h.frames(3); fill(&mut h, "name", "unsubmitted"); let undo = h.app.session.undo.len(); h.run(&json!([{"click":{"handle":"param:width"}}, {"key":"A","cmd":true}, {"text":"20 mm"}])).unwrap(); enter(&mut h, false); assert_eq!(h.app.session.undo.len(), undo + 1); assert_eq!(h.app.params.as_ref().unwrap().new_name, "unsubmitted"); let result = h.app.session.execute("parameters.list", &json!({})).unwrap(); let ps = result["parameters"].as_array().unwrap(); assert!(ps.iter().any(|p| p["name"] == "width" && p["expression"] == "20 mm")); assert!(!ps.iter().any(|p| p["name"] == "unsubmitted")); let saved = h.app.session.doc.to_json(); h.run(&json!([{"click":{"handle":"param:width"}}, {"key":"A","cmd":true}, {"text":"missing + 2 mm"}])).unwrap(); enter(&mut h, false); assert_eq!(h.app.session.doc.to_json(), saved); assert!(h.app.params.as_ref().unwrap().error.is_some()); assert_eq!(h.app.params.as_ref().unwrap().editing.get("width").map(String::as_str), Some("missing + 2 mm")); } #[test] fn parameter_enter_comment_uses_selected_unit_and_unrelated_focus_does_not_submit() { let mut h = open(); fill(&mut h, "name", "length"); h.run(&json!([{"click":{"handle":"param:new:unit"}}, {"widget":"cm"}])).unwrap(); fill(&mut h, "expression", "2 cm"); fill(&mut h, "comment", "Overall length"); let undo = h.app.session.undo.len(); h.run(&json!([{"click":{"handle":"params:title"}}])).unwrap(); enter(&mut h, false); assert_eq!(h.app.session.undo.len(), undo); h.run(&json!([{"click":{"handle":"param:new:comment"}}])).unwrap(); enter(&mut h, false); let result = h.app.session.execute("parameters.list", &json!({})).unwrap(); assert!(result["parameters"].as_array().unwrap().iter().any(|p| p["name"] == "length" && p["unit"] == "cm" && p["comment"] == "Overall length")); assert_eq!(h.app.session.undo.len(), undo + 1); }