fix(sketch): apply Project to complete preselection
This commit is contained in:
1 parent
56b499e951
commit
874315db8e
9 files changed
+231
-6
No files matched your search
@@ -0,0 +1,122 @@
|
||||
use serde_json::json;
|
||||
use solvecraft_engine::Sel;
|
||||
use solvecraft_ui_egui::scenario::Harness;
|
||||
|
||||
fn setup() -> (Harness, u64) {
|
||||
let mut h = Harness::new();
|
||||
let source = h.app.run("sketch.create", json!({"plane":"XY","offset":10})).unwrap()["sketch"].as_u64().unwrap();
|
||||
h.app.run("sketch.line", json!({"points":[[10,10],[30,10]],"infer":false})).unwrap();
|
||||
h.app.run("sketch.point", json!({"point":[20,20],"id":"p"})).unwrap();
|
||||
h.app.run("sketch.finish", json!({})).unwrap();
|
||||
h.app.run("sketch.create", json!({"plane":"XY"})).unwrap();
|
||||
h.app.run("sketch.line", json!({"points":[[40,40],[50,40]],"infer":false})).unwrap();
|
||||
h.app.run("sketch.point", json!({"point":[45,50],"id":"p"})).unwrap();
|
||||
h.call("ui.set", json!({"shownSketches":[source]}));
|
||||
h.call("ui.view", json!({"view":"top"}));
|
||||
(h, source)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clicked_external_curve_and_point_project_with_source_identity_and_one_undo() {
|
||||
let (mut h, source) = setup();
|
||||
h.step(&json!({"click":{"world":[20,10,10]}})).unwrap();
|
||||
h.step(&json!({"click":{"world":[20,20,10]},"shift":true})).unwrap();
|
||||
assert_eq!(
|
||||
h.app.session.selection,
|
||||
vec![Sel::ExternalSketchCurve { sketch: source, id: "l1".into() }, Sel::ExternalSketchPoint { sketch: source, id: "p".into() }]
|
||||
);
|
||||
let before = h.app.session.doc.to_json();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"key":"P"})).unwrap();
|
||||
assert!(!h.app.status.as_ref().is_some_and(|(_, _, error)| *error), "{:?}", h.app.status);
|
||||
assert!(h.app.session.selection.is_empty());
|
||||
assert!(h.app.tool.is_none());
|
||||
assert_eq!(h.app.session.undo.len(), undo + 1);
|
||||
let state = h.app.session.world_state();
|
||||
let sk = &state.sketch(h.app.session.active_sketch.unwrap()).unwrap().sketch;
|
||||
assert_eq!(sk.curves.len(), 2);
|
||||
assert!(sk.curves.iter().any(|curve| curve.link.is_some()));
|
||||
assert!(sk.points.iter().any(|point| point.link.is_some() && (point.pos.x - 20.).abs() < 1e-6 && (point.pos.y - 20.).abs() < 1e-6));
|
||||
let local = sk.point(sk.resolve_point("p").unwrap()).unwrap();
|
||||
assert!((local.x - 45.).abs() < 1e-6 && (local.y - 50.).abs() < 1e-6);
|
||||
let after = h.app.session.doc.to_json();
|
||||
h.app.run("edit.undo", json!({})).unwrap();
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
h.app.run("edit.redo", json!({})).unwrap();
|
||||
assert_eq!(h.app.session.doc.to_json(), after);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_reference_preserves_selection_and_document_atomically() {
|
||||
let (mut h, source) = setup();
|
||||
h.app.session.selection =
|
||||
vec![Sel::ExternalSketchCurve { sketch: source, id: "l1".into() }, Sel::ExternalSketchPoint { sketch: source, id: "missing".into() }];
|
||||
let selection = h.app.session.selection.clone();
|
||||
let before = h.app.session.doc.to_json();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"start":"sketch.project"})).unwrap();
|
||||
assert!(h.app.status.as_ref().is_some_and(|(_, _, error)| *error));
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
assert_eq!(h.app.session.undo.len(), undo);
|
||||
assert_eq!(h.app.session.selection, selection);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn external_point_drag_and_delete_cannot_edit_same_named_local_point() {
|
||||
let (mut h, source) = setup();
|
||||
let before = h.app.session.doc.to_json();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"drag":[{"world":[20,20,10]},{"world":[25,25,10]}]})).unwrap();
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
assert_eq!(h.app.session.undo.len(), undo);
|
||||
h.app.session.selection =
|
||||
vec![Sel::ExternalSketchPoint { sketch: source, id: "p".into() }, Sel::ExternalSketchCurve { sketch: source, id: "l1".into() }];
|
||||
let error = h.app.run("selection.delete", json!({"dry_run":true})).unwrap_err();
|
||||
assert!(error.contains("nothing to delete"), "{error}");
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn axis_and_plane_preselection_projects_as_one_command() {
|
||||
let (mut h, _) = setup();
|
||||
h.app.session.selection = vec![Sel::Axis { name: "X".into() }, Sel::Plane { name: "YZ".into() }];
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"start":"sketch.project"})).unwrap();
|
||||
assert!(!h.app.status.as_ref().is_some_and(|(_, _, error)| *error), "{:?}", h.app.status);
|
||||
assert_eq!(h.app.session.undo.len(), undo + 1);
|
||||
let state = h.app.session.world_state();
|
||||
let sk = &state.sketch(h.app.session.active_sketch.unwrap()).unwrap().sketch;
|
||||
assert_eq!(sk.curves.iter().filter(|c| c.link.is_some()).count(), 2);
|
||||
assert!(h.app.session.selection.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed_local_and_external_selection_keeps_ordinary_project_picking() {
|
||||
let (mut h, source) = setup();
|
||||
h.app.session.selection = vec![Sel::SketchCurve { id: "l1".into() }, Sel::ExternalSketchCurve { sketch: source, id: "l1".into() }];
|
||||
let before = h.app.session.doc.to_json();
|
||||
let selection = h.app.session.selection.clone();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"key":"P"})).unwrap();
|
||||
assert_eq!(h.app.tool.as_ref().map(|tool| tool.cmd), Some("sketch.project"));
|
||||
assert_eq!(h.app.session.selection, selection);
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
assert_eq!(h.app.session.undo.len(), undo);
|
||||
h.step(&json!({"click":{"world":[20,10,10]}})).unwrap();
|
||||
assert_eq!(h.app.session.undo.len(), undo + 1);
|
||||
let state = h.app.session.world_state();
|
||||
assert!(state.sketch(h.app.session.active_sketch.unwrap()).unwrap().sketch.curves.iter().any(|curve| curve.link.is_some()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oversized_preselection_does_not_silently_project_a_subset() {
|
||||
let (mut h, _) = setup();
|
||||
h.app.session.selection = vec![Sel::Axis { name: "X".into() }; 1001];
|
||||
let before = h.app.session.doc.to_json();
|
||||
let undo = h.app.session.undo.len();
|
||||
h.step(&json!({"start":"sketch.project"})).unwrap();
|
||||
assert_eq!(h.app.tool.as_ref().map(|tool| tool.cmd), Some("sketch.project"));
|
||||
assert_eq!(h.app.session.doc.to_json(), before);
|
||||
assert_eq!(h.app.session.undo.len(), undo);
|
||||
assert_eq!(h.app.session.selection.len(), 1001);
|
||||
}
|
||||
Reference in new issue
Block a user