diff --git a/tests/test_bin_phase_env.py b/tests/test_bin_phase_env.py index e41b441..458cbfd 100644 --- a/tests/test_bin_phase_env.py +++ b/tests/test_bin_phase_env.py @@ -114,10 +114,13 @@ def test_plot_requires_different_compounds(self, mock_warning): self.assertIn("select two different compounds", mock_warning.call_args[0][2]) + @patch('platform.system') @patch('python.utils.Bin_Phase_env.os.path.exists') @patch('python.utils.Bin_Phase_env.shutil.which') @patch('python.utils.Bin_Phase_env.os.environ.get') - def test_get_omc_path_resolution(self, mock_env, mock_which, mock_exists): + def test_get_omc_path_resolution(self, mock_env, mock_which, mock_exists, mock_system): + """Verify OMC path resolution without requiring OpenModelica installation.""" + mock_system.return_value = 'Linux' """Verify OMC path resolution without requiring OpenModelica installation.""" mock_env.return_value = None mock_exists.side_effect = lambda path: path == '/usr/bin/omc' diff --git a/tests/test_dock_widget_compound_separator.py b/tests/test_dock_widget_compound_separator.py new file mode 100644 index 0000000..24236c7 --- /dev/null +++ b/tests/test_dock_widget_compound_separator.py @@ -0,0 +1,77 @@ +import os +import sys +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = MagicMock() +mock_container = MagicMock() +mock_graphics.lst = [] + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetCompoundSeparator import DockWidgetCompoundSeparator + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockCompoundSeparatorObj: + def __init__(self, name="CompSep1"): + self.name = name + self.variables = { + "comp_list": ["Water", "Ethanol"], + "sep_stream": {"name": "Separation Stream", "value": "Top"}, + "split_ratio": {"name": "Split Ratio", "value": [0.9, 0.1]} + } + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def comp_sep_widget(): + obj = MockCompoundSeparatorObj() + container = MockContainerInstance() + widget = DockWidgetCompoundSeparator("CompSep1", "CompoundSeparator", obj, container) + return widget, obj, container + + +def test_dock_widget_compound_separator_init(comp_sep_widget): + widget, obj, _ = comp_sep_widget + assert widget.name == "CompSep1" + assert widget.type == "CompoundSeparator" + assert widget.obj == obj + assert widget.windowTitle() == "CompSep1" + + +def test_dock_widget_compound_separator_param_submission(comp_sep_widget): + widget, obj, _ = comp_sep_widget + if hasattr(widget, 'param'): + widget.param() + assert obj.param_setter.called or hasattr(widget, 'dict') \ No newline at end of file diff --git a/tests/test_dock_widget_compressor_expander.py b/tests/test_dock_widget_compressor_expander.py new file mode 100644 index 0000000..84bfaf6 --- /dev/null +++ b/tests/test_dock_widget_compressor_expander.py @@ -0,0 +1,96 @@ +import os +import sys +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = MagicMock() +mock_container = MagicMock() +mock_graphics.lst = [] + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetCompressorExpander import DockWidgetCompressorExpander + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockCompressorObj: + def __init__(self, name="Compressor1"): + self.name = name + self.type = "Compressor" + self.modes_list = ["Outlet Pressure", "Pressure Ratio"] + self.variables = { + "Outlet Pressure": {"name": "Outlet Pressure", "unit": "Pa"}, + "Pressure Ratio": {"name": "Pressure Ratio", "unit": ""}, + "Pout": {"name": "Outlet Pressure", "unit": "Pa"}, + "eff": {"name": "Adiabatic Efficiency", "unit": "%"} + } + self.param_setter = MagicMock() + + def param_getter(self, mode="Outlet Pressure"): + return {"Pout": "200000", "eff": "75"} + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def comp_widget(): + obj = MockCompressorObj() + container = MockContainerInstance() + widget = DockWidgetCompressorExpander("Compressor1", "Compressor", obj, container) + return widget, obj, container + + +def test_dock_widget_compressor_initialization(comp_widget): + widget, obj, _ = comp_widget + assert widget.name == "Compressor1" + assert widget.type == "Compressor" + assert widget.obj == obj + assert widget.windowTitle() == "Compressor1" + assert widget.comboBox.count() >= 2 + + +def test_dock_widget_compressor_mode_selection(comp_widget): + widget, _, _ = comp_widget + widget.comboBox.setCurrentIndex(1) + assert len(widget.input_dict) > 0 + + +def test_dock_widget_compressor_param_submission(comp_widget): + widget, obj, _ = comp_widget + if "Pout" in widget.input_dict and hasattr(widget.input_dict["Pout"], "setText"): + widget.input_dict["Pout"].setText("300000") + if "eff" in widget.input_dict and hasattr(widget.input_dict["eff"], "setText"): + widget.input_dict["eff"].setText("80") + + widget.param() + obj.param_setter.assert_called_once() + assert widget.dict.get("Pout") == "300000" + assert widget.dict.get("eff") == "80" \ No newline at end of file diff --git a/tests/test_dock_widget_distillation_column.py b/tests/test_dock_widget_distillation_column.py new file mode 100644 index 0000000..0f359bf --- /dev/null +++ b/tests/test_dock_widget_distillation_column.py @@ -0,0 +1,79 @@ +import os +import sys +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = MagicMock() +mock_container = MagicMock() +mock_graphics.lst = [] + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetDistillationColumn import DockWidgetDistillationColumn + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockDistillationColumnObj: + def __init__(self, name="DistCol1"): + self.name = name + self.variables = { + "thermo_package": {"name": "Thermo Package", "value": "Raoults Law"}, + "stages": {"name": "Number of Stages", "value": "10", "unit": ""}, + "condenser_type": {"name": "Condenser Type", "value": "Total"}, + "reflux_ratio": {"name": "Reflux Ratio", "value": "2.0", "unit": ""} + } + self.comp_list = ["Ethanol", "Water"] + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def dist_col_widget(): + obj = MockDistillationColumnObj() + container = MockContainerInstance() + widget = DockWidgetDistillationColumn("DistCol1", "DistillationColumn", obj, container) + return widget, obj, container + + +def test_dock_widget_distillation_column_init(dist_col_widget): + widget, obj, _ = dist_col_widget + assert widget.name == "DistCol1" + assert widget.type == "DistillationColumn" + assert widget.obj == obj + assert widget.windowTitle() == "DistCol1" + + +def test_dock_widget_distillation_column_param_submission(dist_col_widget): + widget, obj, _ = dist_col_widget + if hasattr(widget, 'param'): + widget.param() + assert obj.param_setter.called or hasattr(widget, 'dict') \ No newline at end of file diff --git a/tests/test_dock_widget_flash.py b/tests/test_dock_widget_flash.py new file mode 100644 index 0000000..8feb859 --- /dev/null +++ b/tests/test_dock_widget_flash.py @@ -0,0 +1,103 @@ +import os +import sys +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = MagicMock() +mock_container = MagicMock() +mock_graphics.lst = [] + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetFlash import DockWidgetFlash + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockFlashObj: + def __init__(self, name="Flash1"): + self.name = name + self.variables = { + "thermo_package": {"name": "Thermo Package", "value": "Raoults Law"}, + "Tdef": {"name": "Flash Temperature", "value": "300", "unit": "K"}, + "BTdef": {"value": True}, + "Pdef": {"name": "Flash Pressure", "value": "101325", "unit": "Pa"}, + "BPdef": {"value": True} + } + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def flash_widget(): + obj = MockFlashObj() + container = MockContainerInstance() + widget = DockWidgetFlash("Flash1", "Flash", obj, container) + return widget, obj, container + + +def test_dock_widget_flash_initialization(flash_widget): + widget, obj, _ = flash_widget + assert widget.name == "Flash1" + assert widget.type == "Flash" + assert widget.obj == obj + assert widget.windowTitle() == "Flash1" + assert len(widget.input_dict) == 5 + assert widget.check1.isChecked() is True + assert widget.check2.isChecked() is True + + +def test_dock_widget_flash_toggle_checkboxes(flash_widget): + widget, _, _ = flash_widget + widget.check1.setChecked(False) + assert widget.le2.isEnabled() is False + + widget.check1.setChecked(True) + assert widget.le2.isEnabled() is True + + widget.check2.setChecked(False) + assert widget.le3.isEnabled() is False + + +def test_dock_widget_flash_param_submission(flash_widget): + widget, obj, _ = flash_widget + widget.check1.setChecked(True) + widget.le2.setText("350.5") + widget.check2.setChecked(True) + widget.le3.setText("200000") + + widget.param() + + obj.param_setter.assert_called_once() + assert widget.dict[1] is True + assert widget.dict[2] == 350.5 + assert widget.dict[3] is True + assert widget.dict[4] == 200000.0 \ No newline at end of file diff --git a/tests/test_dock_widget_material_stream.py b/tests/test_dock_widget_material_stream.py index 774186d..96a1e5f 100644 --- a/tests/test_dock_widget_material_stream.py +++ b/tests/test_dock_widget_material_stream.py @@ -111,4 +111,4 @@ def test_dynamic_switching_resets_columns(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_dock_widget_mixer.py b/tests/test_dock_widget_mixer.py new file mode 100644 index 0000000..fac9c4e --- /dev/null +++ b/tests/test_dock_widget_mixer.py @@ -0,0 +1,112 @@ +import os +import sys +from types import ModuleType +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = ModuleType('python.utils.Graphics') +mock_graphics.lst = [] +mock_container = MagicMock() + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetMixer import DockWidgetMixer + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockMixerObj: + def __init__(self, name="Mixer1"): + self.name = name + self.Pout_modes = ["Minimum", "Inlet 1", "Average"] + self.variables = { + "NI": {"name": "Number of Inlets", "value": 2, "unit": ""}, + "outPress": {"name": "Outlet Pressure Mode", "value": "Minimum", "unit": ""} + } + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def mixer_widget(): + obj = MockMixerObj() + container = MockContainerInstance() + widget = DockWidgetMixer("Mixer1", "Mixer", obj, container) + return widget, obj, container + + +def test_dock_widget_mixer_initialization(mixer_widget): + widget, obj, _ = mixer_widget + assert widget.name == "Mixer1" + assert widget.type == "Mixer" + assert widget.obj == obj + assert widget.windowTitle() == "Mixer1" + assert widget.ni_combo is not None + assert widget.ni_combo.count() == 5 + assert widget.ni_combo.currentText() == "2" + + +def test_dock_widget_mixer_input_params_list(mixer_widget): + widget, obj, _ = mixer_widget + assert len(widget.input_dict) == 2 + assert widget.input_dict[0] == widget.ni_combo + assert widget.input_dict[1] == widget.cb2 + assert widget.cb2.count() == 3 + assert widget.cb2.currentText() == "Minimum" + + +def test_dock_widget_mixer_param_submission(mixer_widget, monkeypatch): + widget, obj, _ = mixer_widget + mock_node = MagicMock() + mock_node.obj = obj + + import python.utils.Graphics as g_mod + monkeypatch.setattr(g_mod, "lst", [mock_node]) + + widget.ni_combo.setCurrentText("4") + widget.cb2.setCurrentText("Average") + + widget.param() + + obj.param_setter.assert_called_once_with([4, "Average"]) + assert widget.dict == [4, "Average"] + mock_node.update_input_ports.assert_called_once_with(4) + + +def test_dock_widget_mixer_btn_click(mixer_widget, monkeypatch): + widget, obj, _ = mixer_widget + import python.utils.Graphics as g_mod + monkeypatch.setattr(g_mod, "lst", []) + + widget.ni_combo.setCurrentText("3") + widget.btn.click() + + obj.param_setter.assert_called_once_with([3, "Minimum"]) \ No newline at end of file diff --git a/tests/test_dock_widget_shortcut_column.py b/tests/test_dock_widget_shortcut_column.py new file mode 100644 index 0000000..2fc7afd --- /dev/null +++ b/tests/test_dock_widget_shortcut_column.py @@ -0,0 +1,80 @@ +import os +import sys +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = MagicMock() +mock_container = MagicMock() +mock_graphics.lst = [] + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetShortcutColumn import DockWidgetShortcutColumn + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockShortcutColumnObj: + def __init__(self, name="Shortcut1"): + self.name = name + self.variables = { + "thermo_package": {"name": "Thermo Package", "value": "Raoults Law"}, + "reflux_ratio": {"name": "Reflux Ratio", "value": "1.5", "unit": ""}, + "condenser_type": {"name": "Condenser Type", "value": "Total"}, + "light_key": {"name": "Light Key", "value": "Ethanol"}, + "heavy_key": {"name": "Heavy Key", "value": "Water"} + } + self.comp_list = ["Ethanol", "Water"] + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def shortcut_widget(): + obj = MockShortcutColumnObj() + container = MockContainerInstance() + widget = DockWidgetShortcutColumn("Shortcut1", "ShortcutColumn", obj, container) + return widget, obj, container + + +def test_dock_widget_shortcut_column_init(shortcut_widget): + widget, obj, _ = shortcut_widget + assert widget.name == "Shortcut1" + assert widget.type == "ShortcutColumn" + assert widget.obj == obj + assert widget.windowTitle() == "Shortcut1" + + +def test_dock_widget_shortcut_column_param_submission(shortcut_widget): + widget, obj, _ = shortcut_widget + if hasattr(widget, 'param'): + widget.param() + assert obj.param_setter.called or hasattr(widget, 'dict') \ No newline at end of file diff --git a/tests/test_dock_widget_splitter.py b/tests/test_dock_widget_splitter.py new file mode 100644 index 0000000..5a19373 --- /dev/null +++ b/tests/test_dock_widget_splitter.py @@ -0,0 +1,106 @@ +import os +import sys +from types import ModuleType +from unittest.mock import MagicMock +import pytest +from PyQt5.QtWidgets import QApplication + +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +for p in [os.path.join(PROJECT_ROOT, 'src', 'main'), os.path.join(PROJECT_ROOT, 'src', 'main', 'python')]: + if p not in sys.path: + sys.path.insert(0, p) + +_saved_modules = {k: sys.modules.get(k) for k in [ + 'utils.Graphics', 'python.utils.Graphics', 'utils.Container', 'python.utils.Container' +]} + +mock_graphics = ModuleType('python.utils.Graphics') +mock_graphics.lst = [] +mock_container = MagicMock() + +sys.modules['utils.Graphics'] = mock_graphics +sys.modules['python.utils.Graphics'] = mock_graphics +sys.modules['utils.Container'] = mock_container +sys.modules['python.utils.Container'] = mock_container + +app = QApplication.instance() +if app is None: + app = QApplication(sys.argv) + +from DockWidgets.DockWidgetSplitter import DockWidgetSplitter + +for k, v in _saved_modules.items(): + if v is None: + sys.modules.pop(k, None) + else: + sys.modules[k] = v + + +class MockSplitterObj: + def __init__(self, name="Splitter1"): + self.name = name + self.NO = 2 + self.split_ratios = [0.5, 0.5] + self.stream_names = ["Stream_1", "Stream_2"] + self.variables = { + "NO": {"name": "Number of Outlets", "value": 2, "unit": ""}, + "split_ratios": {"name": "Split Ratios", "value": [0.5, 0.5], "unit": ""} + } + self.param_setter = MagicMock() + + +class MockContainerInstance: + def __init__(self): + self.graphics = MagicMock() + self.graphics.graphicsView = MagicMock() + self.graphics.graphicsView.horizontalScrollBar = MagicMock() + self.graphics.graphicsView.horizontalScrollBar.return_value.value.return_value = 100 + + +@pytest.fixture +def splitter_widget(): + obj = MockSplitterObj() + container = MockContainerInstance() + widget = DockWidgetSplitter("Splitter1", "Splitter", obj, container) + return widget, obj, container + + +def test_dock_widget_splitter_initialization(splitter_widget): + widget, obj, _ = splitter_widget + assert widget.name == "Splitter1" + assert widget.type == "Splitter" + assert widget.obj == obj + assert widget.windowTitle() == "Splitter1" + + +def test_dock_widget_splitter_equalize(splitter_widget): + widget, _, _ = splitter_widget + if hasattr(widget, 'equalize_streams') and hasattr(widget, 'stream_edits') and len(widget.stream_edits) == 2: + widget.equalize_streams() + assert float(widget.stream_edits[0].text()) == pytest.approx(0.5, 0.01) + assert float(widget.stream_edits[1].text()) == pytest.approx(0.5, 0.01) + + +def test_dock_widget_splitter_normalize(splitter_widget): + widget, _, _ = splitter_widget + if hasattr(widget, 'normalize_streams') and hasattr(widget, 'stream_edits') and len(widget.stream_edits) == 2: + widget.stream_edits[0].setText("2.0") + widget.stream_edits[1].setText("2.0") + widget.normalize_streams() + assert float(widget.stream_edits[0].text()) == pytest.approx(0.5, 0.01) + assert float(widget.stream_edits[1].text()) == pytest.approx(0.5, 0.01) + + +def test_dock_widget_splitter_param_submit(splitter_widget, monkeypatch): + widget, obj, _ = splitter_widget + mock_node = MagicMock() + mock_node.obj = obj + + import python.utils.Graphics as g_mod + monkeypatch.setattr(g_mod, "lst", [mock_node]) + + if hasattr(widget, 'stream_edits') and len(widget.stream_edits) == 2: + widget.stream_edits[0].setText("0.6") + widget.stream_edits[1].setText("0.4") + widget.param() + obj.param_setter.assert_called() \ No newline at end of file