fix: accept two line picks for sketch coincidence
This commit is contained in:
1 parent
9d7be3c292
commit
1adb2cd69f
4 files changed
+138
-2
No files matched your search
@@ -0,0 +1,63 @@
|
||||
//! Coincident accepts clicked line bodies as well as explicit sketch points.
|
||||
|
||||
use serde_json::json;
|
||||
use solvecraft_engine::sketch::ConstraintKind;
|
||||
use solvecraft_ui_egui::scenario::Harness;
|
||||
|
||||
fn setup() -> Harness {
|
||||
let mut h = Harness::new();
|
||||
h.run(&json!([
|
||||
{"call":"engine.execute","params":{"command":"sketch.create","params":{"plane":"XY"}}},
|
||||
{"call":"engine.execute","params":{"command":"sketch.line","params":{"points":[[10,10],[30,10]],"infer":false,"connect":false}}},
|
||||
{"call":"engine.execute","params":{"command":"sketch.line","params":{"points":[[35,15],[35,40]],"infer":false,"connect":false}}},
|
||||
{"call":"ui.view","params":{"view":"top"}}
|
||||
]))
|
||||
.unwrap();
|
||||
h
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clicked_lines_join_closest_endpoints_in_both_orders() {
|
||||
for reverse in [false, true] {
|
||||
let mut h = setup();
|
||||
let before = serde_json::to_value(&h.app.session.doc).unwrap();
|
||||
let undo = h.app.session.undo.len();
|
||||
let picks = if reverse { [[35.0, 27.5], [20.0, 10.0]] } else { [[20.0, 10.0], [35.0, 27.5]] };
|
||||
h.run(
|
||||
&json!([{"start":"sketch.constraint.coincident"}, {"click":{"sketch":picks[0]}}, {"click":{"sketch":picks[1]}}, {"expect":{"errors":0}}]),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!h.app.status.as_ref().is_some_and(|(_, _, error)| *error));
|
||||
let sk = h.app.session.doc.sketch(h.app.session.active_sketch.unwrap()).unwrap();
|
||||
let a = sk.resolve_point("l1.end").unwrap();
|
||||
let b = sk.resolve_point("l2.start").unwrap();
|
||||
assert!(sk.point(a).unwrap().dist(sk.point(b).unwrap()) < 1e-6);
|
||||
assert!(sk.constraints.iter().any(|c| matches!(c.kind, ConstraintKind::Coincident {p,q} if (p,q)==(a,b) || (p,q)==(b,a))));
|
||||
let fixed_ref = if reverse { "l2.end" } else { "l1.start" };
|
||||
let expected = if reverse { [35.0, 40.0] } else { [10.0, 10.0] };
|
||||
let fixed = sk.point(sk.resolve_point(fixed_ref).unwrap()).unwrap();
|
||||
assert!((fixed.x - expected[0]).abs() < 1e-6 && (fixed.y - expected[1]).abs() < 1e-6);
|
||||
assert_eq!(h.app.session.undo.len(), undo + 1);
|
||||
let after = serde_json::to_value(&h.app.session.doc).unwrap();
|
||||
h.run(&json!([{"call":"engine.execute","params":{"command":"edit.undo","params":{}}}])).unwrap();
|
||||
assert_eq!(serde_json::to_value(&h.app.session.doc).unwrap(), before);
|
||||
h.run(&json!([{"call":"engine.execute","params":{"command":"edit.redo","params":{}}}])).unwrap();
|
||||
assert_eq!(serde_json::to_value(&h.app.session.doc).unwrap(), after);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fixed_line_pair_rejects_without_changing_document_or_history() {
|
||||
let mut h = setup();
|
||||
h.run(&json!([
|
||||
{"call":"engine.execute","params":{"command":"sketch.constraint.fix","params":{"entity":"l1"}}},
|
||||
{"call":"engine.execute","params":{"command":"sketch.constraint.fix","params":{"entity":"l2"}}}
|
||||
]))
|
||||
.unwrap();
|
||||
let before = serde_json::to_value(&h.app.session.doc).unwrap();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.run(&json!([{"start":"sketch.constraint.coincident"},{"click":{"sketch":[20,10]}},{"click":{"sketch":[35,27.5]}}])).unwrap();
|
||||
assert!(h.app.status.as_ref().is_some_and(|(_, _, error)| *error));
|
||||
assert_eq!(serde_json::to_value(&h.app.session.doc).unwrap(), before);
|
||||
assert_eq!(h.app.session.undo.len(), undo);
|
||||
}
|
||||
Reference in new issue
Block a user