music-assistant-server

2.4 KBPY
helpers.py
2.4 KB69 lines • python
1"""Helper functions for nicovideo tests."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING, TypeVar
6from unittest.mock import Mock
7
8from music_assistant.providers.nicovideo.converters.manager import NicovideoConverterManager
9from tests.providers.nicovideo.types import JsonDict
10
11if TYPE_CHECKING:
12    from mashumaro import DataClassDictMixin
13    from pydantic import JsonValue
14
15T = TypeVar("T")
16
17
18def create_converter_manager() -> NicovideoConverterManager:
19    """Create a NicovideoConverterManager for testing."""
20    # Create mock provider
21    mock_provider = Mock()
22    mock_provider.instance_id = "nicovideo_test"
23    mock_provider.domain = "nicovideo"
24
25    # Create mock logger
26    mock_logger = Mock()
27
28    return NicovideoConverterManager(mock_provider, mock_logger)
29
30
31def sort_dict_keys_and_lists(obj: JsonValue) -> JsonValue:
32    """Sort dictionary keys and list elements for consistent snapshot comparison.
33
34    This function ensures deterministic ordering by:
35    - Sorting dictionary keys alphabetically
36    - Sorting list elements by type and string representation
37
38    Particularly useful for handling serialized sets that would otherwise have
39    random ordering between test runs.
40    """
41    if isinstance(obj, dict):
42        # Sort dictionary keys and recursively process values
43        return {key: sort_dict_keys_and_lists(obj[key]) for key in sorted(obj.keys())}
44    if isinstance(obj, list):
45        # Recursively process list items first
46        sorted_items = [sort_dict_keys_and_lists(item) for item in obj]
47        try:
48            # Sort items for deterministic ordering (handles serialized sets)
49            return sorted(sorted_items, key=lambda x: (type(x).__name__, str(x)))
50        except (TypeError, ValueError):
51            # If sorting fails, return in original order
52            return sorted_items
53    else:
54        # Return primitive values as-is
55        return obj
56
57
58def to_dict_for_snapshot(media_item: DataClassDictMixin) -> JsonDict:
59    """Convert DataClassDictMixin to dict with sorted keys and lists for snapshot comparison."""
60    # Get the standard to_dict representation
61    item_dict = media_item.to_dict()
62
63    # Recursively sort all nested structures, especially sets
64    sorted_result = sort_dict_keys_and_lists(item_dict)
65
66    # Ensure we return the expected dict type
67    assert isinstance(sorted_result, dict)
68    return sorted_result
69