Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed Aug 15, 2023
1 parent 80c5120 commit 38dd2bf
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 16 deletions.
21 changes: 11 additions & 10 deletions homeassistant/components/weather/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,16 +352,17 @@ def __init_subclass__(cls, **kwargs: Any) -> None:
cls.__name__,
report_issue,
)
if any(method in cls.__dict__ for method in ("_attr_forecast", "forecast")):
if not any(
method in cls.__dict__
for method in (
"async_forecast_daily",
"async_forecast_hourly",
"async_forecast_twice_daily",
)
):
cls.__weather_legacy_forecast = True
if any(
method in cls.__dict__ for method in ("_attr_forecast", "forecast")
) and not any(
method in cls.__dict__
for method in (
"async_forecast_daily",
"async_forecast_hourly",
"async_forecast_twice_daily",
)
):
cls.__weather_legacy_forecast = True

@callback
def add_to_platform_start(
Expand Down
16 changes: 10 additions & 6 deletions tests/components/weather/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
from . import create_entity

from tests.testing_config.custom_components.test import weather as WeatherPlatform
from tests.testing_config.custom_components.test_weather import (
weather as NewWeatherPlatform,
)
from tests.typing import WebSocketGenerator


Expand Down Expand Up @@ -1286,27 +1289,28 @@ async def test_issue_forecast_deprecated_no_logging(
"native_temperature": 38,
"native_temperature_unit": UnitOfTemperature.CELSIUS,
}
platform: WeatherPlatform = getattr(hass.components, "test.weather")
platform: NewWeatherPlatform = getattr(hass.components, "test_weather.weather")
caplog.clear()
platform.init(empty=True)
platform.ENTITIES.append(
platform.MockWeatherMockLegacyForecastOnly(
name="Testing",
entity_id="weather.testing",
platform.MockWeatherMockForecast(
name="Test",
entity_id="weather.test",
condition=ATTR_CONDITION_SUNNY,
**kwargs,
)
)

entity0 = platform.ENTITIES[0]
assert await async_setup_component(
hass, "weather", {"weather": {"platform": "test", "name": "testing"}}
hass, "weather", {"weather": {"platform": "test_weather", "name": "test"}}
)
await hass.async_block_till_done()

assert entity0.state == ATTR_CONDITION_SUNNY

assert "Setting up weather.test_weather" in caplog.text
assert (
"custom_components.test.weather::weather.testing2 is using a forecast attribute on an instance of WeatherEntity"
"custom_components.test_weather.weather::weather.test is using a forecast attribute on an instance of WeatherEntity"
not in caplog.text
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""An integration with Weather platform."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"domain": "test_weather",
"name": "Test Weather",
"documentation": "http://example.com",
"requirements": [],
"dependencies": [],
"codeowners": [],
"version": "1.2.3"
}
210 changes: 210 additions & 0 deletions tests/testing_config/custom_components/test_weather/weather.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
"""Provide a mock weather platform.
Call init before using it in your tests to ensure clean test data.
"""
from __future__ import annotations

from typing import Any

from homeassistant.components.weather import (
ATTR_FORECAST_CLOUD_COVERAGE,
ATTR_FORECAST_HUMIDITY,
ATTR_FORECAST_IS_DAYTIME,
ATTR_FORECAST_NATIVE_APPARENT_TEMP,
ATTR_FORECAST_NATIVE_DEW_POINT,
ATTR_FORECAST_NATIVE_PRECIPITATION,
ATTR_FORECAST_NATIVE_PRESSURE,
ATTR_FORECAST_NATIVE_TEMP,
ATTR_FORECAST_NATIVE_TEMP_LOW,
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED,
ATTR_FORECAST_NATIVE_WIND_SPEED,
ATTR_FORECAST_UV_INDEX,
ATTR_FORECAST_WIND_BEARING,
Forecast,
WeatherEntity,
)

from tests.common import MockEntity

ENTITIES = []


def init(empty=False):
"""Initialize the platform with entities."""
global ENTITIES
ENTITIES = [] if empty else [MockWeatherMockForecast()]


async def async_setup_platform(
hass, config, async_add_entities_callback, discovery_info=None
):
"""Return mock entities."""
async_add_entities_callback(ENTITIES)


class MockWeatherMockForecast(MockEntity, WeatherEntity):
"""Mock weather class."""

def __init__(self, **values: Any) -> None:
"""Initialize."""
super().__init__(**values)
self.forecast_list: list[Forecast] | None = [
{
ATTR_FORECAST_NATIVE_TEMP: self.native_temperature,
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point,
ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage,
ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure,
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed,
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
ATTR_FORECAST_UV_INDEX: self.uv_index,
ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get(
"native_precipitation"
),
ATTR_FORECAST_HUMIDITY: self.humidity,
}
]

@property
def forecast(self) -> list[Forecast] | None:
"""Return the forecast."""
return self.forecast_list

async def async_forecast_daily(self) -> list[Forecast] | None:
"""Return the forecast_daily."""
return self.forecast_list

async def async_forecast_twice_daily(self) -> list[Forecast] | None:
"""Return the forecast_twice_daily."""
return [
{
ATTR_FORECAST_NATIVE_TEMP: self.native_temperature,
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point,
ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage,
ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure,
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed,
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
ATTR_FORECAST_UV_INDEX: self.uv_index,
ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get(
"native_precipitation"
),
ATTR_FORECAST_HUMIDITY: self.humidity,
ATTR_FORECAST_IS_DAYTIME: self._values.get("is_daytime"),
}
]

async def async_forecast_hourly(self) -> list[Forecast] | None:
"""Return the forecast_hourly."""
return [
{
ATTR_FORECAST_NATIVE_TEMP: self.native_temperature,
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point,
ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage,
ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure,
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed,
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
ATTR_FORECAST_UV_INDEX: self.uv_index,
ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get(
"native_precipitation"
),
ATTR_FORECAST_HUMIDITY: self.humidity,
}
]

@property
def native_temperature(self) -> float | None:
"""Return the platform temperature."""
return self._handle("native_temperature")

@property
def native_apparent_temperature(self) -> float | None:
"""Return the platform apparent temperature."""
return self._handle("native_apparent_temperature")

@property
def native_dew_point(self) -> float | None:
"""Return the platform dewpoint temperature."""
return self._handle("native_dew_point")

@property
def native_temperature_unit(self) -> str | None:
"""Return the unit of measurement for temperature."""
return self._handle("native_temperature_unit")

@property
def native_pressure(self) -> float | None:
"""Return the pressure."""
return self._handle("native_pressure")

@property
def native_pressure_unit(self) -> str | None:
"""Return the unit of measurement for pressure."""
return self._handle("native_pressure_unit")

@property
def humidity(self) -> float | None:
"""Return the humidity."""
return self._handle("humidity")

@property
def native_wind_gust_speed(self) -> float | None:
"""Return the wind speed."""
return self._handle("native_wind_gust_speed")

@property
def native_wind_speed(self) -> float | None:
"""Return the wind speed."""
return self._handle("native_wind_speed")

@property
def native_wind_speed_unit(self) -> str | None:
"""Return the unit of measurement for wind speed."""
return self._handle("native_wind_speed_unit")

@property
def wind_bearing(self) -> float | str | None:
"""Return the wind bearing."""
return self._handle("wind_bearing")

@property
def ozone(self) -> float | None:
"""Return the ozone level."""
return self._handle("ozone")

@property
def cloud_coverage(self) -> float | None:
"""Return the cloud coverage in %."""
return self._handle("cloud_coverage")

@property
def uv_index(self) -> float | None:
"""Return the UV index."""
return self._handle("uv_index")

@property
def native_visibility(self) -> float | None:
"""Return the visibility."""
return self._handle("native_visibility")

@property
def native_visibility_unit(self) -> str | None:
"""Return the unit of measurement for visibility."""
return self._handle("native_visibility_unit")

@property
def native_precipitation_unit(self) -> str | None:
"""Return the native unit of measurement for accumulated precipitation."""
return self._handle("native_precipitation_unit")

@property
def condition(self) -> str | None:
"""Return the current condition."""
return self._handle("condition")

0 comments on commit 38dd2bf

Please sign in to comment.