feat: named case-result load combinations with full GUI support

Snapshots the current development tree, headlined by proper load
combinations (user request): a reusable LoadCombination entity of
weighted completed static-case results (e.g. 1.2xDead + 1.6xLive).

- core: LoadCombination/LoadCombinationItem entities, Project
  integration (lookup, unique ids, reference validation)
- services: combinations.py (linear superposition + envelope),
  exported via services __init__
- commands: undoable Add/Delete/Update for combinations
- GUI: Load Combinations manager dialog, Run-dialog evaluation,
  envelope display in Results panel, Combinations tab in Table dock
- tests: unit coverage (validation, math, error paths) + integration
  superposition check vs a single factored run
This commit is contained in:
smill 2026-09-11 13:19:59 -04:00
commit f361fee969
560 changed files with 178701 additions and 0 deletions

View file

@ -0,0 +1,49 @@
"""Unit-system label table tests."""
from __future__ import annotations
import pytest
from otko.core import UnitSystem, labels_for
def test_si_m_n_labels() -> None:
lab = labels_for(UnitSystem.SI_M_N)
assert lab.length == "m"
assert lab.force == "N"
assert lab.moment == "N·m"
assert lab.stress == "Pa"
assert lab.curvature == "1/m"
def test_us_in_kip_labels() -> None:
lab = labels_for(UnitSystem.US_IN_KIP)
assert lab.length == "in"
assert lab.force == "kip"
assert lab.moment == "kip·in"
assert lab.stress == "ksi"
assert lab.curvature == "1/in"
def test_us_ft_kip_labels() -> None:
lab = labels_for(UnitSystem.US_FT_KIP)
assert lab.length == "ft"
assert lab.force == "kip"
assert lab.moment == "kip·ft"
assert lab.stress == "ksf"
assert lab.curvature == "1/ft"
def test_si_mm_n_labels() -> None:
lab = labels_for(UnitSystem.SI_MM_N)
assert lab.length == "mm"
assert lab.force == "N"
assert lab.stress == "MPa"
def test_labels_for_covers_every_unit_system() -> None:
"""Every UnitSystem enum value must have a matching label bundle."""
for us in UnitSystem:
lab = labels_for(us)
# sanity: at least length / force populated.
assert lab.length and lab.force