Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for Issues #8 and #9 #49

Merged
merged 17 commits into from
Oct 12, 2023
Merged
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,4 @@ dmypy.json
# JetBrains IDE
.idea/

.vscode/
.vscode/
17 changes: 17 additions & 0 deletions bpmnconstraints/parser/bpmn_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,29 @@ def run(self):
self.__mark_gateway_elements()
if self.transitivity:
self.__add_transitivity()
self.validate_splitting_and_joining_gateway_cases()
return self.sequence
except Exception:
logging.warning(
"\nCould not execute model. Make sure that model is:\n1. Formatted correctly.\n2. File ends with .xml or .json."
)

def validate_splitting_and_joining_gateway_cases(self):
"""Update 'is start' and 'is end' attributes of cfo based on splitting/joining gateways.
Otherwise, the parser interprets the gateways as start/end events instead of the activities.
"""

item_indices = {item["name"]: index for index, item in enumerate(self.sequence)}
for cfo in self.sequence:
if cfo["is start"] and cfo["name"] == "XOR":
cfo["is start"] = False
for successor in cfo["successor"]:
self.sequence[item_indices[successor["name"]]]["is start"] = True
if cfo["is end"] and cfo["name"] in GATEWAY_NAMES:
cfo["is end"] = False
for predecessor in cfo["predecessor"]:
self.sequence[item_indices[predecessor["name"]]]["is end"] = True

def __mark_gateway_elements(self):
for cfo in self.sequence:
predecessors = cfo.get("predecessor")
Expand Down
24 changes: 23 additions & 1 deletion tests/test_end_constraints.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from test_utils import init_test_setup_for_compiler
from test_utils import init_test_setup_for_compiler, init_test_setup_for_parser
from file_constants import (
MULTIPLE_ENDINGS_DIAGRAM,
LINEAR_SEQUENCE_DIAGRAM_WITHOUT_START_AND_END,
XOR_GATEWAY_SEQUENCE_DIAGRAM,
LINEAR_MERMAID_GRAPH,
)


Expand All @@ -15,6 +17,26 @@ def test_end_constraint_is_generated_when_multiple_endings():
assert all(constraint in res for constraint in expected_ending_constraints)


def test_end_constraint_is_generated_with_linear_parser():
res = init_test_setup_for_parser(LINEAR_MERMAID_GRAPH)
assert res[-1]["is end"] == True


def test_end_constraint_is_generated_without_explicit_end_event():
res = init_test_setup_for_compiler(LINEAR_SEQUENCE_DIAGRAM_WITHOUT_START_AND_END)
assert "End[second element]" in res


def test_end_constraint_is_generated_when_multiple_endings():
res = init_test_setup_for_parser(XOR_GATEWAY_SEQUENCE_DIAGRAM)

assert res[-1]["is end"] and res[-2]["is end"] and not res[3]["is end"]


def test_end_constraint_is_generated_when_xor_gateway():
res = init_test_setup_for_compiler(XOR_GATEWAY_SEQUENCE_DIAGRAM)
expected_ending_constraints = [
"End[activity four]",
"End[activity five]",
]
assert all(constraint in res for constraint in expected_ending_constraints)
20 changes: 18 additions & 2 deletions tests/test_init_constraints.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from test_utils import init_test_setup_for_compiler
from test_utils import init_test_setup_for_compiler, init_test_setup_for_parser
from file_constants import (
LINEAR_SEQUENCE_DIAGRAM_WITHOUT_START_AND_END,
MULTIPLE_STARTS_DIAGRAM,
XOR_GATEWAY_SEQUENCE_DIAGRAM,
)


Expand All @@ -12,4 +13,19 @@ def test_init_constraint_is_generated_without_explicit_start_event():

def test_that_each_start_has_init_constraint():
res = init_test_setup_for_compiler(MULTIPLE_STARTS_DIAGRAM)
assert ["Init[path one]", "Init[path two]"] == res
expected_init_constraints = ["Init[path one]", "Init[path two]"]
assert all(constraint in res for constraint in expected_init_constraints)


def test_missing_init_constraints_for_XOR_gate_parser():
res = init_test_setup_for_parser(XOR_GATEWAY_SEQUENCE_DIAGRAM)
assert res[4]["is start"] and res[5]["is start"] and not res[0]["is start"]


def test_missing_init_constraints_for_XOR_gate():
res = init_test_setup_for_compiler(XOR_GATEWAY_SEQUENCE_DIAGRAM)
expected_init_constraints = [
"Init[activity one]",
"Init[activity two]",
]
assert all(constraint in res for constraint in expected_init_constraints)