Commit f8aa39c9 authored by Samuel GAIST's avatar Samuel GAIST
Browse files

[widgets][algorithmeditor] Implement AlgorithmEditor

parent 2addb974
......@@ -23,16 +23,335 @@
# #
###############################################################################
import pytest
from PyQt5 import QtCore
from ..backend.asset import Asset
from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel
from ..widgets.algorithmeditor import PropertyEditor
from ..widgets.algorithmeditor import ParameterEditor
from ..widgets.algorithmeditor import ResultEditor
from ..widgets.algorithmeditor import IOWidget
from ..widgets.algorithmeditor import GroupEditor
from ..widgets.algorithmeditor import AlgorithmEditor
from ..widgets.algorithmeditor import ALGORITHM_TYPE
from ..widgets.algorithmeditor import DEFAULT_SCHEMA_VERSION
from ..widgets.algorithmeditor import DEFAULT_API_VERSION
from .conftest import sync_prefix
from .conftest import prefix
def get_algorithm_declaration(prefix_path, algorithm_name):
asset = Asset(prefix_path, AssetType.ALGORITHM, algorithm_name)
return asset.declaration
def get_valid_algorithm(test_prefix):
sync_prefix()
model = AssetModel()
model.asset_type = AssetType.ALGORITHM
model.prefix_path = test_prefix
model.setLatestOnlyEnabled(False)
return [
algorithm
for algorithm in model.stringList()
if all(
invalid not in algorithm
for invalid in ["errors", "legacy", "invalid", "v1"]
)
]
@pytest.fixture()
def dataformat_model(test_prefix):
model = AssetModel()
model.asset_type = AssetType.DATAFORMAT
model.prefix_path = test_prefix
return model
class TestPropertyEditor:
"""Test that the algorithm properties editor works as expected"""
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, test_prefix, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
editor = PropertyEditor()
qtbot.addWidget(editor)
editor.load(reference_json)
reference_json.pop("groups", None)
reference_json.pop("parameters", None)
reference_json.pop("results", None)
reference_json.pop("uses", None)
assert editor.dump() == reference_json
def test_default_dump(self, qtbot):
editor = PropertyEditor()
qtbot.addWidget(editor)
assert editor.dump() == {
"language": "unknown",
"api_version": DEFAULT_API_VERSION,
"type": "sequential",
"schema_version": DEFAULT_SCHEMA_VERSION,
"splittable": False,
}
def test_splittable(self, qtbot):
editor = PropertyEditor()
qtbot.addWidget(editor)
assert editor.canBeSplitable()
assert editor.splittable_checkbox.isEnabled()
for button in [
editor.autonomous_radiobutton,
editor.loopuser_radiobutton,
editor.sequential_radiobutton,
]:
with qtbot.waitSignal(editor.dataChanged):
button.toggle()
assert editor.canBeSplitable()
with qtbot.waitSignal(editor.dataChanged):
editor.loop_radiobutton.toggle()
assert not editor.canBeSplitable()
assert not editor.splittable_checkbox.isEnabled()
with qtbot.waitSignal(editor.dataChanged):
editor.analyzer_checkbox.toggle()
assert not editor.canBeSplitable()
def test_has_outputs(self, qtbot):
editor = PropertyEditor()
qtbot.addWidget(editor)
assert editor.hasOutputs()
with qtbot.waitSignal(editor.dataChanged):
editor.analyzer_checkbox.toggle()
assert not editor.hasOutputs()
with qtbot.waitSignal(editor.dataChanged):
editor.analyzer_checkbox.toggle()
assert editor.hasOutputs()
with qtbot.waitSignal(editor.dataChanged):
editor.loop_radiobutton.toggle()
assert not editor.hasOutputs()
@pytest.mark.parametrize(
["algorithm_type", "has_loop"],
[
("sequential", False),
("autonomous", False),
("loop", True),
("loop_user", True),
],
)
def test_has_loop(self, qtbot, algorithm_type, has_loop):
editor = PropertyEditor()
qtbot.addWidget(editor)
assert not editor.hasLoop()
for button in editor.button_group.buttons():
if button.property(ALGORITHM_TYPE) == algorithm_type:
button.setChecked(True)
break
assert editor.hasLoop() == has_loop
@pytest.mark.parametrize(
["algorithm_type", "schema_version"],
[
("sequential", DEFAULT_SCHEMA_VERSION),
("autonomous", DEFAULT_SCHEMA_VERSION),
("loop", 3),
("loop_user", 3),
],
)
def test_schema_version(self, qtbot, algorithm_type, schema_version):
editor = PropertyEditor()
qtbot.addWidget(editor)
for button in editor.button_group.buttons():
if button.property(ALGORITHM_TYPE) == algorithm_type:
button.setChecked(True)
break
assert editor.dump().get("schema_version") == schema_version
class TestParameterEditor:
"""Test that the algorithm parameter editor works as expected"""
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, test_prefix, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
parameters = reference_json.pop("parameters", {})
editor = ParameterEditor()
qtbot.addWidget(editor)
for _, parameter in parameters.items():
editor.load(parameter)
assert editor.dump() == parameter
def test_name(self, qtbot):
editor = ParameterEditor()
qtbot.addWidget(editor)
new_name = "test"
with qtbot.waitSignal(editor.dataChanged):
editor.setName(new_name)
assert editor.name() == new_name
class TestResultEditor:
"""Test that the algorithm result editor works as expected"""
@pytest.fixture()
def editor(self, qtbot, dataformat_model):
editor = ResultEditor(dataformat_model)
qtbot.addWidget(editor)
return editor
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, test_prefix, editor, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
results = reference_json.pop("results", {})
for _, result in results.items():
editor.load(result)
assert editor.dump() == result
def test_name(self, qtbot, editor):
new_name = "test"
with qtbot.waitSignal(editor.dataChanged):
editor.setName(new_name)
assert editor.name() == new_name
def test_type_change(self, qtbot, editor):
model = editor.type_combobox.model()
dataformat = model.index(1, 0).data()
with qtbot.waitSignal(editor.dataChanged):
editor.type_combobox.setCurrentIndex(1)
assert editor.dump()["type"] == dataformat
def test_display_change(self, qtbot, editor):
assert not editor.dump()["display"]
with qtbot.waitSignal(editor.dataChanged):
editor.display_checkbox.toggle()
assert editor.dump()["display"]
with qtbot.waitSignal(editor.dataChanged):
editor.display_checkbox.toggle()
assert not editor.dump()["display"]
class TestIOWidget(object):
"""Tests for the widget for input output handling"""
@pytest.fixture()
def editor(self, qtbot, dataformat_model):
editor = IOWidget("Test", dataformat_model)
qtbot.addWidget(editor)
return editor
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, test_prefix, dataformat_model, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
groups = reference_json.pop("groups", {})
for group in groups:
inputs = group.get("inputs", {})
outputs = group.get("outputs", {})
editor = IOWidget("Test", dataformat_model)
qtbot.addWidget(editor)
editor.load(inputs)
assert editor.dump() == inputs
editor.load(outputs)
assert editor.dump() == outputs
def test_add_entry(self, qtbot, test_prefix, editor):
assert len(editor.dump()) == 0
with qtbot.waitSignal(editor.dataChanged):
qtbot.mouseClick(editor.add_button, QtCore.Qt.LeftButton)
assert len(editor.dump()) == 1
def test_remove_entry(self, qtbot, test_prefix, editor, dataformat_model):
assert not editor.remove_button.isEnabled()
editor.load({"Test": {"type": dataformat_model.stringList()[0]}})
assert not editor.remove_button.isEnabled()
with qtbot.waitSignal(editor.tablewidget.itemSelectionChanged):
editor.tablewidget.selectRow(0)
assert editor.remove_button.isEnabled()
qtbot.mouseClick(editor.remove_button, QtCore.Qt.LeftButton)
assert len(editor.dump()) == 0
assert not editor.remove_button.isEnabled()
class TestGroupEditor:
"""Test that the algorithm group editor works as expected"""
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, test_prefix, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
model = AssetModel()
model.asset_type = AssetType.DATAFORMAT
model.prefix_path = test_prefix
groups = reference_json.pop("groups", {})
editor = GroupEditor(model)
qtbot.addWidget(editor)
is_loop = reference_json.get("type") in ["loop", "loop_user"]
has_no_output = (
reference_json.get("type") == "loop" or "results" in reference_json
)
for index, group in enumerate(groups):
editor.load(group)
if not has_no_output:
editor.setOutputsEnabled(index == 0)
else:
editor.setOutputsEnabled(False)
editor.setLoopEnabled(is_loop)
assert editor.dump() == group
class TestAlgorithmEditor:
"""Test that the mock editor works correctly"""
def test_load_and_dump(self, qtbot):
reference_json = {"description": "test"}
@pytest.mark.parametrize("algorithm", get_valid_algorithm(prefix))
def test_load_and_dump(self, qtbot, beat_context, test_prefix, algorithm):
reference_json = get_algorithm_declaration(test_prefix, algorithm)
editor = AlgorithmEditor()
qtbot.addWidget(editor)
editor.set_context(beat_context)
editor.load_json(reference_json)
assert editor.dump_json() == reference_json
This diff is collapsed.
......@@ -216,6 +216,8 @@ class BoolSetupWidget(QWidget):
def load(self, data):
"""Load the json object passed as parameter"""
self.reset()
default = data.get("default", True)
if default:
self.true_button.setChecked(True)
......@@ -309,6 +311,8 @@ class StringSetupWidget(QWidget):
def load(self, data):
"""Load the json object passed as parameter"""
self.reset()
choices = data.get("choice", [])
default = data.get("default", "")
......@@ -523,6 +527,8 @@ class NumericalSetupWidget(QWidget):
def load(self, data):
"""Load the json object passed as parameter"""
self.reset(self.current_type)
choices = data.get("choice", [])
str_choices = [str(item) for item in choices]
range_values = data.get("range", [-10, 10])
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment