Skip to content

Commit 868d9cb

Browse files
committed
Add tests for DLC pose metadata loading
Expand `test_dlc_processor.py` with focused unit tests for `_load_pose_metadata_from_dlc_config()`. The new cases verify successful loading of bodyparts/skeleton/task metadata, clearing of stale metadata when config is empty, support for bodyparts without skeleton data, and validation failures for duplicate bodyparts and skeleton links to unknown bodyparts.
1 parent 27e7fa5 commit 868d9cb

1 file changed

Lines changed: 96 additions & 3 deletions

File tree

‎tests/services/test_dlc_processor.py‎

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import queue
44
import threading
5+
from types import SimpleNamespace
56

67
import numpy as np
78
import pytest
@@ -10,9 +11,7 @@
1011

1112
# from dlclivegui.config import DLCProcessorSettings
1213
from dlclivegui.processors.processor_utils import ProcessorSpec
13-
from dlclivegui.services.dlc_processor import (
14-
DLCLiveProcessor,
15-
)
14+
from dlclivegui.services.dlc_processor import DLCLiveProcessor
1615
from dlclivegui.services.inference.base import (
1716
ProcessorStats,
1817
WorkerState,
@@ -385,3 +384,97 @@ def test_queue_accounting_clears_after_processed_frame(qtbot, monkeypatch_dlcliv
385384

386385
finally:
387386
proc.reset()
387+
388+
389+
def test_load_pose_metadata_from_dlc_config() -> None:
390+
processor = DLCLiveProcessor()
391+
processor._dlc = SimpleNamespace(
392+
cfg={
393+
"Task": "mouse",
394+
"bodyparts": [
395+
"nose",
396+
"shoulder",
397+
"tail",
398+
],
399+
"skeleton": [
400+
["nose", "shoulder"],
401+
["shoulder", "tail"],
402+
],
403+
}
404+
)
405+
406+
processor._load_pose_metadata_from_dlc_config()
407+
408+
assert processor._keypoint_names == (
409+
"nose",
410+
"shoulder",
411+
"tail",
412+
)
413+
assert processor._skeleton_id == "deeplabcut.mouse"
414+
assert processor._skeleton_edges == (
415+
("nose", "shoulder"),
416+
("shoulder", "tail"),
417+
)
418+
419+
420+
def test_metadata_loader_clears_stale_metadata() -> None:
421+
processor = DLCLiveProcessor()
422+
processor._keypoint_names = ("stale",)
423+
processor._skeleton_id = "stale"
424+
processor._skeleton_edges = (("stale", "other"),)
425+
processor._dlc = SimpleNamespace(cfg={})
426+
427+
processor._load_pose_metadata_from_dlc_config()
428+
429+
assert processor._keypoint_names is None
430+
assert processor._skeleton_id is None
431+
assert processor._skeleton_edges is None
432+
433+
434+
def test_metadata_loader_allows_bodyparts_without_skeleton() -> None:
435+
processor = DLCLiveProcessor()
436+
processor._dlc = SimpleNamespace(
437+
cfg={
438+
"bodyparts": ["nose", "tail"],
439+
}
440+
)
441+
442+
processor._load_pose_metadata_from_dlc_config()
443+
444+
assert processor._keypoint_names == (
445+
"nose",
446+
"tail",
447+
)
448+
assert processor._skeleton_id is None
449+
assert processor._skeleton_edges is None
450+
451+
452+
def test_metadata_loader_rejects_duplicate_bodyparts() -> None:
453+
processor = DLCLiveProcessor()
454+
processor._dlc = SimpleNamespace(
455+
cfg={
456+
"bodyparts": ["nose", "nose"],
457+
}
458+
)
459+
460+
with pytest.raises(
461+
RuntimeError,
462+
match="duplicate",
463+
):
464+
processor._load_pose_metadata_from_dlc_config()
465+
466+
467+
def test_metadata_loader_rejects_unknown_skeleton_endpoint() -> None:
468+
processor = DLCLiveProcessor()
469+
processor._dlc = SimpleNamespace(
470+
cfg={
471+
"bodyparts": ["nose", "tail"],
472+
"skeleton": [["nose", "shoulder"]],
473+
}
474+
)
475+
476+
with pytest.raises(
477+
RuntimeError,
478+
match="unknown bodypart",
479+
):
480+
processor._load_pose_metadata_from_dlc_config()

0 commit comments

Comments
 (0)