mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 22:27:07 +00:00
Add missing conversion tests in unit conversion (#86434)
This commit is contained in:
parent
d0153f5031
commit
64535175b1
@ -102,95 +102,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
|
|||||||
VolumeConverter: (UnitOfVolume.GALLONS, UnitOfVolume.LITERS, 0.264172),
|
VolumeConverter: (UnitOfVolume.GALLONS, UnitOfVolume.LITERS, 0.264172),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Dict containing a conversion test for every know unit.
|
||||||
@pytest.mark.parametrize(
|
_CONVERTED_VALUE: dict[
|
||||||
"converter",
|
type[BaseUnitConverter], list[tuple[float, str | None, float, str | None]]
|
||||||
[
|
] = {
|
||||||
# Generate list of all converters available in
|
DataRateConverter: [
|
||||||
# `homeassistant.util.unit_conversion` to ensure
|
|
||||||
# that we don't miss any in the tests.
|
|
||||||
obj
|
|
||||||
for _, obj in inspect.getmembers(unit_conversion)
|
|
||||||
if inspect.isclass(obj)
|
|
||||||
and issubclass(obj, BaseUnitConverter)
|
|
||||||
and obj != BaseUnitConverter
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_all_converters(converter: type[BaseUnitConverter]) -> None:
|
|
||||||
"""Ensure all unit converters are tested."""
|
|
||||||
assert converter in _ALL_CONVERTERS, "converter is not present in _ALL_CONVERTERS"
|
|
||||||
assert converter in _GET_UNIT_RATIO, "converter is not present in _GET_UNIT_RATIO"
|
|
||||||
|
|
||||||
|
|
||||||
@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:
|
|
||||||
"""Test conversion from any valid unit to same unit."""
|
|
||||||
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:
|
|
||||||
"""Test exception is thrown for invalid units."""
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"converter,from_unit,to_unit",
|
|
||||||
[
|
|
||||||
# Pick any two units
|
|
||||||
(converter, valid_units[0], valid_units[1])
|
|
||||||
for converter, valid_units in _ALL_CONVERTERS.items()
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_convert_nonnumeric_value(
|
|
||||||
converter: type[BaseUnitConverter], from_unit: str, to_unit: str
|
|
||||||
) -> None:
|
|
||||||
"""Test exception is thrown for nonnumeric type."""
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
converter.convert("a", from_unit, to_unit)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"converter,from_unit,to_unit,expected",
|
|
||||||
[
|
|
||||||
(converter, item[0], item[1], item[2])
|
|
||||||
for converter, item in _GET_UNIT_RATIO.items()
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_get_unit_ratio(
|
|
||||||
converter: type[BaseUnitConverter], from_unit: str, to_unit: str, expected: float
|
|
||||||
) -> None:
|
|
||||||
"""Test unit ratio."""
|
|
||||||
ratio = converter.get_unit_ratio(from_unit, to_unit)
|
|
||||||
assert ratio == pytest.approx(expected)
|
|
||||||
assert converter.get_unit_ratio(to_unit, from_unit) == pytest.approx(1 / ratio)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(8e3, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.KILOBITS_PER_SECOND),
|
(8e3, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.KILOBITS_PER_SECOND),
|
||||||
(8e6, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.MEGABITS_PER_SECOND),
|
(8e6, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.MEGABITS_PER_SECOND),
|
||||||
(8e9, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.GIGABITS_PER_SECOND),
|
(8e9, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.GIGABITS_PER_SECOND),
|
||||||
@ -217,39 +133,7 @@ def test_get_unit_ratio(
|
|||||||
UnitOfDataRate.GIBIBYTES_PER_SECOND,
|
UnitOfDataRate.GIBIBYTES_PER_SECOND,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
DistanceConverter: [
|
||||||
def test_data_rate_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert DataRateConverter.convert(value, from_unit, to_unit) == pytest.approx(
|
|
||||||
expected
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(5, UnitOfElectricCurrent.AMPERE, 5000, UnitOfElectricCurrent.MILLIAMPERE),
|
|
||||||
(5, UnitOfElectricCurrent.MILLIAMPERE, 0.005, UnitOfElectricCurrent.AMPERE),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_electric_current_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert ElectricCurrentConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(5, UnitOfLength.MILES, 8.04672, UnitOfLength.KILOMETERS),
|
(5, UnitOfLength.MILES, 8.04672, UnitOfLength.KILOMETERS),
|
||||||
(5, UnitOfLength.MILES, 8046.72, UnitOfLength.METERS),
|
(5, UnitOfLength.MILES, 8046.72, UnitOfLength.METERS),
|
||||||
(5, UnitOfLength.MILES, 804672.0, UnitOfLength.CENTIMETERS),
|
(5, UnitOfLength.MILES, 804672.0, UnitOfLength.CENTIMETERS),
|
||||||
@ -307,21 +191,15 @@ def test_electric_current_convert(
|
|||||||
(5000000, UnitOfLength.MILLIMETERS, 16404.2, UnitOfLength.FEET),
|
(5000000, UnitOfLength.MILLIMETERS, 16404.2, UnitOfLength.FEET),
|
||||||
(5000000, UnitOfLength.MILLIMETERS, 196850.5, UnitOfLength.INCHES),
|
(5000000, UnitOfLength.MILLIMETERS, 196850.5, UnitOfLength.INCHES),
|
||||||
],
|
],
|
||||||
)
|
ElectricCurrentConverter: [
|
||||||
def test_distance_convert(
|
(5, UnitOfElectricCurrent.AMPERE, 5000, UnitOfElectricCurrent.MILLIAMPERE),
|
||||||
value: float,
|
(5, UnitOfElectricCurrent.MILLIAMPERE, 0.005, UnitOfElectricCurrent.AMPERE),
|
||||||
from_unit: str,
|
],
|
||||||
expected: float,
|
ElectricPotentialConverter: [
|
||||||
to_unit: str,
|
(5, UnitOfElectricPotential.VOLT, 5000, UnitOfElectricPotential.MILLIVOLT),
|
||||||
) -> None:
|
(5, UnitOfElectricPotential.MILLIVOLT, 0.005, UnitOfElectricPotential.VOLT),
|
||||||
"""Test conversion to other units."""
|
],
|
||||||
expected = pytest.approx(expected)
|
EnergyConverter: [
|
||||||
assert DistanceConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(10, UnitOfEnergy.WATT_HOUR, 0.01, UnitOfEnergy.KILO_WATT_HOUR),
|
(10, UnitOfEnergy.WATT_HOUR, 0.01, UnitOfEnergy.KILO_WATT_HOUR),
|
||||||
(10, UnitOfEnergy.WATT_HOUR, 0.00001, UnitOfEnergy.MEGA_WATT_HOUR),
|
(10, UnitOfEnergy.WATT_HOUR, 0.00001, UnitOfEnergy.MEGA_WATT_HOUR),
|
||||||
(10, UnitOfEnergy.KILO_WATT_HOUR, 10000, UnitOfEnergy.WATT_HOUR),
|
(10, UnitOfEnergy.KILO_WATT_HOUR, 10000, UnitOfEnergy.WATT_HOUR),
|
||||||
@ -331,20 +209,7 @@ def test_distance_convert(
|
|||||||
(10, UnitOfEnergy.GIGA_JOULE, 10000 / 3.6, UnitOfEnergy.KILO_WATT_HOUR),
|
(10, UnitOfEnergy.GIGA_JOULE, 10000 / 3.6, UnitOfEnergy.KILO_WATT_HOUR),
|
||||||
(10, UnitOfEnergy.GIGA_JOULE, 10 / 3.6, UnitOfEnergy.MEGA_WATT_HOUR),
|
(10, UnitOfEnergy.GIGA_JOULE, 10 / 3.6, UnitOfEnergy.MEGA_WATT_HOUR),
|
||||||
],
|
],
|
||||||
)
|
InformationConverter: [
|
||||||
def test_energy_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert EnergyConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(8e3, UnitOfInformation.BITS, 8, UnitOfInformation.KILOBITS),
|
(8e3, UnitOfInformation.BITS, 8, UnitOfInformation.KILOBITS),
|
||||||
(8e6, UnitOfInformation.BITS, 8, UnitOfInformation.MEGABITS),
|
(8e6, UnitOfInformation.BITS, 8, UnitOfInformation.MEGABITS),
|
||||||
(8e9, UnitOfInformation.BITS, 8, UnitOfInformation.GIGABITS),
|
(8e9, UnitOfInformation.BITS, 8, UnitOfInformation.GIGABITS),
|
||||||
@ -366,21 +231,7 @@ def test_energy_convert(
|
|||||||
(8 * 2**70, UnitOfInformation.BITS, 1, UnitOfInformation.ZEBIBYTES),
|
(8 * 2**70, UnitOfInformation.BITS, 1, UnitOfInformation.ZEBIBYTES),
|
||||||
(8 * 2**80, UnitOfInformation.BITS, 1, UnitOfInformation.YOBIBYTES),
|
(8 * 2**80, UnitOfInformation.BITS, 1, UnitOfInformation.YOBIBYTES),
|
||||||
],
|
],
|
||||||
)
|
MassConverter: [
|
||||||
def test_information_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
expected = pytest.approx(expected)
|
|
||||||
assert InformationConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(10, UnitOfMass.KILOGRAMS, 10000, UnitOfMass.GRAMS),
|
(10, UnitOfMass.KILOGRAMS, 10000, UnitOfMass.GRAMS),
|
||||||
(10, UnitOfMass.KILOGRAMS, 10000000, UnitOfMass.MILLIGRAMS),
|
(10, UnitOfMass.KILOGRAMS, 10000000, UnitOfMass.MILLIGRAMS),
|
||||||
(10, UnitOfMass.KILOGRAMS, 10000000000, UnitOfMass.MICROGRAMS),
|
(10, UnitOfMass.KILOGRAMS, 10000000000, UnitOfMass.MICROGRAMS),
|
||||||
@ -417,37 +268,11 @@ def test_information_convert(
|
|||||||
(1, UnitOfMass.STONES, 14, UnitOfMass.POUNDS),
|
(1, UnitOfMass.STONES, 14, UnitOfMass.POUNDS),
|
||||||
(1, UnitOfMass.STONES, 224, UnitOfMass.OUNCES),
|
(1, UnitOfMass.STONES, 224, UnitOfMass.OUNCES),
|
||||||
],
|
],
|
||||||
)
|
PowerConverter: [
|
||||||
def test_mass_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert MassConverter.convert(value, from_unit, to_unit) == pytest.approx(expected)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(10, UnitOfPower.KILO_WATT, 10000, UnitOfPower.WATT),
|
(10, UnitOfPower.KILO_WATT, 10000, UnitOfPower.WATT),
|
||||||
(10, UnitOfPower.WATT, 0.01, UnitOfPower.KILO_WATT),
|
(10, UnitOfPower.WATT, 0.01, UnitOfPower.KILO_WATT),
|
||||||
],
|
],
|
||||||
)
|
PressureConverter: [
|
||||||
def test_power_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert PowerConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(1000, UnitOfPressure.HPA, 14.5037743897, UnitOfPressure.PSI),
|
(1000, UnitOfPressure.HPA, 14.5037743897, UnitOfPressure.PSI),
|
||||||
(1000, UnitOfPressure.HPA, 29.5299801647, UnitOfPressure.INHG),
|
(1000, UnitOfPressure.HPA, 29.5299801647, UnitOfPressure.INHG),
|
||||||
(1000, UnitOfPressure.HPA, 100000, UnitOfPressure.PA),
|
(1000, UnitOfPressure.HPA, 100000, UnitOfPressure.PA),
|
||||||
@ -474,22 +299,9 @@ def test_power_convert(
|
|||||||
(30, UnitOfPressure.MMHG, 39.9967, UnitOfPressure.MBAR),
|
(30, UnitOfPressure.MMHG, 39.9967, UnitOfPressure.MBAR),
|
||||||
(30, UnitOfPressure.MMHG, 3.99967, UnitOfPressure.CBAR),
|
(30, UnitOfPressure.MMHG, 3.99967, UnitOfPressure.CBAR),
|
||||||
(30, UnitOfPressure.MMHG, 1.181102, UnitOfPressure.INHG),
|
(30, UnitOfPressure.MMHG, 1.181102, UnitOfPressure.INHG),
|
||||||
|
(5, UnitOfPressure.BAR, 72.51887, UnitOfPressure.PSI),
|
||||||
],
|
],
|
||||||
)
|
SpeedConverter: [
|
||||||
def test_pressure_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
expected = pytest.approx(expected)
|
|
||||||
assert PressureConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
# 5 km/h / 1.609 km/mi = 3.10686 mi/h
|
# 5 km/h / 1.609 km/mi = 3.10686 mi/h
|
||||||
(5, UnitOfSpeed.KILOMETERS_PER_HOUR, 3.106856, UnitOfSpeed.MILES_PER_HOUR),
|
(5, UnitOfSpeed.KILOMETERS_PER_HOUR, 3.106856, UnitOfSpeed.MILES_PER_HOUR),
|
||||||
# 5 mi/h * 1.609 km/mi = 8.04672 km/h
|
# 5 mi/h * 1.609 km/mi = 8.04672 km/h
|
||||||
@ -541,20 +353,7 @@ def test_pressure_convert(
|
|||||||
# 5 ft/s * 0.3048 m/ft = 1.524 m/s
|
# 5 ft/s * 0.3048 m/ft = 1.524 m/s
|
||||||
(5, UnitOfSpeed.FEET_PER_SECOND, 1.524, UnitOfSpeed.METERS_PER_SECOND),
|
(5, UnitOfSpeed.FEET_PER_SECOND, 1.524, UnitOfSpeed.METERS_PER_SECOND),
|
||||||
],
|
],
|
||||||
)
|
TemperatureConverter: [
|
||||||
def test_speed_convert(
|
|
||||||
value: float,
|
|
||||||
from_unit: str,
|
|
||||||
expected: float,
|
|
||||||
to_unit: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
assert SpeedConverter.convert(value, from_unit, to_unit) == pytest.approx(expected)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(100, UnitOfTemperature.CELSIUS, 212, UnitOfTemperature.FAHRENHEIT),
|
(100, UnitOfTemperature.CELSIUS, 212, UnitOfTemperature.FAHRENHEIT),
|
||||||
(100, UnitOfTemperature.CELSIUS, 373.15, UnitOfTemperature.KELVIN),
|
(100, UnitOfTemperature.CELSIUS, 373.15, UnitOfTemperature.KELVIN),
|
||||||
(100, UnitOfTemperature.FAHRENHEIT, 37.7778, UnitOfTemperature.CELSIUS),
|
(100, UnitOfTemperature.FAHRENHEIT, 37.7778, UnitOfTemperature.CELSIUS),
|
||||||
@ -562,37 +361,11 @@ def test_speed_convert(
|
|||||||
(100, UnitOfTemperature.KELVIN, -173.15, UnitOfTemperature.CELSIUS),
|
(100, UnitOfTemperature.KELVIN, -173.15, UnitOfTemperature.CELSIUS),
|
||||||
(100, UnitOfTemperature.KELVIN, -279.6699, UnitOfTemperature.FAHRENHEIT),
|
(100, UnitOfTemperature.KELVIN, -279.6699, UnitOfTemperature.FAHRENHEIT),
|
||||||
],
|
],
|
||||||
)
|
UnitlessRatioConverter: [
|
||||||
def test_temperature_convert(
|
(5, None, 500, PERCENTAGE),
|
||||||
value: float, from_unit: str, expected: float, to_unit: str
|
(5, PERCENTAGE, 0.05, None),
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
expected = pytest.approx(expected)
|
|
||||||
assert TemperatureConverter.convert(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(100, UnitOfTemperature.CELSIUS, 180, UnitOfTemperature.FAHRENHEIT),
|
|
||||||
(100, UnitOfTemperature.CELSIUS, 100, UnitOfTemperature.KELVIN),
|
|
||||||
(100, UnitOfTemperature.FAHRENHEIT, 55.5556, UnitOfTemperature.CELSIUS),
|
|
||||||
(100, UnitOfTemperature.FAHRENHEIT, 55.5556, UnitOfTemperature.KELVIN),
|
|
||||||
(100, UnitOfTemperature.KELVIN, 100, UnitOfTemperature.CELSIUS),
|
|
||||||
(100, UnitOfTemperature.KELVIN, 180, UnitOfTemperature.FAHRENHEIT),
|
|
||||||
],
|
],
|
||||||
)
|
VolumeConverter: [
|
||||||
def test_temperature_convert_with_interval(
|
|
||||||
value: float, from_unit: str, expected: float, to_unit: str
|
|
||||||
) -> None:
|
|
||||||
"""Test conversion to other units."""
|
|
||||||
expected = pytest.approx(expected)
|
|
||||||
assert TemperatureConverter.convert_interval(value, from_unit, to_unit) == expected
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value,from_unit,expected,to_unit",
|
|
||||||
[
|
|
||||||
(5, UnitOfVolume.LITERS, 1.32086, UnitOfVolume.GALLONS),
|
(5, UnitOfVolume.LITERS, 1.32086, UnitOfVolume.GALLONS),
|
||||||
(5, UnitOfVolume.GALLONS, 18.92706, UnitOfVolume.LITERS),
|
(5, UnitOfVolume.GALLONS, 18.92706, UnitOfVolume.LITERS),
|
||||||
(5, UnitOfVolume.CUBIC_METERS, 176.5733335, UnitOfVolume.CUBIC_FEET),
|
(5, UnitOfVolume.CUBIC_METERS, 176.5733335, UnitOfVolume.CUBIC_FEET),
|
||||||
@ -633,12 +406,142 @@ def test_temperature_convert_with_interval(
|
|||||||
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 3740.26, UnitOfVolume.GALLONS),
|
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 3740.26, UnitOfVolume.GALLONS),
|
||||||
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 14158.42, UnitOfVolume.LITERS),
|
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 14158.42, UnitOfVolume.LITERS),
|
||||||
],
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"converter",
|
||||||
|
[
|
||||||
|
# Generate list of all converters available in
|
||||||
|
# `homeassistant.util.unit_conversion` to ensure
|
||||||
|
# that we don't miss any in the tests.
|
||||||
|
obj
|
||||||
|
for _, obj in inspect.getmembers(unit_conversion)
|
||||||
|
if inspect.isclass(obj)
|
||||||
|
and issubclass(obj, BaseUnitConverter)
|
||||||
|
and obj != BaseUnitConverter
|
||||||
|
],
|
||||||
)
|
)
|
||||||
def test_volume_convert(
|
def test_all_converters(converter: type[BaseUnitConverter]) -> None:
|
||||||
|
"""Ensure all unit converters are tested."""
|
||||||
|
assert converter in _ALL_CONVERTERS, "converter is not present in _ALL_CONVERTERS"
|
||||||
|
|
||||||
|
assert converter in _GET_UNIT_RATIO, "converter is not present in _GET_UNIT_RATIO"
|
||||||
|
unit_ratio_item = _GET_UNIT_RATIO[converter]
|
||||||
|
assert unit_ratio_item[0] != unit_ratio_item[1], "ratio units should be different"
|
||||||
|
|
||||||
|
assert converter in _CONVERTED_VALUE, "converter is not present in _CONVERTED_VALUE"
|
||||||
|
converted_value_items = _CONVERTED_VALUE[converter]
|
||||||
|
for valid_unit in converter.VALID_UNITS:
|
||||||
|
assert any(
|
||||||
|
item
|
||||||
|
for item in converted_value_items
|
||||||
|
# item[1] is from_unit, item[3] is to_unit
|
||||||
|
if valid_unit in {item[1], item[3]}
|
||||||
|
), 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:
|
||||||
|
"""Test conversion from any valid unit to same unit."""
|
||||||
|
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:
|
||||||
|
"""Test exception is thrown for invalid units."""
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"converter,from_unit,to_unit",
|
||||||
|
[
|
||||||
|
# Pick any two units
|
||||||
|
(converter, valid_units[0], valid_units[1])
|
||||||
|
for converter, valid_units in _ALL_CONVERTERS.items()
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_convert_nonnumeric_value(
|
||||||
|
converter: type[BaseUnitConverter], from_unit: str, to_unit: str
|
||||||
|
) -> None:
|
||||||
|
"""Test exception is thrown for nonnumeric type."""
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
converter.convert("a", from_unit, to_unit)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"converter,from_unit,to_unit,expected",
|
||||||
|
[
|
||||||
|
# Process all items in _GET_UNIT_RATIO
|
||||||
|
(converter, item[0], item[1], item[2])
|
||||||
|
for converter, item in _GET_UNIT_RATIO.items()
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_get_unit_ratio(
|
||||||
|
converter: type[BaseUnitConverter], from_unit: str, to_unit: str, expected: float
|
||||||
|
) -> None:
|
||||||
|
"""Test unit ratio."""
|
||||||
|
ratio = converter.get_unit_ratio(from_unit, to_unit)
|
||||||
|
assert ratio == pytest.approx(expected)
|
||||||
|
assert converter.get_unit_ratio(to_unit, from_unit) == pytest.approx(1 / ratio)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"converter,value,from_unit,expected,to_unit",
|
||||||
|
[
|
||||||
|
# Process all items in _CONVERTED_VALUE
|
||||||
|
(converter, list_item[0], list_item[1], list_item[2], list_item[3])
|
||||||
|
for converter, item in _CONVERTED_VALUE.items()
|
||||||
|
for list_item in item
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_unit_conversion(
|
||||||
|
converter: type[BaseUnitConverter],
|
||||||
value: float,
|
value: float,
|
||||||
from_unit: str,
|
from_unit: str,
|
||||||
expected: float,
|
expected: float,
|
||||||
to_unit: str,
|
to_unit: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test conversion to other units."""
|
"""Test conversion to other units."""
|
||||||
assert VolumeConverter.convert(value, from_unit, to_unit) == pytest.approx(expected)
|
assert converter.convert(value, from_unit, to_unit) == pytest.approx(expected)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value,from_unit,expected,to_unit",
|
||||||
|
[
|
||||||
|
(100, UnitOfTemperature.CELSIUS, 180, UnitOfTemperature.FAHRENHEIT),
|
||||||
|
(100, UnitOfTemperature.CELSIUS, 100, UnitOfTemperature.KELVIN),
|
||||||
|
(100, UnitOfTemperature.FAHRENHEIT, 55.5556, UnitOfTemperature.CELSIUS),
|
||||||
|
(100, UnitOfTemperature.FAHRENHEIT, 55.5556, UnitOfTemperature.KELVIN),
|
||||||
|
(100, UnitOfTemperature.KELVIN, 100, UnitOfTemperature.CELSIUS),
|
||||||
|
(100, UnitOfTemperature.KELVIN, 180, UnitOfTemperature.FAHRENHEIT),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_temperature_convert_with_interval(
|
||||||
|
value: float, from_unit: str, expected: float, to_unit: str
|
||||||
|
) -> None:
|
||||||
|
"""Test conversion to other units."""
|
||||||
|
expected = pytest.approx(expected)
|
||||||
|
assert TemperatureConverter.convert_interval(value, from_unit, to_unit) == expected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user