|
10 | 10 |
|
11 | 11 | zhaquirks.setup()
|
12 | 12 |
|
13 |
| - |
14 |
| -ALL_QUIRK_V2_CLASSES: list[QuirksV2RegistryEntry] = list( |
| 13 | +# zigpy registry v2 contains duplicates (due to being keyed by manufacturer and model), |
| 14 | +# so to avoid duplicates but maintain insertion order, we use a dict instead of a set |
| 15 | +ALL_QUIRK_V2_CLASSES: dict[QuirksV2RegistryEntry, None] = dict.fromkeys( |
15 | 16 | itertools.chain.from_iterable(zigpy.quirks.DEVICE_REGISTRY.registry_v2.values())
|
16 | 17 | )
|
17 | 18 |
|
@@ -46,3 +47,26 @@ def test_translation_key_and_fallback_name_match() -> None:
|
46 | 47 | assert (
|
47 | 48 | len(set(fallback_names)) == 1
|
48 | 49 | ), f"Translation key '{translation_key}' is shared by quirks with different fallback names: {quirk_locations}"
|
| 50 | + |
| 51 | + |
| 52 | +def test_manufacturer_model_metadata_unique() -> None: |
| 53 | + """Ensure that each manufacturer-model pair is unique across all v2 quirks.""" |
| 54 | + # quirk_locations are a list and not a set below, |
| 55 | + # as they are not guaranteed to be unique when set up incorrectly |
| 56 | + |
| 57 | + # (manufacturer, model) -> {quirk_location} |
| 58 | + man_model_quirk_map: dict[tuple[str, str], list[str]] = collections.defaultdict( |
| 59 | + list |
| 60 | + ) |
| 61 | + |
| 62 | + for quirk in ALL_QUIRK_V2_CLASSES: |
| 63 | + for metadata in quirk.manufacturer_model_metadata: |
| 64 | + man_model_quirk_map[(metadata.manufacturer, metadata.model)].append( |
| 65 | + f"{quirk.quirk_file}:{quirk.quirk_file_line}" |
| 66 | + ) |
| 67 | + |
| 68 | + # check that each manufacturer-model pair is unique |
| 69 | + for (manufacturer, model), quirk_locations in man_model_quirk_map.items(): |
| 70 | + assert ( |
| 71 | + len(quirk_locations) == 1 |
| 72 | + ), f"Manufacturer-model pair '{manufacturer}' '{model}' is shared by multiple quirks: {quirk_locations}" |
0 commit comments