Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mal_gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(self, parent=None):
os.makedirs(os.path.dirname(self.config_file_path), exist_ok=True)

self.config = configparser.ConfigParser()
self.config.read(self.config_file_path)
self.config.read(self.config_file_path, encoding="utf-8")
self.selected_lang_file = self.config.get(
"Settings", "langFilePath", fallback=None
)
Expand Down
19 changes: 10 additions & 9 deletions mal_gui/connection_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ def __init__(
for fieldname, association in possible_assocs.items():
field = association.get_field(fieldname)

# If assoc ends with end_assets type, give that assoc
# as option in list widget
if field.asset == self.end_asset.lg_asset:
# Association endpoints also accept subassets of their declared type.
if self.end_asset.lg_asset.is_subasset_of(field.asset):
assoc_list_item = QListWidgetItem(
self.start_asset.name
+ "."
Expand All @@ -91,6 +90,7 @@ def __init__(
self.ok_button = QPushButton("OK")
self.ok_button.clicked.connect(self.ok_button_clicked)
self.ok_button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.ok_button.setEnabled(self.association_list_widget.count() > 0)
button_layout.addWidget(self.ok_button)

self.cancel_button = QPushButton("Cancel")
Expand All @@ -112,15 +112,16 @@ def filter_items(self, text):

def ok_button_clicked(self):
selected_item = self.association_list_widget.currentItem()
if selected_item is None:
return

if selected_item:
data = selected_item.data(Qt.UserRole)
data = selected_item.data(Qt.UserRole)

from_asset: ModelAsset = data.get("from")
to_asset: ModelAsset = data.get("to")
self.field_name: str = data.get("fieldname")
from_asset: ModelAsset = data.get("from")
to_asset: ModelAsset = data.get("to")
self.field_name: str = data.get("fieldname")

print(f"{from_asset}.{self.field_name} = {to_asset} chosen")
print(f"{from_asset}.{self.field_name} = {to_asset} chosen")

self.accept()

Expand Down
86 changes: 86 additions & 0 deletions tests/test_connection_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from types import SimpleNamespace

import pytest
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QDialog

from maltoolbox.language import LanguageGraphAsset, LanguageGraphAssociation
from maltoolbox.language.language_graph_assoc import (
LanguageGraphAssociationField,
link_association_to_assets,
)
from maltoolbox.model import ModelAsset

from mal_gui.connection_dialog import AssociationConnectionDialog


@pytest.fixture
def machine_execution_assets(app):
machine = LanguageGraphAsset("Machine")
infotainment = LanguageGraphAsset("InfotainmentSystem", own_super_asset=machine)
application = LanguageGraphAsset("VehicularApplication")
operating_system = LanguageGraphAsset(
"OperatingSystem", own_super_asset=application
)

association = LanguageGraphAssociation(
name="machineExecution",
left_field=LanguageGraphAssociationField(machine, "hostMachine", 0, 1),
right_field=LanguageGraphAssociationField(
application, "machineExecutedApps", 0, 0
),
)
link_association_to_assets(association, machine, application)

return {
asset.name: ModelAsset(asset.name, asset_id, asset)
for asset_id, asset in enumerate(
(machine, infotainment, application, operating_system)
)
}


def make_dialog(start_asset, end_asset):
start_item = SimpleNamespace(asset=start_asset, asset_type=start_asset.type)
end_item = SimpleNamespace(asset=end_asset, asset_type=end_asset.type)
return AssociationConnectionDialog(start_item, end_item, None, None)


@pytest.mark.parametrize(
("start_type", "end_type", "expected_fieldname"),
[
("InfotainmentSystem", "OperatingSystem", "machineExecutedApps"),
("OperatingSystem", "InfotainmentSystem", "hostMachine"),
("Machine", "VehicularApplication", "machineExecutedApps"),
],
)
def test_inherited_endpoint_types_are_available(
machine_execution_assets, start_type, end_type, expected_fieldname
):
start_asset = machine_execution_assets[start_type]
end_asset = machine_execution_assets[end_type]
dialog = make_dialog(start_asset, end_asset)

assert dialog.association_list_widget.count() == 1
assert dialog.ok_button.isEnabled()
selected_item = dialog.association_list_widget.currentItem()
assert selected_item.data(Qt.UserRole)["fieldname"] == expected_fieldname

dialog.ok_button_clicked()
assert dialog.result() == QDialog.Accepted
assert dialog.field_name == expected_fieldname

start_asset.add_associated_assets(expected_fieldname, {end_asset})
assert end_asset in start_asset.associated_assets[expected_fieldname]


def test_empty_selection_cannot_be_accepted(machine_execution_assets):
unrelated_asset = ModelAsset("Unrelated", 4, LanguageGraphAsset("Unrelated"))
dialog = make_dialog(machine_execution_assets["Machine"], unrelated_asset)

assert dialog.association_list_widget.count() == 0
assert not dialog.ok_button.isEnabled()

dialog.ok_button_clicked()
assert dialog.result() != QDialog.Accepted
assert dialog.field_name is None