From b6c3bf3c53eb8a45f613b2cb30ce615fb03f523b Mon Sep 17 00:00:00 2001 From: jyviko <2501648+jyviko@users.noreply.github.com> Date: Thu, 29 Oct 2026 22:04:03 -0400 Subject: [PATCH] Face capture test: an Offset Face's top is anchored by its exact history name legacy_internal_capture_refuses_an_uncaptured_source_in_another_component picked the top Offset Face raised as a face with neither a construction certificate nor an exact history name (#494), to reach the legacy path that refuses a profile across components while the source occurrence's move is uncaptured. Offset Face has SMLib's history since 0f3d6f177 (shell, offset faces and thicken through SMLib), so that top is now named exactly (F3:+z#[F3:-x], verified) and capture_face_anchor gives it a lineage anchor; the legacy path is not taken, and the capture is right to succeed: an anchored attachment captures its path's pending positions when it is made (capture_positions). The test, renamed to what it now checks (internal_capture_in_another_component_anchors_an_offset_face_by_its_history_name), asserts the face still has no construction certificate, the capture is a Lineage anchor on the occurrence's path, and capturing changes neither the document nor the pending moves. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/cmd/face_tests.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/engine/src/cmd/face_tests.rs b/crates/engine/src/cmd/face_tests.rs index 5af20f9c2f..e9afe13893 100644 --- a/crates/engine/src/cmd/face_tests.rs +++ b/crates/engine/src/cmd/face_tests.rs @@ -137,20 +137,23 @@ fn generated_profiles_and_press_pull_convert_rotated_occurrence_picks_once() { } /// A 40 x 30 x 20 box whose top is split at x = 20 and its left half raised 5 by Offset Face: -/// the raised top has no construction certificate and no exact history name yet (#494). +/// the raised top has no construction certificate, and an exact history name from SMLib's +/// offset history. fn raised_half(s: &mut Session, body: &str) { run(s, "solid.box", json!({"length":40,"width":30,"height":20,"body_name":body})); run(s, "solid.split_face", json!({"faces":[[10,15,20]],"plane":{"origin":[20,0,0],"normal":[1,0,0]}})); run(s, "solid.offset_face", json!({"faces":[[10,15,20]],"distance":5})); } +/// Internal capture of a face in another component whose occurrence has an uncaptured move: +/// the raised top has no construction certificate, but its exact history name keeps it, so the +/// capture is an exact (lineage) anchor on that occurrence's path, whose pending position is +/// captured when the attachment is made (`capture_positions`). Capturing changes nothing. #[test] -fn legacy_internal_capture_refuses_an_uncaptured_source_in_another_component() { +fn internal_capture_in_another_component_anchors_an_offset_face_by_its_history_name() { let mut s = Session::default(); let component = run(&mut s, "component.create", json!({"name":"Source","grounded":false})); let occurrence = component["occurrence"].as_u64().unwrap(); - // A face Offset Face raised has no construction certificate or exact history name yet: - // the legacy path. raised_half(&mut s, "Stock"); run(&mut s, "component.activate", json!({"component":0})); run(&mut s, "occurrence.move", json!({"occurrence":occurrence,"translate":[30,0,0],"capture":false})); @@ -165,15 +168,20 @@ fn legacy_internal_capture_refuses_an_uncaptured_source_in_another_component() { .into_iter() .find(|face| face.plane_normal.is_some_and(|normal| normal.z > 0.999) && (face.centroid.z - 25.0).abs() < 1e-6) .unwrap(); + assert!(state.body("Stock").unwrap().body.face_plane(end.index).is_none(), "the raised top has no construction certificate"); let before = s.doc.to_json(); - let error = super::super::sketch::face::capture_internal( + let pending = s.pending_moves.clone(); + let plane = super::super::sketch::face::capture_internal( &s, &json!({"face":[40,15,25],"body":"Stock","index":end.index,"path":[occurrence]}), "internal", ) - .unwrap_err(); - assert!(error.to_string().contains("capture the source occurrence position"), "{error}"); + .unwrap(); + let anchor = super::super::sketch::face::anchor(&plane).expect("an exact attachment"); + assert_eq!(anchor.target.certificate, Some(solidcraft_doc::config::FaceCertificate::Lineage)); + assert_eq!(anchor.path, vec![occurrence]); assert_eq!(s.doc.to_json(), before); + assert_eq!(s.pending_moves, pending); } #[test]