Files
JEREMY 382680d8e8 fix(skills): refresh Boolean checking facts that fail on current release (#1835) (#2093)
* fix(skills): refresh Boolean checking facts that fail on current release (#1835)

* fix(skills): restore warning coverage in test_run and use present tense in Boolean facts

* fix(skills): the slot keeps its side at zero since the solver takes the shortest step

The upstream solver now takes the shortest step that fits (#2060), so the slot
that other constraints also held slides to the origin when the distance reaches
0 and keeps the side it was drawn on when the value comes back. It no longer
comes back mirrored, so the trap and its test state the current behaviour.

---------

Co-authored-by: jeremymiribung-blip <jeremymiribung-blip@users.noreply.github.com>
2026-10-21 00:41:45 +00:00

130 lines
6.0 KiB
Python

import json
import subprocess
import sys
from pathlib import Path
import pytest
SCRIPTS = Path(__file__).parents[1]
sys.path.insert(0, str(SCRIPTS))
import run # noqa: E402
BOX = [{"command": "solid.box", "params": {"length": 10, "width": 10, "height": 10, "body_name": "Cube"}}]
def report(tmp_path, commands, *args):
script = tmp_path / "script.json"
script.write_text(json.dumps({"commands": commands}))
return subprocess.run(
[sys.executable, SCRIPTS / "run.py", script, *args], capture_output=True, text=True
)
def test_reports_bodies(tmp_path):
result = report(tmp_path, BOX)
assert result.returncode == 0, result.stderr
assert "BODY Cube: volume 1000 mm3, area 600 mm2, bbox (0, 0, 0)..(10, 10, 10), com (5, 5, 5)" in result.stdout
def test_flags_underconstrained_sketch(tmp_path):
result = report(tmp_path, [
{"command": "sketch.create", "params": {"plane": "XY", "name": "Loose"}},
{"command": "sketch.circle.center", "params": {"center": [5, 5], "radius": 5}},
{"command": "sketch.finish", "params": {}},
])
assert result.returncode == 0, result.stderr
assert 'SKETCH "Loose": dof 3, solved' in result.stdout
def test_reports_step_warnings(tmp_path):
result = report(tmp_path, [
{"command": "parameters.add", "params": {"name": "h", "expression": "5 mm"}},
{"command": "solid.box", "params": {"length": 91, "width": 62, "height": 30, "center": [0, 0, 15], "body_name": "Case"}},
{"command": "solid.fillet", "params": {"edges": [[45.5, 31, 15], [-45.5, 31, 15], [45.5, -31, 15], [-45.5, -31, 15]], "radius": 3}},
{"command": "solid.shell", "params": {"faces": [[0, 0, 30]], "thickness": 2}},
{"command": "solid.fillet", "params": {"edges": [[0, -31, 30]], "radius": 1}},
{"command": "solid.cylinder", "params": {"diameter": "6 mm", "height": "h", "base": [-39, -24.5, 2], "operation": "join", "targets": ["Case"], "name": "Standoff"}},
{"command": "solid.cylinder", "params": {"diameter": "2.5 mm", "height": "h", "base": [-39, -24.5, 2], "operation": "cut", "targets": ["Case"], "name": "Pilot"}},
])
assert result.returncode == 0, result.stderr
assert 'WARN "Pilot": Boolean retry' in result.stdout
def test_fails_on_a_bad_step(tmp_path):
result = report(tmp_path, [{"command": "solid.box", "params": {"width": 10}}])
assert result.returncode == 1
assert result.stdout.startswith("FAIL") and "step 1 (solid.box)" in result.stdout
def test_applies_a_script_to_a_saved_design(tmp_path):
design = tmp_path / "cube.json"
built = report(tmp_path, [
{"command": "parameters.add", "params": {"name": "size", "expression": "10 mm"}},
{"command": "solid.box", "params": {"length": "size", "width": "size", "height": "size", "body_name": "Cube"}},
], "--save", design)
assert built.returncode == 0, built.stderr
changed = report(tmp_path, [
{"command": "parameters.change", "params": {"name": "size", "expression": "20 mm"}},
], "--in", design)
assert changed.returncode == 0, changed.stderr
assert "BODY Cube: volume 8000 mm3" in changed.stdout
def test_execute_returns_the_final_inspection():
inspection = run.execute(BOX)
assert [b["name"] for b in inspection["bodies"]] == ["Cube"]
def test_execute_raises_on_failure():
with pytest.raises(run.SolidCraftError, match="step 1"):
run.execute([{"command": "solid.box", "params": {"width": 10}}])
@pytest.fixture
def flush_design(tmp_path):
"""A shelled case with a joined standoff and a cut pilot hole; Pilot warns tool displacement."""
design = tmp_path / "standoff.json"
built = report(tmp_path, [
{"command": "parameters.add", "params": {"name": "h", "expression": "5 mm"}},
{"command": "solid.box", "params": {"length": 91, "width": 62, "height": 30, "center": [0, 0, 15], "body_name": "Case"}},
{"command": "solid.fillet", "params": {"edges": [[45.5, 31, 15], [-45.5, 31, 15], [45.5, -31, 15], [-45.5, -31, 15]], "radius": 3}},
{"command": "solid.shell", "params": {"faces": [[0, 0, 30]], "thickness": 2}},
{"command": "solid.fillet", "params": {"edges": [[0, -31, 30]], "radius": 1}},
{"command": "solid.cylinder", "params": {"diameter": "6 mm", "height": "h", "base": [-39, -24.5, 2], "operation": "join", "targets": ["Case"], "name": "Standoff"}},
{"command": "solid.cylinder", "params": {"diameter": "2.5 mm", "height": "h", "base": [-39, -24.5, 2], "operation": "cut", "targets": ["Case"], "name": "Pilot"}},
], "--save", design)
assert built.returncode == 0, built.stdout + built.stderr
return design
def depth(value: str) -> dict:
return {"command": "parameters.change", "params": {"name": "h", "expression": value}}
def test_reports_warnings_after_a_parameter_change(tmp_path, flush_design):
flush = report(tmp_path, [depth("7 mm")], "--in", flush_design)
assert flush.returncode == 0, flush.stderr
assert 'WARN "Pilot": Boolean retry' in flush.stdout
def test_reports_every_inspection_in_the_script(tmp_path, flush_design):
walk = report(tmp_path, [depth("7 mm"), {"command": "document.inspect", "params": {"measure": True}},
depth("5 mm")], "--in", flush_design)
lines = walk.stdout.splitlines()
assert any(line.startswith('step 2 WARN "Pilot": Boolean retry') for line in lines)
assert any(line.startswith("step 2 BODY Case: volume") for line in lines)
assert any(line.startswith('WARN "Pilot": Boolean retry') for line in lines)
def test_reports_bodies_inspected_without_measurements(tmp_path):
result = report(tmp_path, [*BOX, {"command": "document.inspect", "params": {}}])
assert "step 2 BODY Cube\n" in result.stdout
assert "BODY Cube: volume 1000 mm3" in result.stdout
def test_says_so_when_there_is_nothing_to_report(tmp_path):
result = report(tmp_path, [{"command": "parameters.add", "params": {"name": "size", "expression": "10 mm"}}])
assert result.returncode == 0, result.stderr
assert result.stdout.strip() == "no bodies"