Add tests

This commit is contained in:
jbouwh 2025-05-21 18:28:03 +00:00
parent c77767024d
commit cb4c26dde8
3 changed files with 104 additions and 3 deletions

View File

@ -2,6 +2,8 @@
from __future__ import annotations from __future__ import annotations
from typing import Any
from astroid import nodes from astroid import nodes
from pylint.checkers import BaseChecker from pylint.checkers import BaseChecker
from pylint.lint import PyLinter from pylint.lint import PyLinter
@ -34,13 +36,33 @@ class HassEnforceGreekMicroCharChecker(BaseChecker):
self, target: nodes.NodeNG, node: nodes.Assign | nodes.AnnAssign self, target: nodes.NodeNG, node: nodes.Assign | nodes.AnnAssign
) -> None: ) -> None:
"""Check const assignment is not containing ANSI micro char.""" """Check const assignment is not containing ANSI micro char."""
def _check_const(node_const: nodes.Const | Any) -> bool:
if (
isinstance(node_const, nodes.Const)
and isinstance(node_const.value, str)
and "\u00b5" in node_const.value
):
self.add_message(self.name, node=node)
return True
return False
# Check constant assignments
if ( if (
isinstance(target, nodes.AssignName) isinstance(target, nodes.AssignName)
and isinstance(node.value, nodes.Const) and isinstance(node.value, nodes.Const)
and isinstance(node.value.value, str) and _check_const(node.value)
and "\u00b5" in node.value.value
): ):
self.add_message(self.name, node=node) return
# Check dict with EntityDescription calls
if isinstance(target, nodes.AssignName) and isinstance(node.value, nodes.Dict):
for _, subnode in node.value.items:
if not isinstance(subnode, nodes.Call):
continue
for keyword in subnode.keywords:
if _check_const(keyword.value):
return
def register(linter: PyLinter) -> None: def register(linter: PyLinter) -> None:

View File

@ -3755,6 +3755,34 @@ async def test_compile_hourly_statistics_convert_units_1(
30, 30,
), ),
(None, "m3", "", None, "volume", 13.050847, 13.333333, -10, 30), (None, "m3", "", None, "volume", 13.050847, 13.333333, -10, 30),
(None, "\u00b5V", "\u03bcV", None, "voltage", 13.050847, 13.333333, -10, 30),
(None, "\u00b5Sv/h", "\u03bcSv/h", None, None, 13.050847, 13.333333, -10, 30),
(
None,
"\u00b5S/cm",
"\u03bcS/cm",
None,
"conductivity",
13.050847,
13.333333,
-10,
30,
),
(None, "\u00b5g/ft³", "\u03bcg/ft³", None, None, 13.050847, 13.333333, -10, 30),
(None, "\u00b5g/m³", "\u03bcg/m³", None, None, 13.050847, 13.333333, -10, 30),
(
None,
"\u00b5mol/s⋅m²",
"\u03bcmol/s⋅m²",
None,
None,
13.050847,
13.333333,
-10,
30,
),
(None, "\u00b5g", "\u03bcg", None, "mass", 13.050847, 13.333333, -10, 30),
(None, "\u00b5s", "\u03bcs", None, "duration", 13.050847, 13.333333, -10, 30),
], ],
) )
async def test_compile_hourly_statistics_equivalent_units_1( async def test_compile_hourly_statistics_equivalent_units_1(
@ -5716,6 +5744,14 @@ async def test_validate_statistics_unit_change_no_conversion(
(NONE_SENSOR_ATTRIBUTES, "m3", ""), (NONE_SENSOR_ATTRIBUTES, "m3", ""),
(NONE_SENSOR_ATTRIBUTES, "rpm", "RPM"), (NONE_SENSOR_ATTRIBUTES, "rpm", "RPM"),
(NONE_SENSOR_ATTRIBUTES, "RPM", "rpm"), (NONE_SENSOR_ATTRIBUTES, "RPM", "rpm"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5V", "\u03bcV"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5Sv/h", "\u03bcSv/h"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5S/cm", "\u03bcS/cm"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5g/ft³", "\u03bcg/ft³"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5g/m³", "\u03bcg/m³"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5mol/s⋅m²", "\u03bcmol/s⋅m²"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5g", "\u03bcg"),
(NONE_SENSOR_ATTRIBUTES, "\u00b5s", "\u03bcs"),
], ],
) )
async def test_validate_statistics_unit_change_equivalent_units( async def test_validate_statistics_unit_change_equivalent_units(
@ -5779,6 +5815,14 @@ async def test_validate_statistics_unit_change_equivalent_units(
("attributes", "unit1", "unit2", "supported_unit"), ("attributes", "unit1", "unit2", "supported_unit"),
[ [
(NONE_SENSOR_ATTRIBUTES, "", "m3", "CCF, L, fl. oz., ft³, gal, mL, m³"), (NONE_SENSOR_ATTRIBUTES, "", "m3", "CCF, L, fl. oz., ft³, gal, mL, m³"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcV", "\u00b5V", "\u03bcV"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcSv/h", "\u00b5Sv/h", "\u03bcSv/h"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcS/cm", "\u00b5S/cm", "\u03bcS/cm"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcg/ft³", "\u00b5g/ft³", "\u03bcg/ft³"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcg/m³", "\u00b5g/m³", "\u03bcg/m³"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcmol/s⋅m²", "\u00b5mol/s⋅m²", "\u03bcmol/s⋅m²"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcg", "\u00b5g", "\u03bcg"),
(NONE_SENSOR_ATTRIBUTES, "\u03bcs", "\u00b5s", "\u03bcs"),
], ],
) )
async def test_validate_statistics_unit_change_equivalent_units_2( async def test_validate_statistics_unit_change_equivalent_units_2(

View File

@ -45,6 +45,25 @@ from . import assert_no_messages
""", """,
id="good_str_enum", id="good_str_enum",
), ),
pytest.param(
"""
SENSOR_DESCRIPTION = {
"radiation_rate": AranetSensorEntityDescription(
key="radiation_rate",
translation_key="radiation_rate",
name="Radiation Dose Rate",
native_unit_of_measurement="μSv/h", # "μ" == "\u03bc"
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=2,
scale=0.001,
),
}
OTHER_DICT = {
"value_with_bad_mu_should_pass": "µ"
}
""",
id="good_sensor_description",
),
], ],
) )
def test_enforce_greek_micro_char( def test_enforce_greek_micro_char(
@ -95,6 +114,22 @@ def test_enforce_greek_micro_char(
""", """,
id="bad_str_enum", id="bad_str_enum",
), ),
pytest.param(
"""
SENSOR_DESCRIPTION = {
"radiation_rate": AranetSensorEntityDescription(
key="radiation_rate",
translation_key="radiation_rate",
name="Radiation Dose Rate",
native_unit_of_measurement="µSv/h", # "μ" != "\u03bc"
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=2,
scale=0.001,
),
}
""",
id="bad_sensor_description",
),
], ],
) )
def test_enforce_greek_micro_char_assign_bad( def test_enforce_greek_micro_char_assign_bad(