app
SOLIDWORKS Bridge
Public Made by Adomby adom
Launch, model and quit SOLIDWORKS from any Adom container. Nothing is ever lost.
main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
//! HIDEFILEEXT (0.10.10). MEASURED 2026-10-15 on Michael's SOLIDWORKS 2021
//! (COM 29.5.1, Windows 11): swx_selftest {level:"write"} passed every
//! modelling check and failed SIX verbs — swx_design_info, swx_get_parameters,
//! swx_set_parameter, swx_export_step, swx_save, swx_close_doc — all
//! `document_not_open: no open document is titled 'Part14-….SLDPRT'`. With
//! Windows' "Hide extensions for known file types" ON (the Windows default),
//! SOLIDWORKS titles that document `Part14-…`; the self-test addressed it by a
//! title WITH the extension, and the close missed too, leaving it open.
//!
//! `mock-hide-file-ext` makes the simulator title documents the way that
//! machine did. Everything here runs in the simulator.
mod common;
use common::{Bridge, TempDir};
use serde_json::{json, Value};
fn s(v: &Value) -> String {
serde_json::to_string_pretty(v).unwrap_or_default()
}
fn boot(tag: &str, hide: bool) -> (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())]);
if hide {
std::fs::write(b.scratch.join("mock-hide-file-ext"), "1").unwrap();
}
std::fs::write(b.scratch.join("mock-revision"), "29.5.1").unwrap();
b.call("swx_start", json!({}));
(b, machine)
}
#[test]
fn the_selftest_passes_with_extensions_hidden_and_shown_and_leaves_nothing_open() {
for hide in [true, false] {
let (b, _m) = boot(if hide { "hfe-selftest-hidden" } else { "hfe-selftest-shown" }, hide);
let before = b.call("swx_docs", json!({}))["count"].clone();
let r = b.call("swx_selftest", json!({"level": "write"}));
let rows = r["results"].as_array().cloned().unwrap_or_default();
let failed: Vec<&Value> = rows.iter().filter(|x| x["pass"] == false).collect();
check!(
b,
&format!("swx_selftest write, HideFileExt {}: nothing fails (Michael's 6 failures were one bug)", if hide { "ON" } else { "off" }),
r["success"] == true && failed.is_empty(),
format!("{}\nFAILED: {failed:?}", s(&r["summary"]))
);
for verb in ["swx_design_info", "swx_get_parameters", "swx_set_parameter", "swx_export_step", "swx_save", "swx_close_doc"] {
check!(
b,
&format!("{verb} on the scratch part passes (HideFileExt {hide})"),
rows.iter().any(|x| x["verb"] == verb && x["pass"] == true),
s(&Value::Array(rows.clone()))
);
}
check!(
b,
"the ownership check is numbered T23, so the rows run T01-T32 without a gap",
rows.iter().any(|x| x["name"].as_str().unwrap_or("").starts_with("T23 ")),
""
);
check!(b, "every scratch part was CLOSED", b.call("swx_docs", json!({}))["count"] == before && r.get("documentsLeftOpen").is_none(), s(&r));
check!(b, "...and struck off the orphan record", b.call("swx_status", json!({}))["orphanedSelftestDocuments"].is_null(), "");
check!(
b,
"the reply says how to call it without being cut off",
r["_timeoutHint"].as_str().unwrap_or("").starts_with("call this with responseMode:\"stream\" or \"job\""),
s(&r["_timeoutHint"])
);
}
}
#[test]
fn a_title_with_or_without_the_extension_names_the_same_document() {
let (b, _m) = boot("hfe-titles", true);
let made = b.call("swx_new_document", json!({"type": "part"}));
let title = made["created"]["title"].as_str().unwrap_or("").to_string();
let path = made["documentIdentity"]["path"].as_str().unwrap_or("").to_string();
check!(
b,
"swx_new_document reports the title SOLIDWORKS shows (no extension with HideFileExt ON) AND the path",
!title.is_empty() && !title.to_ascii_lowercase().ends_with(".sldprt") && path.to_ascii_lowercase().ends_with(".sldprt"),
s(&made)
);
let docs = b.call("swx_docs", json!({}));
check!(b, "swx_docs lists it under that same title", docs.to_string().contains(&format!("\"{title}\"")), s(&docs));
let with_ext = format!("{title}.SLDPRT");
let di = b.call("swx_design_info", json!({"targetDocument": with_ext}));
check!(b, "swx_design_info finds it by the title WITH the extension", di["success"] != false, s(&di));
let lower = format!("{title}.sldprt");
let gp = b.call("swx_get_parameters", json!({"targetDocument": lower}));
check!(b, "...and with a lower-case extension", gp["success"] != false, s(&gp));
let act = b.call("swx_activate_document", json!({"name": with_ext}));
check!(b, "swx_activate_document takes either spelling", act["success"] != false, s(&act));
let close = b.call("swx_close_doc", json!({"targetDocument": with_ext, "save": false}));
check!(b, "swx_close_doc closes it by the title with the extension", close["success"] != false, s(&close));
check!(b, "...and it is gone", b.call("swx_docs", json!({}))["count"] == 0, "");
}
#[test]
fn a_cut_off_selftests_parts_are_reported_by_status_and_closed_by_the_next_run() {
let (b, _m) = boot("hfe-orphans", true);
// What a cut-off run leaves: a part it made and recorded, still open.
let made = b.call("swx_new_document", json!({"type": "part"}));
let path = made["documentIdentity"]["path"].as_str().unwrap_or("").to_string();
std::fs::write(b.scratch.join("selftest-docs.json"), json!([{"key": path, "at": "2026-10-15T00:00:00Z"}]).to_string()).unwrap();
let st = b.call("swx_status", json!({}));
check!(
b,
"swx_status REPORTS the orphan (and closes nothing: a run may be in progress)",
st["orphanedSelftestDocuments"]["documents"][0]["key"] == path.as_str() && b.call("swx_docs", json!({}))["count"] == 1,
s(&st["orphanedSelftestDocuments"])
);
let r = b.call("swx_selftest", json!({"level": "write", "only": ["T01"]}));
let rows = r["results"].as_array().cloned().unwrap_or_default();
check!(
b,
"the next swx_selftest closes it first, and says so",
rows.iter().any(|x| x["name"] == "close what a cut-off self-test left open" && x["pass"] == true),
s(&Value::Array(rows.clone()))
);
check!(b, "nothing is left open, nothing left recorded", b.call("swx_docs", json!({}))["count"] == 0
&& b.call("swx_status", json!({}))["orphanedSelftestDocuments"].is_null(), "");
}