Skip to content

Commit bdc04d9

Browse files
🧪 Add unit tests for Labels string parsing and fix edge cases
- Added unit tests for `Labels.parse` covering multiple labels, single labels, empty strings, and multiple spaces. - Fixed `Labels.parse` to gracefully handle empty strings and redundant whitespace. - Added a `conftest.py` in the new test directory to mock missing dependencies in restricted environments. Co-authored-by: rnovatorov <20299819+rnovatorov@users.noreply.github.com>
1 parent c311b04 commit bdc04d9

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

‎src/enapter/http/api/telemetry/labels.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ class Labels(collections.UserDict):
66

77
@classmethod
88
def parse(cls, s: str) -> Self:
9-
return cls(kv.split("=") for kv in s.split(" "))
9+
if not s:
10+
return cls()
11+
return cls(kv.split("=") for kv in s.split(" ") if kv)
1012

1113
@property
1214
def device(self) -> str:

‎tests/unit/test_http/test_api/test_telemetry/__init__.py‎

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sys
2+
from unittest.mock import MagicMock
3+
4+
# The enapter package's __init__.py imports all core submodules (async_, log, mdns, mqtt, http, standalone).
5+
# This means that importing even a small part of the package (like Labels) can trigger
6+
# imports of all dependencies. We mock these dependencies to allow unit tests to run in
7+
# environments where they are not installed.
8+
MOCKED_MODULES = [
9+
"json_log_formatter",
10+
"aiomqtt",
11+
"httpx",
12+
"dns",
13+
"dns.asyncresolver",
14+
"docker",
15+
]
16+
17+
for module_name in MOCKED_MODULES:
18+
if module_name not in sys.modules:
19+
sys.modules[module_name] = MagicMock()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from enapter.http.api.telemetry.labels import Labels
2+
3+
4+
def test_parse_multiple_labels():
5+
s = "device=foo telemetry=bar custom=baz"
6+
labels = Labels.parse(s)
7+
assert labels == {"device": "foo", "telemetry": "bar", "custom": "baz"}
8+
assert labels.device == "foo"
9+
assert labels.telemetry == "bar"
10+
11+
12+
def test_parse_single_label():
13+
s = "device=only"
14+
labels = Labels.parse(s)
15+
assert labels == {"device": "only"}
16+
assert labels.device == "only"
17+
18+
19+
def test_parse_empty_string():
20+
labels = Labels.parse("")
21+
assert labels == {}
22+
23+
24+
def test_parse_multiple_spaces():
25+
s = "device=foo telemetry=bar "
26+
labels = Labels.parse(s)
27+
assert labels == {"device": "foo", "telemetry": "bar"}

0 commit comments

Comments
 (0)