Files
OneCAD/crates/ui-egui/src/dialogs_plastic_tests.rs
T
bherbruckandClaude Opus 5.5 296683229d Rename SolveCraft to SolidCraft everywhere, with compatibility shims (#389)
* WIP deep rename (not for push)

* WIP2

* WIP3

* WIP4 wxs fix

* rustfmt

* Rename the remaining identifiers in merged crash-report code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:17:01 -04:00

105 lines
4.3 KiB
Rust

use serde_json::json;
use solidcraft_engine::Session;
use super::*;
use crate::Services;
use crate::dialogs::{apply_commands, face_sel, for_feature as edit_dialog};
fn app_with(cmds: &[(&str, Value)]) -> SolveApp {
let mut s = Session::default();
for (id, p) in cmds {
s.execute(id, p).unwrap();
}
SolveApp::new(s, Services::default())
}
fn run_all(app: &mut SolveApp, c: Vec<(String, Value)>) {
for (id, p) in c {
app.run(&id, p).unwrap();
}
}
/// A face pick places a boss; optional values left empty take the rule; ribs only with a count;
/// Edit Feature keeps the direction and refills the values.
#[test]
fn boss_from_a_face_pick() {
let mut app = app_with(&[("solid.box", json!({"length": 60, "width": 60, "height": 3}))]);
app.session.selection = face_sel(&app.session, Vec3::new(30.0, 30.0, 3.0)).into_iter().collect();
app.start("plastic.boss");
let mut d = app.dialog.clone().unwrap();
assert_eq!(d.primary().map(|p| p.0), Some("Height"));
let c = apply_commands(&app, &d).unwrap();
let p = &c[0].1;
assert_eq!(p["position"], json!([30.0, 30.0, 3.0]));
assert_eq!(p["hole_diameter"], "3 mm");
assert!(p.get("draft").is_none() && p.get("ribs").is_none(), "{p}");
if let Kind::Plastic(Pl::Boss { ribs, .. }) = &mut d.kind {
*ribs = "4".into();
}
let c = apply_commands(&app, &d).unwrap();
assert_eq!(c[0].1["ribs"], "4");
run_all(&mut app, c);
let f = app.session.doc.features.last().unwrap().clone();
let e = edit_dialog(&app, f.id, None).unwrap();
assert!(matches!(&e.kind, Kind::Plastic(Pl::Boss { ribs, .. }) if ribs == "4"));
let c = apply_commands(&app, &e).unwrap();
assert_eq!(c[0].0, "timeline.redefine");
assert_eq!(c[0].1["params"]["direction"], json!([0.0, 0.0, 1.0]));
}
/// A snap fit's catch points across the face; a groove takes its clearance; rests can be round
/// or rectangular.
#[test]
fn snap_lip_rest() {
for n in [Vec3::Z, Vec3::X, Vec3::new(0.0, -1.0, 0.0)] {
let dirs = hook_dirs(n);
assert_eq!(dirs.len(), 4);
assert!(dirs.iter().all(|(_, d)| d.dot(n).abs() < 1e-12 && (d.len() - 1.0).abs() < 1e-12));
}
let mut app = app_with(&[
("solid.box", json!({"length": 80, "width": 50, "height": 30})),
("solid.shell", json!({"faces": [[40, 25, 30]], "thickness": 2})),
]);
app.session.selection = face_sel(&app.session, Vec3::new(1.0, 25.0, 30.0)).into_iter().collect();
app.start("plastic.lip");
let mut d = app.dialog.clone().unwrap();
if let Kind::Plastic(Pl::Lip { groove, gap, .. }) = &mut d.kind {
*groove = true;
*gap = "0.2 mm".into();
}
let c = apply_commands(&app, &d).unwrap();
assert_eq!(c[0].1["type"], "groove");
assert_eq!(c[0].1["gap"], "0.2 mm");
run_all(&mut app, c);
let mut app = app_with(&[("solid.box", json!({"length": 40, "width": 40, "height": 4}))]);
app.session.selection = face_sel(&app.session, Vec3::new(20.0, 20.0, 4.0)).into_iter().collect();
app.start("plastic.snap_fit");
let c = apply_commands(&app, app.dialog.as_ref().unwrap()).unwrap();
assert_eq!(c[0].1["hook"], json!([1.0, 0.0, 0.0]));
run_all(&mut app, c);
app.dialog = None;
app.session.selection = face_sel(&app.session, Vec3::new(5.0, 5.0, 4.0)).into_iter().collect();
app.start("plastic.rest");
let mut d = app.dialog.clone().unwrap();
assert!(apply_commands(&app, &d).unwrap()[0].1.get("length").is_none(), "round");
if let Kind::Plastic(Pl::Rest { round, .. }) = &mut d.kind {
*round = false;
}
assert_eq!(apply_commands(&app, &d).unwrap()[0].1["length"], "15 mm");
}
/// The rule manager edits a library rule into the design; Assign gives bodies a rule.
#[test]
fn plastic_rules_manage_and_assign() {
let mut app = app_with(&[("solid.box", json!({"length": 10, "width": 10, "height": 10}))]);
app.start("plastic.manage_rules");
let d = app.dialog.clone().unwrap();
assert!(apply_commands(&app, &d).is_ok());
app.session.selection = vec![Sel::Body { name: "Body1".into() }];
app.start("plastic.assign_rule");
let c = apply_commands(&app, app.dialog.as_ref().unwrap()).unwrap();
assert_eq!(c[0].1["bodies"], json!(["Body1"]));
assert_eq!(c[0].1["rule"], "ABS (1.5mm)");
run_all(&mut app, c);
}