Sample test: one loop checks every sample builds cleanly and without a panic; the robustness copy goes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-31 09:03:29 -04:00
committed by jyviko
parent 6704d3094b
commit 94acc0c435
2 changed files with 30 additions and 38 deletions
+30 -7
View File
@@ -177,17 +177,40 @@ mod tests {
assert!(reopened_plate.contains(solidcraft_geom::Vec3::new(40., 35., 2.)));
}
/// Every built-in sample builds without a failing feature or joint.
/// Every built-in sample builds without a failing feature or joint, and without a panic on
/// the way: panics inside the kernel are caught natively, but abort the web build (wasm
/// can't unwind; the Plastic Enclosure's bosses used to panic 8 times).
#[test]
fn samples_build_cleanly() {
fn samples_build_cleanly_without_panics() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
let me = std::thread::current().id();
let count = Arc::new(AtomicUsize::new(0));
let seen = count.clone();
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(move |_| {
if std::thread::current().id() == me {
seen.fetch_add(1, Ordering::SeqCst);
}
}));
let mut failed = Vec::new();
for s in super::samples() {
let mut session = crate::Session::default();
if let Err(e) = session.run_script(&(s.script)()) {
panic!("{}: {e}", s.name);
let built = session.run_script(&(s.script)());
let panics = count.swap(0, Ordering::SeqCst);
if panics > 0 {
failed.push(format!("{}: {panics} panic(s)", s.name));
}
if let Err(e) = built {
failed.push(format!("{}: {e}", s.name));
continue;
}
failed.extend(session.model.results.iter().filter_map(|r| r.error.as_ref().map(|e| format!("{}: {}: {e}", s.name, r.name))));
if session.model.state().bodies.is_empty() {
failed.push(format!("{}: no bodies", s.name));
}
let failed: Vec<String> = session.model.results.iter().filter_map(|r| r.error.as_ref().map(|e| format!("{}: {e}", r.name))).collect();
assert!(failed.is_empty(), "{}: {failed:?}", s.name);
assert!(!session.model.state().bodies.is_empty(), "{}", s.name);
}
std::panic::set_hook(prev);
assert!(failed.is_empty(), "{failed:?}");
}
}
-31
View File
@@ -174,37 +174,6 @@ fn shell_thicker_than_a_step_says_so() {
assert!(e.to_string().contains("not supported yet"), "{e}");
}
/// Panics inside the kernel are caught natively, but abort the web build (wasm can't unwind).
/// Building the samples must not panic at all (the Plastic Enclosure's bosses used to, 8 times).
#[test]
fn samples_build_without_panics() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
let me = std::thread::current().id();
let count = Arc::new(AtomicUsize::new(0));
let c2 = count.clone();
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
if std::thread::current().id() == me {
c2.fetch_add(1, Ordering::SeqCst);
}
let _ = info;
}));
let mut failed = Vec::new();
for sample in crate::sample::samples() {
let mut s = Session::default();
for c in (sample.script)()["commands"].as_array().into_iter().flatten() {
let _ = s.execute(c["command"].as_str().unwrap_or(""), &c["params"]);
}
let n = count.swap(0, Ordering::SeqCst);
if n > 0 {
failed.push(format!("{}: {n} panic(s)", sample.name));
}
}
std::panic::set_hook(prev);
assert!(failed.is_empty(), "{failed:?}");
}
fn total_volume(s: &Session) -> f64 {
s.model.state().bodies.iter().map(|b| solidcraft_kernel::measure(&b.body).map(|m| m.volume).unwrap_or(0.0)).sum()
}