Skip to content

Commit 351c51c

Browse files
committed
Update tr_link to support pattern matching
1 parent 8526552 commit 351c51c

File tree

4 files changed

+111
-12
lines changed

4 files changed

+111
-12
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[flake8]
22
max-line-length = 120
3-
extend-ignore = I
3+
extend-ignore = I, W503
44
per-file-ignores =
55
sphinxcontrib/test_reports/__init__.py: F401
66
sphinxcontrib/test_reports/directives/__init__.py: F401

docs/functions.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Then it goes through **all** other needs and checks if the value of their ``sour
3333
the ``target_option``.
3434
If this is the case, their IDs get stored and finally returned.
3535

36+
In case the ``source_option`` contains a ``*`` (e.g. ``sphinxcontrib.test_reports.*``), the function will check if the
37+
``target_option`` matches the ``source_option``. This is useful if one wants to link multiple test results to one test case.
38+
39+
3640
**Example**::
3741

3842
.. spec:: sphinxcontrib.test_reports.test_reports

sphinxcontrib/test_reports/functions/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
import re
2+
3+
14
def tr_link(app, need, needs, test_option, target_option, *args, **kwargs):
25
if test_option not in need:
36
return ""
4-
test_opt = need[test_option]
7+
test_option_value = need[test_option]
8+
if test_option_value is None or len(test_option_value) <= 0:
9+
return []
510

611
links = []
12+
test_pattern = re.compile(test_option_value)
713
for need_target in needs.values():
14+
# Skip linking to itself
15+
if need_target["id"] == need["id"]:
16+
continue
17+
818
if target_option not in need_target:
919
continue
1020

21+
target_option_value = need_target[target_option]
1122
if (
12-
test_opt == need_target[target_option] and test_opt is not None and len(test_opt) > 0 # fmt: skip
23+
target_option_value is not None
24+
and len(target_option_value) > 0
25+
and test_pattern.match(target_option_value)
1326
):
1427
links.append(need_target["id"])
1528

tests/test_tr_link.py

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,113 @@ def test_tr_link_option_not_in_need():
55
"""
66
Return an empty string when the specified test option is missing from the need.
77
"""
8-
assert tr_link(app=None, need={}, needs={}, test_option="a", target_option="b") == ""
8+
assert (
9+
tr_link(app=None, need={}, needs={}, test_option="a", target_option="b") == ""
10+
)
11+
912

1013
def test_tr_link_no_target_option_in_needs():
1114
"""
1215
Return an empty list when the target option is missing in all items of needs.
1316
"""
14-
assert tr_link(app=None, need={"a": "1"}, needs={"x": {"id": "123"}}, test_option="a", target_option="b") == []
17+
assert (
18+
tr_link(
19+
app=None,
20+
need={"id": "1", "a": "1"},
21+
needs={"x": {"id": "123"}},
22+
test_option="a",
23+
target_option="b",
24+
)
25+
== []
26+
)
27+
1528

1629
def test_tr_link_no_match():
1730
"""
18-
Returns an empty list when no matching value for the test option is found in any of the target options within needs.
31+
Returns an empty list when no matching value for the test option is found
32+
in any of the target options within needs.
1933
"""
20-
assert tr_link(app=None, need={"a": "1"}, needs={"x": {"b": "2", "id": "123"}}, test_option="a", target_option="b") == []
34+
assert (
35+
tr_link(
36+
app=None,
37+
need={"id": "1", "a": "1"},
38+
needs={"x": {"b": "2", "id": "123"}},
39+
test_option="a",
40+
target_option="b",
41+
)
42+
== []
43+
)
44+
2145

2246
def test_tr_link_match():
2347
"""
2448
Returns a list of ids when there is a matching value in both need and needs.
2549
"""
26-
assert tr_link(app=None, need={"a": "1"}, needs={"x": {"b": "1", "id": "123"}}, test_option="a", target_option="b") == ["123"]
50+
assert tr_link(
51+
app=None,
52+
need={"id": "1", "a": "1"},
53+
needs={"x": {"b": "1", "id": "123"}},
54+
test_option="a",
55+
target_option="b",
56+
) == ["123"]
57+
2758

2859
def test_tr_link_none_or_empty():
2960
"""
3061
'None' and empty string values are not considered as valid matches.
3162
"""
32-
need = {"a": None, "b": ""}
33-
needs = {"x": {"c": None, "id": "111"}, "y": {"c": "valid", "id": "222"}, "z": {"c": "", "id": "333"}}
34-
assert tr_link(app=None, need=need, needs=needs, test_option="b", target_option="c") == []
35-
assert tr_link(app=None, need=need, needs=needs, test_option="a", target_option="c") == []
63+
need = {"id": "1", "a": None, "b": ""}
64+
needs = {
65+
"x": {"c": None, "id": "111"},
66+
"y": {"c": "valid", "id": "222"},
67+
"z": {"c": "", "id": "333"},
68+
}
69+
assert (
70+
tr_link(app=None, need=need, needs=needs, test_option="b", target_option="c")
71+
== []
72+
)
73+
assert (
74+
tr_link(app=None, need=need, needs=needs, test_option="a", target_option="c")
75+
== []
76+
)
77+
78+
79+
def test_tr_link_regex_match():
80+
"""
81+
Returns a list of ids when the test option value containing an asterisk (*)
82+
correctly matches target options using regular expression patterns.
83+
"""
84+
needs = {
85+
"x": {"b": "abc123", "id": "111"},
86+
"q": {"b": "abc/123", "id": "112"},
87+
"y": {"b": "def456", "id": "222"},
88+
"z": {"b": "ghi789", "id": "333"},
89+
}
90+
need = {"id": "1", "a": "abc.*"}
91+
assert tr_link(
92+
app=None, need=need, needs=needs, test_option="a", target_option="b"
93+
) == ["111", "112"]
94+
95+
96+
def test_tr_link_regex_no_match():
97+
"""
98+
Returns an empty list when the test option value containing an asterisk (*)
99+
does not match any target options using regular expression patterns.
100+
"""
101+
needs = {"x": {"b": "abc123", "id": "111"}, "y": {"b": "def456", "id": "222"}}
102+
need = {"id": "1", "a": "xyz.*"}
103+
assert (
104+
tr_link(app=None, need=need, needs=needs, test_option="a", target_option="b")
105+
== []
106+
)
107+
108+
109+
def test_tr_link_skip_linking_to_itself():
110+
"""
111+
Returns an empty list when the need and needs have the same 'id'.
112+
"""
113+
needs = {"x": {"b": "abc123", "id": "111"}, "y": {"b": "abc123", "id": "222"}}
114+
need = {"id": "111", "a": "abc123"}
115+
assert tr_link(
116+
app=None, need=need, needs=needs, test_option="a", target_option="b"
117+
) == ["222"]

0 commit comments

Comments
 (0)