forked from 1b-agent/fieldcraft-upstream
mesh: relax nodes by CAD face; params docs match their forms (#471)
mesh.node.relax takes faces: [{body, face}] (every node on those B-rep
faces and the nodes of the elements touching them, sliding on the faces)
and elements in its form; the undocumented-by-form set is dropped.
A schema test checks every top-level key a params doc names is accepted,
which also found mesh.hex.extrude normal, mesh.hex.project max_arc_angle
and mesh.plan.apply name missing from their forms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
4bb2134b47
commit
3ee622f62a
4 files changed
+184
-11
No files matched your search
@@ -1560,4 +1560,54 @@ mod tests {
|
||||
let e = s.execute("results.contour", &json!({"field": "displacement", "deformed": true})).unwrap_err().to_string();
|
||||
assert!(e.contains("`deformed`") && e.contains("field"), "{e}");
|
||||
}
|
||||
|
||||
/// The top-level keys a params doc names (`"key":` and `"key"?:` directly inside its
|
||||
/// leading `{…}`; keys of nested objects and of the reply described after it are not).
|
||||
fn doc_keys(doc: &str) -> Vec<&str> {
|
||||
let mut keys = Vec::new();
|
||||
let mut depth = 0usize;
|
||||
let mut chars = doc.char_indices();
|
||||
while let Some((i, c)) = chars.next() {
|
||||
match c {
|
||||
'{' | '[' => depth += 1,
|
||||
'}' | ']' => {
|
||||
depth = depth.saturating_sub(1);
|
||||
if depth == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
'"' => {
|
||||
let rest = &doc[i + 1..];
|
||||
let Some(end) = rest.find('"') else { break };
|
||||
let word = &rest[..end];
|
||||
let tail = &rest[end + 1..];
|
||||
if depth == 1 && (tail.starts_with(':') || tail.starts_with("?:")) && !word.is_empty() {
|
||||
keys.push(word);
|
||||
}
|
||||
for _ in 0..word.chars().count() + 1 {
|
||||
chars.next();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
keys
|
||||
}
|
||||
|
||||
/// A command's params doc names only parameters its form describes, so a documented
|
||||
/// parameter is never refused as unknown (#471: `mesh.node.relax` listed `set`).
|
||||
#[test]
|
||||
fn every_documented_parameter_is_accepted() {
|
||||
let mut wrong = Vec::new();
|
||||
for spec in crate::commands() {
|
||||
let Some(form) = spec.form else { continue };
|
||||
let keys = accepted_keys(form, &Value::Null);
|
||||
for key in doc_keys(spec.params) {
|
||||
if !keys.contains(&key) {
|
||||
wrong.push(format!("{}: `{key}`", spec.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
assert!(wrong.is_empty(), "documented but not in the form:\n{}", wrong.join("\n"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user