Skip to content

Commit

Permalink
Merge pull request #7 from pheetah/feat/enhance
Browse files Browse the repository at this point in the history
feat: Allow cascaded flows
  • Loading branch information
pheetah authored Dec 28, 2023
2 parents 1fc166a + 9d67b49 commit cba8e01
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
31 changes: 25 additions & 6 deletions compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from doctree import ActivityNode, EpcDiagram, EpcNode, EventNode, IfNode
from logs import log
from settings.language import SYMBOLS, ContextKeywords, Keywords
from settings.language import NODE_KEYWORDS, SYMBOLS, ContextKeywords, Keywords

G = AGraph(directed=True)

Expand Down Expand Up @@ -37,6 +37,19 @@ def _get_after(self, token: str, keyword: str):
.rstrip()
)

def _split_flow(self, token: str):
rules = "|".join(NODE_KEYWORDS)
regex = rf"({rules})(.*?)(?=({rules}|$))"
flows = [
x.group()
for x in re.finditer(
regex,
token,
)
]

return flows

def _handle_activity(self, token: str, diagram: EpcDiagram) -> EpcNode:
if Keywords.ACTIVITY in token:
raw_action = self._get_after(token, Keywords.ACTIVITY)
Expand All @@ -61,6 +74,12 @@ def _handle_event(self, token: str, diagram: EpcDiagram) -> EpcNode:
raw_action = self._get_after(token, Keywords.EVENT)
diagram.push(EventNode(description=raw_action))

def _handle_flow(self, token: str, diagram: EpcDiagram):
flows = self._split_flow(token=token)
for flow in flows:
self._handle_activity(token=flow, diagram=diagram)
self._handle_event(token=flow, diagram=diagram)

def _handle_if(self, sequence: TokenSequence, depth=0) -> EpcNode:
first_element = str(sequence.pop(0))
if Keywords.IF not in str(first_element):
Expand All @@ -69,6 +88,8 @@ def _handle_if(self, sequence: TokenSequence, depth=0) -> EpcNode:
if_node = copy.deepcopy(IfNode(uuid4()))
current_branch = copy.deepcopy(EpcDiagram())

self._handle_flow(token=first_element, diagram=current_branch)

depth_inner_processed_index = None
depth_latest_index = None

Expand All @@ -94,13 +115,12 @@ def _handle_if(self, sequence: TokenSequence, depth=0) -> EpcNode:
current_branch.push(depth_if)
continue

self._handle_activity(token=token, diagram=current_branch)
self._handle_event(token=token, diagram=current_branch)

if Keywords.ELSE in token:
if_node.branches.append(current_branch.head)
current_branch = EpcDiagram()

self._handle_flow(token=token, diagram=current_branch)

if Keywords.ENDIF in token:
if_node.branches.append(current_branch.head)
return index + 1, if_node
Expand Down Expand Up @@ -128,8 +148,7 @@ def add_nodes(self, token_sequence: str) -> EpcDiagram:
diagram.push(if_node)
continue

self._handle_activity(token=token, diagram=diagram)
self._handle_event(token=token, diagram=diagram)
self._handle_flow(token=token, diagram=diagram)

return diagram

Expand Down
8 changes: 8 additions & 0 deletions settings/language.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class ContextKeywords(StringEnum):
API_CALL_IN = "<-"


NODE_KEYWORDS = [
Keywords.ACTIVITY,
Keywords.EVENT,
Keywords.IF,
Keywords.ELSE,
Keywords.ENDIF,
]

SYMBOLS = [
Keywords.ACTIVITY,
Keywords.EVENT,
Expand Down
46 changes: 40 additions & 6 deletions tests/test_node_adder.py → tests/test_language_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,45 @@ def test_can_separate_multiple_sources(self):
self.node_adder._handle_activity(token=TOKEN, diagram=diagram)

# After
actvity: ActivityNode = diagram.head
activity: ActivityNode = diagram.head

assert actvity._description == "find related tax rates"
assert actvity._database == "banking.rates"
assert set(actvity._outgoing_api_calls) == set(["id"])
assert set(actvity._incoming_api_calls) == set(["tax_rate_list", "permissions"])
assert activity._description == "find related tax rates"
assert activity._database == "banking.rates"
assert set(activity._outgoing_api_calls) == set(["id"])
assert set(activity._incoming_api_calls) == set(
["tax_rate_list", "permissions"]
)

assert activity.next is None

def test_can_cascade_multiple_nodes(self):
# Before
diagram = EpcDiagram()
TOKEN = (
f"# {Keywords.ACTIVITY} find related tax rates "
"[=] banking.rates "
f"{Keywords.ACTIVITY} fetch tax rates and permissions "
"-> id <- tax_rate_list, permissions "
f"{Keywords.EVENT} payment completed"
)

# Test
self.node_adder._handle_flow(token=TOKEN, diagram=diagram)

# After
# Assert first node
first_node: ActivityNode = diagram.head
assert first_node._description == "find related tax rates"
assert first_node._database == "banking.rates"

# Assert next node
second_node = first_node.next
assert set(second_node._outgoing_api_calls) == set(["id"])
assert set(second_node._incoming_api_calls) == set(
["tax_rate_list", "permissions"]
)

assert actvity.next is None
# Assert next node
third_node = second_node.next
assert third_node._description == "payment completed"
assert third_node.next is None

0 comments on commit cba8e01

Please sign in to comment.