app
SOLIDWORKS Bridge
Public Made by Adomby adom
Launch, model and quit SOLIDWORKS from any Adom container. Nothing is ever lost.
main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
//! CSWA PHASE 1 (0.11.0) — Drew, 2026-10-15: "pull 3-5 random parts from CSWA
//! exams as part of our e2e testing/validation for each release … We need this
//! bridge to be a real, useable tool, for more than the basics."
//!
//! The new DSL (lines and arcs, revolve, mirror, hole, end conditions, draft,
//! density) through the WHOLE bridge, and the benchmark (swx_selftest
//! {level:"cswa"}). EVERYTHING HERE RUNS IN THE SIMULATOR: the geometry is the
//! mock's arithmetic model against closed forms, NOT a SOLIDWORKS measurement —
//! every new op says `proven.live:false` until a live run measures it.
mod common;
use common::{Bridge, TempDir};
use serde_json::{json, Value};
const PI: f64 = std::f64::consts::PI;
fn s(v: &Value) -> String {
serde_json::to_string_pretty(v).unwrap_or_default()
}
fn boot(tag: &str) -> (Bridge, TempDir) {
let machine = TempDir::new(tag);
std::fs::write(machine.join("windows.json"), "[]").unwrap();
let b = Bridge::start_with(&[("SWX_LAUNCH_FAKE_DIR", &machine.path())]);
b.call("swx_start", json!({}));
(b, machine)
}
fn near(a: &Value, b: f64, rel: f64) -> bool {
a.as_f64().map(|x| (x - b).abs() <= rel * b.abs().max(1e-9)).unwrap_or(false)
}
#[test]
fn a_flanged_bushing_revolved_holed_and_mirrored_weighs_what_the_closed_forms_say() {
let (b, _m) = boot("cswa-bushing");
// A flanged bushing, revolved from ONE closed polyline about the sketch's
// y axis: a Ø40 x 8 flange and a Ø24 x 30 barrel, Ø12 bore.
let r = b.call("swx_run_script", json!({"script": [
{"op": "new_part"},
{"op": "sketch", "plane": "Front Plane", "entities": [
{"polyline": {"points": [[6, 0], [20, 0], [20, 8], [12, 8], [12, 30], [6, 30]], "close": true}}]},
{"op": "revolve", "axis": "y"},
// From the flange's BOTTOM face (the simulator picks faces of a body's
// box; SOLIDWORKS takes any planar face), 8 mm: through the flange.
{"op": "hole", "atMm": [16, 0, 0], "diameterMm": 3, "depthMm": 8},
{"op": "mirror", "plane": "Right Plane"},
{"op": "set_material", "name": "AISI 1020", "densityKgM3": 7900}
]}));
check!(b, "the script runs end to end", r["success"] == true, s(&r));
let steps = r["steps"].as_array().cloned().unwrap_or_default();
let ops: Vec<&str> = steps.iter().map(|x| x["op"].as_str().unwrap_or("")).collect();
check!(b, "revolve, hole, mirror, set_material ran in order", ops == ["new_part", "sketch", "revolve", "hole", "mirror", "set_material"], format!("{ops:?}"));
// The 360 revolve and the mirror about a named plane were measured by the first
// canary (2026-10-16, 0.11.4-rc1, cswa-09 and cswa-10 on SOLIDWORKS 2026) — so on
// this simulated 2025 they are not live, and nothing is unmeasured.
for (i, op) in [(2, "revolve"), (4, "mirror")] {
let p = &steps[i]["result"]["proven"];
check!(
b,
&format!("{op}: measured on 2026 by the canary, so not live on this simulated 2025, and nothing unmeasured"),
p["live"] == false && p.get("unmeasured").is_none()
&& p["measuredOn"].as_array().map(|a| a.iter().any(|m| m["bridge"] == "0.11.4-rc1" && m["solidworks"] == 2026)).unwrap_or(false),
s(p)
);
}
// The plain hole and the density were measured by the first live CSWA run
// (2026-10-15, SOLIDWORKS 2026) — not on the simulated release (2025).
for (i, op) in [(3, "hole"), (5, "set_material")] {
let p = &steps[i]["result"]["proven"];
check!(
b,
&format!("{op}: measured on 2026 by the CSWA run, so not live on this simulated 2025, and nothing unmeasured"),
p["live"] == false && p.get("unmeasured").is_none()
&& p["measuredOn"].as_array().map(|a| a.iter().any(|m| m["bridge"] == "0.11.2" && m["solidworks"] == 2026)).unwrap_or(false),
s(p)
);
}
check!(b, "the sketch's lines are named as sketch.line", steps[1]["result"]["proven"]["variants"].as_array().map(|a| a.iter().any(|v| v == "sketch.line")).unwrap_or(false), s(&steps[1]["result"]["proven"]));
let solid = PI * ((400.0 - 36.0) * 8.0 + (144.0 - 36.0) * 22.0);
let holes = 2.0 * PI * 2.25 * 8.0;
let ib = b.call("swx_inspect_bodies", json!({}));
check!(
b,
"the volume is the revolved profile less two Ø3 holes through the flange (SIMULATED by the arithmetic model: exact)",
near(&ib["bodies"][0]["volumeMm3"], solid - holes, 1e-7),
format!("want {} mm3\n{}", solid - holes, s(&ib))
);
let mp = b.call("swx_mass_properties", json!({}));
check!(
b,
"swx_mass_properties integrates the same solid by columns (within 0.1 %): mass = volume x 7900, the material named",
near(&mp["volumeMm3"], solid - holes, 1e-3) && near(&mp["massG"], (solid - holes) * 7.9e-3, 1e-3) && mp["densityKgM3"] == 7900.0
&& mp["materialName"] == "AISI 1020" && mp["simulatedBy"]["volume"].as_str().unwrap_or("").contains("column"),
format!("want {} mm3\n{}", solid - holes, s(&mp))
);
}
#[test]
fn an_open_profile_and_a_crossing_axis_are_refused_before_anything_is_built() {
let (b, _m) = boot("cswa-refusals");
let before = b.call("swx_docs", json!({}))["count"].clone();
let r = b.call("swx_run_script", json!({"script": [
{"op": "new_part"},
{"op": "sketch", "entities": [{"polyline": {"points": [[0, 0], [10, 0], [10, 10]]}}]},
{"op": "extrude", "depthMm": 5}
]}));
check!(b, "an open polyline is refused, naming the gap", r["success"] == false && r["error"].as_str().unwrap_or("").contains("gap of"), s(&r));
let r = b.call("swx_run_script", json!({"script": [
{"op": "new_part"},
{"op": "sketch_rect", "widthMm": 10, "heightMm": 4, "anchor": "center"},
{"op": "revolve", "axis": "y"}
]}));
check!(b, "a profile across the revolve axis is refused", r["success"] == false && r["error"].as_str().unwrap_or("").contains("crosses the revolve axis"), s(&r));
check!(b, "...and neither created a document", b.call("swx_docs", json!({}))["count"] == before, "");
}
#[test]
fn the_cswa_level_builds_weighs_and_closes_every_shipped_part() {
let (b, _m) = boot("cswa-selftest");
let before = b.call("swx_docs", json!({}))["count"].clone();
let r = b.call("swx_selftest", json!({"level": "cswa"}));
let parts = r["cswa"]["parts"].as_array().cloned().unwrap_or_default();
let n = parts.len();
check!(
b,
"every runnable spec is within tolerance in the simulator, and the summary says so",
r["success"] == true && r["level"] == "cswa" && n >= 1 && r["cswa"]["allPassed"] == true
&& r["cswa"]["summary"].as_str().unwrap_or("").starts_with(&format!("{n} of {n} CSWA parts within tolerance")),
s(&r["cswa"])
);
check!(b, "the hint LEADS with the verdict", r["_hint"].as_str().unwrap_or("").starts_with(&format!("{n} of {n} CSWA parts")), s(&r["_hint"]));
let rows = r["results"].as_array().cloned().unwrap_or_default();
if std::env::var("CSWA_PRINT").is_ok() {
for x in rows.iter().filter(|x| x["name"].as_str().unwrap_or("").starts_with("CSWA")) {
eprintln!("{} pass={} {} {}", x["name"], x["pass"], x["checks"], x.get("skipped").cloned().unwrap_or_default());
}
}
let lego = rows.iter().find(|x| x["name"].as_str().unwrap_or("").contains("cswa-00-lego-2x4")).cloned().unwrap_or(Value::Null);
check!(
b,
"spec 0 (the LEGO brick): mass and volume compared against Michael's measured volume, ABS",
lego["pass"] == true && lego["checks"].as_array().map(|a| a.iter().any(|c| c["quantity"] == "volumeMm3" && c["pass"] == true)).unwrap_or(false),
s(&lego)
);
check!(b, "every part it built was CLOSED", b.call("swx_docs", json!({}))["count"] == before, "");
let one = b.call("swx_selftest", json!({"level": "cswa", "only": ["cswa-00-lego-2x4"]}));
check!(b, "only:[id] runs one part", one["cswa"]["ran"] == 1, s(&one["cswa"]));
}
#[test]
fn the_cswa_level_refuses_up_front_with_solidworks_closed() {
let machine = TempDir::new("cswa-closed");
std::fs::write(machine.join("windows.json"), "[]").unwrap();
let b = Bridge::start_with(&[("SWX_LAUNCH_FAKE_DIR", &machine.path())]);
let r = b.call("swx_selftest", json!({"level": "cswa"}));
check!(b, "refused: SOLIDWORKS is not running, nothing created", r["success"] == false && r["errorCode"] == "solidworks_not_running", s(&r));
}
#[test]
fn the_script_help_teaches_the_cswa_ops() {
let (b, _m) = boot("cswa-help");
let r = b.call("swx_run_script", json!({"script": "make me a bracket"}));
let ops: Vec<String> = r["ops"].as_array().cloned().unwrap_or_default().iter().filter_map(|o| o.as_str().map(String::from)).collect();
check!(
b,
"swx_run_script's help lists revolve, revolve_cut, mirror and hole, with their arguments",
["revolve", "revolve_cut", "mirror", "hole"].iter().all(|o| ops.iter().any(|x| x == o) && r["opArgs"].get(*o).is_some()),
s(&r)
);
let ents = r["opArgs"]["sketch"]["entities"].as_str().unwrap_or("");
check!(
b,
"...and every sketch entity kind, and the face-offset plane",
["line:", "polyline:", "arc:", "arc3:", "tangentArc:", "slot:", "polygon:", "sketchFillet:", "sketchChamfer:", "construction:true"].iter().all(|k| ents.contains(k))
&& r["opArgs"]["sketch"]["plane"].as_str().unwrap_or("").contains("{offsetFrom: {face:"),
s(&r["opArgs"]["sketch"])
);
}
/// THE SPECS DO WHAT THEY SAY (0.11.4). Every spec's `exercises` list is a
/// subset of the variants its steps report — run in the simulator (which
/// classifies each step exactly as the COM host does), or, for a part only
/// SOLIDWORKS can build, classified from its parsed script. Every DERIVED key
/// is reproduced by its `derivation` (tools/cswa-check.py --derivations,
/// where python3 is installed). And a part the simulator cannot build is
/// skipped there, saying why, while the live checker runs it.
#[test]
fn every_spec_exercises_what_it_names_and_every_derived_key_reproduces() {
let (b, _m) = boot("cswa-exercises");
let all: Vec<Value> = swx_bridge::cswa::SPECS.iter().map(|(_, t)| serde_json::from_str(t).unwrap()).collect();
let mut checked = 0;
for raw in &all {
let id = raw["id"].as_str().unwrap().to_string();
let Some(ex) = raw.get("exercises").and_then(|e| e.as_array()) else { continue };
let spec = swx_bridge::cswa::expand(raw, &all).unwrap();
let mut seen: Vec<String> = Vec::new();
if raw.get("simulatorSkips").is_some() {
let ops = swx_bridge::script::parse(&spec["script"]).unwrap();
for op in &ops {
seen.extend(swx_bridge::compat::op_variants(op, &json!({})));
}
// A face sketch's side needs the face SOLIDWORKS picked: not claimed here.
seen.retain(|v| !v.starts_with("sketch.face."));
for e in ex.iter().filter_map(|e| e.as_str()).filter(|e| !e.starts_with("sketch.face.")) {
check!(b, &format!("{id} exercises {e} (from its parsed script)"), seen.iter().any(|v| v == e), format!("{seen:?}"));
}
} else {
let r = b.call("swx_run_script", json!({"script": spec["script"]}));
check!(b, &format!("{id} builds in the simulator"), r["success"] == true, s(&r));
for st in r["steps"].as_array().cloned().unwrap_or_default() {
for v in st["result"]["proven"]["variants"].as_array().cloned().unwrap_or_default() {
seen.push(v.as_str().unwrap_or("").to_string());
}
}
for e in ex.iter().filter_map(|e| e.as_str()) {
check!(b, &format!("{id} exercises {e}"), seen.iter().any(|v| v == e), format!("{seen:?}"));
}
let _ = b.call("swx_close_doc", json!({"targetDocument": r["documentName"], "save": false}));
}
checked += 1;
}
check!(b, "the community specs and both Step 4 variants name what they exercise", checked >= 6, format!("{checked}"));
// Every community spec carries a derivation, and every derivation reproduces its key.
for raw in &all {
if raw["id"].as_str().unwrap_or("").contains("community") {
check!(b, "a community spec derives its key", raw["official"] == false && raw["derivation"].as_array().map(|d| !d.is_empty()).unwrap_or(false), s(raw));
}
}
let out = std::process::Command::new("python3")
.arg(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tools/cswa-check.py"))
.arg("--derivations")
.output();
if let Ok(o) = out {
let report: Value = serde_json::from_slice(&o.stdout).unwrap_or(Value::Null);
check!(
b,
"tools/cswa-check.py --derivations reproduces every derived key (massG, volume, centre of mass)",
o.status.success() && report.as_object().map(|m| m.len() >= 4 && m.values().all(|v| v["ok"] == true)).unwrap_or(false),
format!("{}\n{}", String::from_utf8_lossy(&o.stdout), String::from_utf8_lossy(&o.stderr))
);
}
// The part only SOLIDWORKS builds: skipped in the simulator, the reason given.
let r = b.call("swx_selftest", json!({"level": "cswa", "only": ["cswa-08-tool-block-step4", "cswa-08b-tool-block-step4-explicit"]}));
let rows = r["results"].as_array().cloned().unwrap_or_default();
let main = rows.iter().find(|x| x["name"].as_str().unwrap_or("").contains("cswa-08-tool-block-step4:")).cloned().unwrap_or(Value::Null);
check!(
b,
"Step 4 by Offset Entities is skipped in the simulator, saying why; the explicit variant runs and lands within the exam's 1 %",
main["skipped"].as_str().unwrap_or("").starts_with("skipped in the simulator: Offset Entities")
&& r["cswa"]["ran"] == 1 && r["cswa"]["passed"] == 1 && r["cswa"]["skippedInSimulator"] == 1
&& r["cswa"]["summary"] == "1 of 1 CSWA parts within tolerance (1 skipped in the simulator: only SOLIDWORKS can build them)",
s(&r["cswa"])
);
}
/// WHICH BUILD RAN (the canary gate): tools/cswa-check.py reads the INSTALLED
/// exe back through ab's read_file in ranges and hashes it, finds the manifest
/// ab installed from (a map or a list in ~/.adom/bridge-install-urls.json), and
/// names its own report (`--report auto`) — checked here against a fake ab, in
/// python3 (skipped where it is not installed).
#[test]
fn the_live_checker_records_which_build_ran() {
let script = r#"
import base64, hashlib, importlib.util, json, os, sys
spec = importlib.util.spec_from_file_location("cc", sys.argv[1]); cc = importlib.util.module_from_spec(spec); spec.loader.exec_module(cc)
blob = bytes(range(256)) * 9000
files = {"C:\\ab\\solidworks\\swx-bridge.exe": blob, "C:\\ab\\solidworks\\bridge.json": b'{"version":"9.9.9"}',
"~/.adom/bridge-install-urls.json": json.dumps({"solidworks": "https://wiki.adom.inc/api/v1/pages/solidworks-bridge/files/manifests/canary.json"}).encode()}
def fake(verb, args, timeout=300):
if verb == "bridge_info":
return {"success": True, "version": "9.9.9", "installPath": "C:\\ab\\solidworks\\", "manifestUrl": "m", "source": "cache"}
data = files.get(args.get("path"))
if data is None:
return {"success": False, "error": "no such file"}
if args.get("encoding") == "base64":
off, n = args.get("offset", 0), args.get("length", 1000000)
part = data[off:off + n]
return {"success": True, "content": base64.b64encode(part).decode(), "totalSize": len(data), "nextOffset": off + len(part), "eof": off + len(part) >= len(data)}
return {"success": True, "content": data.decode()}
cc.call = fake
cc.wiki_json = lambda url: {"sha256": "z" * 64, "version": "9.9.9", "canary": {"rc": "9.9.9-rc1"}} if url.endswith("canary.json") else None
f = cc.bridge_facts()
assert f["exeSha256"] == hashlib.sha256(blob).hexdigest(), f
assert f["bridgeJsonSha256"] == hashlib.sha256(b'{"version":"9.9.9"}').hexdigest(), f
assert f["installedFrom"].endswith("manifests/canary.json") and f["zipSha256"] == "z" * 64 and f["canary"]["rc"] == "9.9.9-rc1", f
files["~/.adom/bridge-install-urls.json"] = json.dumps([{"name": "kicad", "manifestUrl": "k"}, {"name": "solidworks", "manifestUrl": "s"}]).encode()
assert cc.installed_from() == "s"
del files["C:\\ab\\solidworks\\swx-bridge.exe"]
f = cc.bridge_facts()
assert f["exeSha256"] is None and "read_file" in f["exeWhy"], f
p = cc.report_path("auto", {"bridgeVersion": "9.9.9"}, {"versionSupport": {"year": 2026}})
assert os.path.basename(p).startswith("cswa-") and p.endswith("-sw2026-9.9.9.json") and "tools/cswa/reports" in p.replace(os.sep, "/"), p
assert cc.report_path("mine.json", {}, {}) == "mine.json"
assert cc.wiki_json("https://example.com/not-the-wiki.json") is None
print("OK")
"#;
let out = std::process::Command::new("python3")
.arg("-c")
.arg(script)
.arg(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tools/cswa-check.py"))
.output();
let Ok(o) = out else { return };
assert!(o.status.success() && String::from_utf8_lossy(&o.stdout).contains("OK"), "{}{}", String::from_utf8_lossy(&o.stdout), String::from_utf8_lossy(&o.stderr));
}