85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from step_editor.relation_formulas import ( # noqa: E402
|
|
RelationFormulaError,
|
|
Vector3,
|
|
evaluate_relation_formula,
|
|
parse_relation_formula,
|
|
validate_relation_formula_graph,
|
|
)
|
|
|
|
|
|
def _parse_many(texts: list[str]):
|
|
return [parse_relation_formula(text) for text in texts]
|
|
|
|
|
|
def _assert_ok(texts: list[str]) -> None:
|
|
validate_relation_formula_graph(_parse_many(texts))
|
|
|
|
|
|
def _assert_fails(texts: list[str], expected_fragment: str) -> None:
|
|
try:
|
|
validate_relation_formula_graph(_parse_many(texts))
|
|
except RelationFormulaError as exc:
|
|
message = str(exc)
|
|
if expected_fragment not in message:
|
|
raise AssertionError(f"expected {expected_fragment!r} in error message, got {message!r}") from exc
|
|
return
|
|
raise AssertionError(f"expected relation formulas to fail: {texts!r}")
|
|
|
|
|
|
def _assert_value(text: str, expected: object, values: dict[str, object] | None = None) -> None:
|
|
formula = parse_relation_formula(text)
|
|
values = dict(values or {})
|
|
value = evaluate_relation_formula(formula, lambda ref: values[ref.token])
|
|
if isinstance(value, Vector3):
|
|
actual = tuple(value.values)
|
|
expected_tuple = tuple(expected) # type: ignore[arg-type]
|
|
if len(actual) != len(expected_tuple) or any(abs(float(left) - float(right)) > 1.0e-12 for left, right in zip(actual, expected_tuple)):
|
|
raise AssertionError(f"expected {expected_tuple!r}, got {actual!r} for {text!r}")
|
|
return
|
|
if abs(float(value) - float(expected)) > 1.0e-12:
|
|
raise AssertionError(f"expected {expected!r}, got {value!r} for {text!r}")
|
|
|
|
|
|
def main() -> int:
|
|
_assert_ok(["Face87.直径 = Face87.半径 + 0.1"])
|
|
_assert_ok(["Face87.位置 = Face85.位置 + (0, 0, -3.5)"])
|
|
_assert_ok(["Face85.直径 = Face87.半径", "Face11.直径 = Face85.半径"])
|
|
_assert_ok(["Face87.直径 = 10mm"])
|
|
_assert_ok(["Face87.直径 = 1 cm + 2mm"])
|
|
_assert_value("Face87.直径 = 1cm + 2毫米", 12.0)
|
|
_assert_value("Face87.直径 = .5m / 10", 50.0)
|
|
_assert_value(
|
|
"Face87.位置 = Face85.位置 + (0mm, 1cm, -0.002m)",
|
|
(1.0, 12.0, 1.0),
|
|
{"Face85.位置": (1.0, 2.0, 3.0)},
|
|
)
|
|
|
|
_assert_fails(["Face87.直径 = Face87.直径 + 0.1"], "不能引用自身")
|
|
_assert_fails(["Face85.直径 = Face87.半径", "Face85.直径 = Face11.半径"], "同一目标参数")
|
|
_assert_fails(["Face85.直径 = Face87.直径", "Face87.直径 = Face85.直径"], "循环依赖")
|
|
_assert_fails(
|
|
[
|
|
"Face1.位置 = Face2.位置",
|
|
"Face2.位置 = Face3.位置",
|
|
"Face3.位置 = Face1.位置",
|
|
],
|
|
"循环依赖",
|
|
)
|
|
|
|
print("relation formula rules ok")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|