DEM_MCM_App / tests /test_study.py
cao-app-sync
deploy: sync FEM solver from CAD repo (2026-09-10T11:59:07Z)
87e485b
Raw History Blame Contribute Delete
2.62 kB
"""Validation tests for the study JSON protocol (v1)."""
import json
import pytest
from fem_solver.errors import FemSolverError
from fem_solver.study import parse_study
def valid_study() -> dict:
return {
"version": 1,
"material": {"name": "Steel", "youngModulus": 210000, "poissonRatio": 0.3, "density": 7.85e-9},
"mesh": {"targetSize": 2.5},
"fixtures": [{"type": "fixed", "patch": {"vertices": [[0, 0, 0], [0, 10, 10]]}}],
"loads": [
{"type": "force", "value": [0, -1000, 0], "patch": {"vertices": [[100, 0, 0], [100, 10, 10]]}}
],
}
def test_valid_study_is_normalized():
parsed = parse_study(__import__("json").dumps(valid_study()))
assert parsed["material"]["youngModulus"] == 210000
assert parsed["mesh"]["targetSize"] == 2.5
assert parsed["fixtures"][0]["type"] == "fixed"
assert parsed["loads"][0]["type"] == "force"
def test_defaults_are_applied():
study = valid_study()
del study["mesh"]
study["material"].pop("density")
parsed = parse_study(__import__("json").dumps(study))
assert parsed["mesh"]["targetSize"] == 2.5
assert parsed["material"]["density"] == 7.85e-9
@pytest.mark.parametrize(
"mutation,stage",
[
(lambda s: s.update(material=None), "study"),
(lambda s: s["material"].update(youngModulus=-1), "study"),
(lambda s: s["material"].update(poissonRatio=0.5), "study"),
(lambda s: s.update(fixtures=[]), "study"),
(lambda s: s.update(loads=[]), "study"),
(lambda s: s["loads"][0].update(value=[0, None, 0]), "study"),
(lambda s: s["fixtures"][0].update(patch={"vertices": []}), "study"),
(lambda s: s.update(version=99), "study"),
],
)
def test_invalid_studies_are_rejected(mutation, stage):
study = valid_study()
mutation(study)
with pytest.raises(FemSolverError) as excinfo:
parse_study(__import__("json").dumps(study))
assert excinfo.value.stage == stage
def test_pressure_load_requires_area_and_normal():
study = valid_study()
study["loads"] = [{"type": "pressure", "value": 0.1, "patch": {"vertices": [[0, 0, 0]]}}]
with pytest.raises(FemSolverError):
parse_study(__import__("json").dumps(study))
study["loads"][0]["patch"].update(area=120.0, normal=[0, 1, 0])
parsed = parse_study(__import__("json").dumps(study))
assert parsed["loads"][0]["patch"]["area"] == 120.0
def test_malformed_json_is_rejected():
with pytest.raises(FemSolverError) as excinfo:
parse_study("{not json")
assert excinfo.value.stage == "study"