From 82027488497b862ec9c81ab9e866c6ee5c39f096 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 30 Aug 2026 20:05:16 +0200 Subject: [PATCH] Iterate the unit conversion tables instead of parametrizing each row (#180460) Co-authored-by: Franck Nijhof --- tests/util/test_unit_conversion.py | 120 ++++++++--------------------- 1 file changed, 31 insertions(+), 89 deletions(-) diff --git a/tests/util/test_unit_conversion.py b/tests/util/test_unit_conversion.py index a729c43dd46d..f37011646f11 100644 --- a/tests/util/test_unit_conversion.py +++ b/tests/util/test_unit_conversion.py @@ -1,7 +1,6 @@ """Test Home Assistant unit conversion utility functions.""" import inspect -from itertools import chain import pytest @@ -1282,38 +1281,22 @@ def test_all_converters(converter: type[BaseUnitConverter]) -> None: ), f"Unit `{valid_unit}` is not tested in _CONVERTED_VALUE" -@pytest.mark.parametrize( - ("converter", "valid_unit"), - [ - # Ensure all units are tested - (converter, valid_unit) - for converter, valid_units in _ALL_CONVERTERS.items() - for valid_unit in valid_units - ], -) -def test_convert_same_unit(converter: type[BaseUnitConverter], valid_unit: str) -> None: +@pytest.mark.parametrize("converter", _ALL_CONVERTERS) +def test_convert_same_unit(converter: type[BaseUnitConverter]) -> None: """Test conversion from any valid unit to same unit.""" - assert converter.convert(2, valid_unit, valid_unit) == 2 + for valid_unit in _ALL_CONVERTERS[converter]: + assert converter.convert(2, valid_unit, valid_unit) == 2 -@pytest.mark.parametrize( - ("converter", "valid_unit"), - [ - # Ensure all units are tested - (converter, valid_unit) - for converter, valid_units in _ALL_CONVERTERS.items() - for valid_unit in valid_units - ], -) -def test_convert_invalid_unit( - converter: type[BaseUnitConverter], valid_unit: str -) -> None: +@pytest.mark.parametrize("converter", _ALL_CONVERTERS) +def test_convert_invalid_unit(converter: type[BaseUnitConverter]) -> None: """Test exception is thrown for invalid units.""" - with pytest.raises(HomeAssistantError, match="is not a recognized .* unit"): - converter.convert(5, INVALID_SYMBOL, valid_unit) + for valid_unit in _ALL_CONVERTERS[converter]: + with pytest.raises(HomeAssistantError, match="is not a recognized .* unit"): + converter.convert(5, INVALID_SYMBOL, valid_unit) - with pytest.raises(HomeAssistantError, match="is not a recognized .* unit"): - converter.convert(5, valid_unit, INVALID_SYMBOL) + with pytest.raises(HomeAssistantError, match="is not a recognized .* unit"): + converter.convert(5, valid_unit, INVALID_SYMBOL) @pytest.mark.parametrize( @@ -1370,46 +1353,22 @@ def get_unit_floored_log_ratio( assert converter.get_unit_floored_log_ratio(to_unit, from_unit) == 1 / ratio -@pytest.mark.parametrize( - ("converter", "value", "from_unit", "expected", "to_unit"), - [ - # Process all items in _CONVERTED_VALUE - (converter, value, from_unit, expected, to_unit) - for converter, item in _CONVERTED_VALUE.items() - for value, from_unit, expected, to_unit in item - ], -) -def test_unit_conversion( - converter: type[BaseUnitConverter], - value: float, - from_unit: str, - expected: float, - to_unit: str, -) -> None: +@pytest.mark.parametrize("converter", _CONVERTED_VALUE) +def test_unit_conversion(converter: type[BaseUnitConverter]) -> None: """Test conversion to other units.""" - assert converter.convert(value, from_unit, to_unit) == pytest.approx(expected) + for value, from_unit, expected, to_unit in _CONVERTED_VALUE[converter]: + assert converter.convert(value, from_unit, to_unit) == pytest.approx( + expected + ), f"{value} {from_unit} to {to_unit}" -@pytest.mark.parametrize( - ("converter", "value", "from_unit", "expected", "to_unit"), - [ - # Process all items in _CONVERTED_VALUE - (converter, value, from_unit, expected, to_unit) - for converter, item in _CONVERTED_VALUE.items() - for value, from_unit, expected, to_unit in item - ], -) -def test_unit_conversion_factory( - converter: type[BaseUnitConverter], - value: float, - from_unit: str, - expected: float, - to_unit: str, -) -> None: +@pytest.mark.parametrize("converter", _CONVERTED_VALUE) +def test_unit_conversion_factory(converter: type[BaseUnitConverter]) -> None: """Test conversion to other units.""" - assert converter.converter_factory(from_unit, to_unit)(value) == pytest.approx( - expected - ) + for value, from_unit, expected, to_unit in _CONVERTED_VALUE[converter]: + assert converter.converter_factory(from_unit, to_unit)(value) == pytest.approx( + expected + ), f"{value} {from_unit} to {to_unit}" def test_unit_conversion_factory_allow_none_with_none() -> None: @@ -1504,34 +1463,17 @@ def test_unit_conversion_factory_allow_none_with_zero_for_inverse_units() -> Non )(25) == pytest.approx(4) -@pytest.mark.parametrize( - ("converter", "value", "from_unit", "expected", "to_unit"), - chain( - [ - # Process all items in _CONVERTED_VALUE - (converter, value, from_unit, expected, to_unit) - for converter, item in _CONVERTED_VALUE.items() - for value, from_unit, expected, to_unit in item - ], - [ - # Process all items in _CONVERTED_VALUE and replace the value with None - (converter, None, from_unit, None, to_unit) - for converter, item in _CONVERTED_VALUE.items() - for value, from_unit, expected, to_unit in item - ], - ), -) +@pytest.mark.parametrize("converter", _CONVERTED_VALUE) def test_unit_conversion_factory_allow_none( converter: type[BaseUnitConverter], - value: float, - from_unit: str, - expected: float, - to_unit: str, ) -> None: - """Test conversion to other units.""" - assert converter.converter_factory_allow_none(from_unit, to_unit)( - value - ) == pytest.approx(expected) + """Test conversion to other units, and that None is passed through.""" + for value, from_unit, expected, to_unit in _CONVERTED_VALUE[converter]: + convert = converter.converter_factory_allow_none(from_unit, to_unit) + assert convert(value) == pytest.approx(expected), ( + f"{value} {from_unit} to {to_unit}" + ) + assert convert(None) is None, f"None {from_unit} to {to_unit}" @pytest.mark.parametrize(