feat: initial otko import
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
This commit is contained in:
commit
612936a00b
540 changed files with 174136 additions and 0 deletions
175
tests/gui/test_grid_dialog.py
Normal file
175
tests/gui/test_grid_dialog.py
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
"""SAP2000-style grid dialog tests — DefineGridSystemDataDialog and friends."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.importorskip("PySide6")
|
||||
|
||||
from otko.core import ( # noqa: E402
|
||||
CoordinateGridSystem,
|
||||
CoordinateSystem,
|
||||
GridLine,
|
||||
GridSystem,
|
||||
make_grid_lines,
|
||||
)
|
||||
|
||||
|
||||
# ────────────────────────── Quick Grid Lines ──────────────────────────
|
||||
@pytest.mark.gui
|
||||
def test_quick_grid_lines_produces_ordinates(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
from otko.views.dialogs.quick_grid_lines import QuickGridLinesDialog
|
||||
dlg = QuickGridLinesDialog()
|
||||
qtbot.addWidget(dlg)
|
||||
dlg._x_n.setValue(4); dlg._x_s.setValue(3.0); dlg._x_f.setValue(0.0)
|
||||
dlg._y_n.setValue(2); dlg._y_s.setValue(4.0); dlg._y_f.setValue(0.0)
|
||||
dlg._z_n.setValue(3); dlg._z_s.setValue(3.0); dlg._z_f.setValue(-3.0)
|
||||
xs, ys, zs = dlg.ordinates()
|
||||
assert xs == [0.0, 3.0, 6.0, 9.0]
|
||||
assert ys == [0.0, 4.0]
|
||||
assert zs == [-3.0, 0.0, 3.0]
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def test_quick_grid_zero_lines_produces_empty(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
from otko.views.dialogs.quick_grid_lines import QuickGridLinesDialog
|
||||
dlg = QuickGridLinesDialog()
|
||||
qtbot.addWidget(dlg)
|
||||
dlg._x_n.setValue(0)
|
||||
dlg._y_n.setValue(0)
|
||||
dlg._z_n.setValue(0)
|
||||
xs, ys, zs = dlg.ordinates()
|
||||
assert xs == [] and ys == [] and zs == []
|
||||
|
||||
|
||||
# ────────────────────── Coord Location + Orientation ──────────────────
|
||||
@pytest.mark.gui
|
||||
def test_locate_origin_round_trip(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
from otko.views.dialogs.locate_origin import (
|
||||
CoordSystemLocationOrientationDialog,
|
||||
)
|
||||
dlg = CoordSystemLocationOrientationDialog(
|
||||
origin=(1.5, -2.0, 3.0),
|
||||
rotation_deg=(0.0, 0.0, 45.0),
|
||||
)
|
||||
qtbot.addWidget(dlg)
|
||||
origin, rot = dlg.location()
|
||||
assert origin == pytest.approx((1.5, -2.0, 3.0))
|
||||
assert rot == pytest.approx((0.0, 0.0, 45.0))
|
||||
|
||||
|
||||
# ────────────────────── Define Grid System Data form ──────────────────
|
||||
@pytest.mark.gui
|
||||
def test_define_grid_data_round_trip(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
"""Loading an existing system and reading .system() must round-trip."""
|
||||
from otko.views.dialogs.define_grid_data import (
|
||||
DefineGridSystemDataDialog,
|
||||
)
|
||||
cs = CoordinateGridSystem(
|
||||
name="Floor2",
|
||||
coord=CoordinateSystem(origin=(0, 0, 3.5)),
|
||||
grid=GridSystem(
|
||||
x_grid_lines=make_grid_lines("X", [0.0, 4.0, 8.0]),
|
||||
y_grid_lines=make_grid_lines("Y", [0.0, 6.0]),
|
||||
z_grid_lines=make_grid_lines("Z", [0.0]),
|
||||
hide_all=False,
|
||||
glue_to_grid=True,
|
||||
bubble_size=18,
|
||||
),
|
||||
)
|
||||
dlg = DefineGridSystemDataDialog(existing=cs)
|
||||
qtbot.addWidget(dlg)
|
||||
|
||||
result = dlg.system()
|
||||
assert result.name == "Floor2"
|
||||
assert result.coord.origin == (0.0, 0.0, 3.5)
|
||||
assert result.grid.x_lines == [0.0, 4.0, 8.0]
|
||||
assert result.grid.y_lines == [0.0, 6.0]
|
||||
assert result.grid.z_lines == [0.0]
|
||||
assert result.grid.glue_to_grid is True
|
||||
assert result.grid.bubble_size == 18
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def test_define_grid_data_spacing_mode_conversion(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
"""Switching to Spacing mode and back must preserve ordinate values."""
|
||||
from otko.views.dialogs.define_grid_data import (
|
||||
DefineGridSystemDataDialog,
|
||||
)
|
||||
cs = CoordinateGridSystem(
|
||||
name="Test",
|
||||
grid=GridSystem(x_grid_lines=make_grid_lines("X", [0.0, 3.0, 6.0, 10.0])),
|
||||
)
|
||||
dlg = DefineGridSystemDataDialog(existing=cs)
|
||||
qtbot.addWidget(dlg)
|
||||
|
||||
# Toggle to Spacing mode.
|
||||
dlg._rb_spacing.setChecked(True)
|
||||
# Then back to Ordinates.
|
||||
dlg._rb_ordinates.setChecked(True)
|
||||
result = dlg.system()
|
||||
assert result.grid.x_lines == pytest.approx([0.0, 3.0, 6.0, 10.0])
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def test_define_grid_data_global_name_locked(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
"""For the Global system, the Name field is disabled."""
|
||||
from otko.views.dialogs.define_grid_data import (
|
||||
DefineGridSystemDataDialog,
|
||||
)
|
||||
dlg = DefineGridSystemDataDialog(is_global=True)
|
||||
qtbot.addWidget(dlg)
|
||||
assert dlg._name_edit.text() == "Global"
|
||||
assert not dlg._name_edit.isEnabled()
|
||||
assert not dlg._btn_locate.isEnabled()
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def test_define_grid_data_add_and_delete_row(qtbot) -> None: # type: ignore[no-untyped-def]
|
||||
"""Add Row / Delete Row buttons modify the X tab table directly."""
|
||||
from otko.views.dialogs.define_grid_data import (
|
||||
DefineGridSystemDataDialog,
|
||||
)
|
||||
dlg = DefineGridSystemDataDialog()
|
||||
qtbot.addWidget(dlg)
|
||||
# Start with empty X table.
|
||||
assert dlg._tab_x._table.rowCount() == 0
|
||||
dlg._tab_x._on_add_row()
|
||||
dlg._tab_x._on_add_row()
|
||||
assert dlg._tab_x._table.rowCount() == 2
|
||||
dlg._tab_x._table.selectRow(0)
|
||||
dlg._tab_x._on_delete_row()
|
||||
assert dlg._tab_x._table.rowCount() == 1
|
||||
|
||||
|
||||
# ────────────────────── GridLine + migration tests ────────────────────
|
||||
def test_grid_line_defaults() -> None:
|
||||
ln = GridLine(id="A", ordinate=3.0)
|
||||
assert ln.id == "A"
|
||||
assert ln.line_type == "Primary"
|
||||
assert ln.visible is True
|
||||
assert ln.bubble_loc == "End"
|
||||
assert ln.color == "#808080"
|
||||
|
||||
|
||||
def test_grid_system_migrates_flat_x_lines() -> None:
|
||||
"""Legacy constructor with list[float] must convert to GridLine records."""
|
||||
g = GridSystem(x_lines=[0.0, 2.5, 5.0])
|
||||
assert len(g.x_grid_lines) == 3
|
||||
ids = [ln.id for ln in g.x_grid_lines]
|
||||
assert ids == ["X1", "X2", "X3"]
|
||||
assert g.x_lines == [0.0, 2.5, 5.0]
|
||||
|
||||
|
||||
def test_grid_system_hide_all_and_glue_persist() -> None:
|
||||
g = GridSystem(
|
||||
x_grid_lines=make_grid_lines("X", [0.0, 1.0]),
|
||||
hide_all=True,
|
||||
glue_to_grid=True,
|
||||
bubble_size=24,
|
||||
)
|
||||
d = g.model_dump()
|
||||
r = GridSystem.model_validate(d)
|
||||
assert r.hide_all is True
|
||||
assert r.glue_to_grid is True
|
||||
assert r.bubble_size == 24
|
||||
Loading…
Reference in a new issue