Coverage for tests/diagram_parts.py: 100%

16 statements  

« prev     ^ index     » next       coverage.py v7.15.3, created at 2026-08-03 00:00 +0000

1import re as py_re 

2import typing 

3 

4 

5EDGE_ARROW: typing.Final = " --> " 

6_GROUP_BLOCK_PATTERN: typing.Final = py_re.compile( 

7 r'subgraph group_\w+\["(?P<group_title>[^"]+)"\]\n(?P<group_body>.*?)\n\s*end', 

8 flags=py_re.DOTALL, 

9) 

10_DEFINED_NODE_PATTERN: typing.Final = py_re.compile(r'(?m)^\s*(?P<node_id>[A-Za-z0-9_]+)\["') 

11_EDGE_ENDS_PATTERN: typing.Final = py_re.compile(r"(?m)^\s*(?P<source>\w+) -->.* (?P<target>\w+)$") 

12 

13 

14@typing.final 

15class EdgeEnds(typing.NamedTuple): 

16 source_id: str 

17 target_id: str 

18 

19 

20def extract_edge_lines(rendered_diagram: str, /) -> list[str]: 

21 return [one_line.strip() for one_line in rendered_diagram.split("\n") if EDGE_ARROW in one_line] 

22 

23 

24def collect_group_of_every_node(rendered_diagram: str, /) -> dict[str, str]: 

25 return { 

26 one_node_match.group("node_id"): one_group_match.group("group_title") 

27 for one_group_match in _GROUP_BLOCK_PATTERN.finditer(rendered_diagram) 

28 for one_node_match in _DEFINED_NODE_PATTERN.finditer(one_group_match.group("group_body")) 

29 } 

30 

31 

32def collect_defined_node_ids(rendered_diagram: str, /) -> list[str]: 

33 return [one_match.group("node_id") for one_match in _DEFINED_NODE_PATTERN.finditer(rendered_diagram)] 

34 

35 

36def collect_edge_ends(rendered_diagram: str, /) -> tuple[EdgeEnds, ...]: 

37 return tuple( 

38 EdgeEnds(source_id=one_match.group("source"), target_id=one_match.group("target")) 

39 for one_match in _EDGE_ENDS_PATTERN.finditer(rendered_diagram) 

40 )