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
99 lines
3 KiB
Python
99 lines
3 KiB
Python
"""GUI tests for the Material Tester dialog."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
pytest.importorskip("PySide6")
|
|
pytest.importorskip("openseespy.opensees")
|
|
|
|
from otko.core import ElasticUniaxial
|
|
from otko.viewmodels import ProjectViewModel
|
|
from otko.views.dialogs.material_tester import MaterialTesterDialog
|
|
|
|
|
|
def _make_vm() -> ProjectViewModel:
|
|
"""View-model with one elastic uniaxial material to probe."""
|
|
vm = ProjectViewModel()
|
|
vm.new_project()
|
|
assert vm.project is not None
|
|
vm.project.materials.append(ElasticUniaxial(id=1, name="TestMat", E=200e9))
|
|
return vm
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_monotonic_run_plots_service_result(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
vm = _make_vm()
|
|
dlg = MaterialTesterDialog(vm)
|
|
qtbot.addWidget(dlg)
|
|
|
|
dlg._comp_spin.setValue(-0.005)
|
|
dlg._tens_spin.setValue(0.005)
|
|
dlg._steps_spin.setValue(5)
|
|
|
|
protocol = dlg.build_protocol()
|
|
assert protocol.kind == "monotonic"
|
|
|
|
result = dlg.run_test()
|
|
assert result is not None
|
|
assert len(result.strain) == 10 # 2 branches x 5 steps
|
|
assert len(result.stress) == len(result.strain)
|
|
assert dlg.last_result is result
|
|
|
|
# NOTE: getOriginalDataset, not getData — pyqtgraph >= 0.14 clips the
|
|
# *display* dataset to +/- dynamicRangeLimit (1e6) x view height, and
|
|
# the view never autoranges in a hidden (headless) widget.
|
|
x, y = dlg._curve.getOriginalDataset()
|
|
assert list(x) == pytest.approx(result.strain)
|
|
assert list(y) == pytest.approx(result.stress)
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_cyclic_protocol_builds_segment_and_runs(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
vm = _make_vm()
|
|
dlg = MaterialTesterDialog(vm)
|
|
qtbot.addWidget(dlg)
|
|
|
|
assert not dlg._cycles_spin.isEnabled()
|
|
dlg._kind_cb.setCurrentIndex(1)
|
|
assert dlg._cycles_spin.isEnabled()
|
|
|
|
dlg._comp_spin.setValue(-0.004)
|
|
dlg._tens_spin.setValue(0.004)
|
|
dlg._steps_spin.setValue(4)
|
|
dlg._cycles_spin.setValue(2)
|
|
|
|
protocol = dlg.build_protocol()
|
|
assert protocol.kind == "cyclic"
|
|
assert protocol.cycles is not None and len(protocol.cycles) == 1
|
|
assert protocol.cycles[0].n_cycles == 2
|
|
|
|
result = dlg.run_test()
|
|
assert result is not None
|
|
assert len(result.strain) == 2 * 3 * 4 # cycles x branches x steps
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_cyclic_without_tensile_peak_shows_message(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
vm = _make_vm()
|
|
dlg = MaterialTesterDialog(vm)
|
|
qtbot.addWidget(dlg)
|
|
|
|
dlg._kind_cb.setCurrentIndex(1)
|
|
dlg._tens_spin.setValue(0.0)
|
|
|
|
assert dlg.run_test() is None
|
|
assert "tensile" in dlg._message.text().lower()
|
|
assert dlg.last_result is None
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_empty_project_disables_run(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
vm = ProjectViewModel()
|
|
vm.new_project()
|
|
dlg = MaterialTesterDialog(vm)
|
|
qtbot.addWidget(dlg)
|
|
|
|
assert not dlg._run_btn.isEnabled()
|
|
assert dlg.selected_material() is None
|
|
assert dlg.run_test() is None
|