From de771f207048683f4d90857b1c61d5cdb4b50f35 Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:03:57 +0400 Subject: [PATCH 1/7] Added CapitalDTO model Added area in CountryDTO Added visibility in WeatherDTO Added CapitalDTO in LocationInfoDTO --- src/collectors/models.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/collectors/models.py b/src/collectors/models.py index 7e36198..454ef28 100644 --- a/src/collectors/models.py +++ b/src/collectors/models.py @@ -60,6 +60,28 @@ class LanguagesInfoDTO(HashableBaseModel): native_name: str +class CapitalDTO(BaseModel): + """ + Модель данных о столице. + + .. code-block:: + + CapitalDTO( + name="Moscow", + longitude=55.75, + latitude=37.62, + timezone="Europe/Moscow", + current_time="22:33:51 on Thursday, February 16, 2023" + ) + """ + + name: str + longitude: float | None + latitude: float | None + timezone: str | None + current_time: str | None + + class CountryDTO(BaseModel): """ Модель данных о стране. @@ -89,6 +111,7 @@ class CountryDTO(BaseModel): }, name="\u00c5land Islands", population=28875, + area=17124442.0, subregion="Northern Europe", timezones=[ "UTC+02:00", @@ -104,6 +127,7 @@ class CountryDTO(BaseModel): languages: set[LanguagesInfoDTO] name: str population: int + area: float | None subregion: str timezones: list[str] @@ -140,6 +164,7 @@ class WeatherInfoDTO(BaseModel): humidity=54, wind_speed=4.63, description="scattered clouds", + visibility="3161.0" ) """ @@ -148,6 +173,7 @@ class WeatherInfoDTO(BaseModel): humidity: int wind_speed: float description: str + visibility: float class LocationInfoDTO(BaseModel): @@ -180,11 +206,19 @@ class LocationInfoDTO(BaseModel): }, name="\u00c5land Islands", population=28875, + area=17124442.0, subregion="Northern Europe", timezones=[ "UTC+02:00", ], ), + capital=CapitalDTO( + name="Moscow", + longitude=55.75, + latitude=37.62, + timezone="Europe/Moscow", + current_time="22:33:51 on Thursday, February 16, 2023" + ), weather=WeatherInfoDTO( temp=13.92, pressure=1023, @@ -199,5 +233,6 @@ class LocationInfoDTO(BaseModel): """ location: CountryDTO + capital: CapitalDTO weather: WeatherInfoDTO currency_rates: dict[str, float] From b74d71ad3cba97909473c302221af274c2fd8355 Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:04:34 +0400 Subject: [PATCH 2/7] Added capital collecting information --- requirements.txt | 6 +++ src/collectors/collector.py | 81 ++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 138eaea..86fc974 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ sphinx-rtd-theme>=1.0.0,<2.0.0 asyncclick>=8.1.3.2,<8.2.0 colorama>=0.4.5,<0.5.0 anyio>=3.6.1,<3.7.0 +prettytable>=3.6.0 # работа с Excel-файлами openpyxl>=3.0.10,<3.1.0 @@ -35,3 +36,8 @@ mypy>=0.971,<1.0 # автоматическое форматирование кода black>=22.8.0,<22.9.0 + +# Определение часового пояса +timezonefinder>=6.1.9 +pytz>=2022.1 +geopy>=2.3.0 \ No newline at end of file diff --git a/src/collectors/collector.py b/src/collectors/collector.py index ebadf7e..783a557 100644 --- a/src/collectors/collector.py +++ b/src/collectors/collector.py @@ -1,16 +1,19 @@ """ Функции сбора информации о странах. """ - from __future__ import annotations import asyncio import json +from datetime import datetime from typing import Any, Optional, FrozenSet +from timezonefinder import TimezoneFinder +from geopy.geocoders import Nominatim + import aiofiles import aiofiles.os - +import pytz from clients.country import CountryClient from clients.currency import CurrencyClient from clients.weather import WeatherClient @@ -18,6 +21,7 @@ from collectors.models import ( LocationDTO, CountryDTO, + CapitalDTO, CurrencyRatesDTO, CurrencyInfoDTO, WeatherInfoDTO, @@ -101,6 +105,7 @@ async def read(cls) -> Optional[list[CountryDTO]]: languages=item["languages"], name=item["name"], population=item["population"], + area=item["area"], subregion=item["subregion"], timezones=item["timezones"], ) @@ -111,6 +116,77 @@ async def read(cls) -> Optional[list[CountryDTO]]: return None +class CapitalCollector: + """ + Сбор информации о столице (географическое описание). + """ + + @classmethod + def get_timezone( + cls, latitude: float | None, longitude: float | None + ) -> str | None: + """ + Получение часового пояса по координатам. + + :param latitude: Широта + :param longitude: Долгота + :return: Часовой пояс или None, если не найден + """ + if longitude is None or latitude is None: + return None + return TimezoneFinder().timezone_at(lng=longitude, lat=latitude) + + @classmethod + async def get_coordinates(cls, city: str) -> tuple[float | None, float | None]: + """ + Получение координат по названию столицы. + + :param city: Название столицы + :return: Координаты или None, None, если не найдены + """ + geolocator = Nominatim(user_agent="geoapiExercises") + location = geolocator.geocode(city) + if location is not None: + return location.latitude, location.longitude + return None, None + + @classmethod + def capital_time( + cls, latitude: float | None, longitude: float | None + ) -> tuple[str | None, str | None]: + """ + Получение часового пояса и текущего времени в столице по координатам. + + :param latitude: Широта + :param longitude: Долгота + :return: Часовой пояс и текущее время или None, None, если не найдены + """ + timezone_raw = cls.get_timezone(latitude, longitude) + if timezone_raw is None: + return None, None + timezone = pytz.timezone(timezone_raw) + time = datetime.now(timezone) + return timezone_raw, time.strftime("%H:%M:%S on %A, %B %d, %Y") + + @classmethod + async def collect(cls, name: str) -> CapitalDTO: + """ + Получение данных о столице в формате CapitalDTO. + + :param name: Название столицы + :return: Модель столицы в формате CapitalDTO + """ + latitude, longitude = await cls.get_coordinates(name) + timezone, current_time = cls.capital_time(latitude, longitude) + return CapitalDTO( + name=name, + latitude=latitude, + longitude=longitude, + timezone=timezone, + current_time=current_time, + ) + + class CurrencyRatesCollector(BaseCollector): """ Сбор информации о курсах валют. @@ -217,6 +293,7 @@ async def read(cls, location: LocationDTO) -> Optional[WeatherInfoDTO]: temp=result["main"]["temp"], pressure=result["main"]["pressure"], humidity=result["main"]["humidity"], + visibility=result["visibility"], wind_speed=result["wind"]["speed"], description=result["weather"][0]["description"], ) From 2c3f63f76bcb0edf42a88f9920b429db99b675ad Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:04:40 +0400 Subject: [PATCH 3/7] Added render for capital --- src/renderer.py | 100 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/src/renderer.py b/src/renderer.py index 8b90dcc..9e034e7 100644 --- a/src/renderer.py +++ b/src/renderer.py @@ -4,6 +4,8 @@ from decimal import ROUND_HALF_UP, Decimal +from prettytable import PrettyTable + from collectors.models import LocationInfoDTO @@ -21,21 +23,90 @@ def __init__(self, location_info: LocationInfoDTO) -> None: self.location_info = location_info - async def render(self) -> tuple[str, ...]: + @staticmethod + def make_table(data: list, columns: list[str]) -> PrettyTable: + """ + Форматирование прочитанных данных о сущности. + + :param data: Список строк для отображения. + :param columns: Список названий столбцов. + + :return: Результат форматирования + """ + table = PrettyTable(columns) + for row in data: + table.add_row(row) + return table + + async def render_country(self) -> PrettyTable: + """ + Форматирование прочитанных данных о стране. + + :return: Результат форматирования + """ + location = self.location_info.location + data = [ + ( + location.name, + location.subregion, + await self._format_none(location.area), + await self._format_languages(), + await self._format_population(), + await self._format_currency_rates(), + ) + ] + return self.make_table( + data, + [ + "Страна", + "Регион", + "Площадь (кв. м.)", + "Языки", + "Население страны (чел.)", + "Курсы валют", + ], + ) + + async def render_capital(self) -> PrettyTable: """ - Форматирование прочитанных данных. + Форматирование прочитанных данных о столице. :return: Результат форматирования """ + capital = self.location_info.capital + data = [ + ( + capital.name, + await self._format_none(capital.latitude), + await self._format_none(capital.longitude), + await self._format_none(capital.timezone), + await self._format_none(capital.current_time), + ) + ] + return self.make_table( + data, + [ + "Название столицы", + "Широта", + "Долгота", + "Часовой пояс", + "Текущее местное время", + ], + ) + + async def render_weather(self) -> PrettyTable: + """ + Форматирование прочитанных данных о погоде. - return ( - f"Страна: {self.location_info.location.name}", - f"Столица: {self.location_info.location.capital}", - f"Регион: {self.location_info.location.subregion}", - f"Языки: {await self._format_languages()}", - f"Население страны: {await self._format_population()} чел.", - f"Курсы валют: {await self._format_currency_rates()}", - f"Погода: {self.location_info.weather.temp} °C", + :return: Результат форматирования + """ + weather = self.location_info.weather + data = [ + (weather.description, weather.temp, weather.visibility, weather.wind_speed) + ] + return self.make_table( + data, + ["Описание", "Температура (°C)", "Видимость (м)", "Скорость ветра (м/с)"], ) async def _format_languages(self) -> str: @@ -60,6 +131,15 @@ async def _format_population(self) -> str: # pylint: disable=C0209 return "{:,}".format(self.location_info.location.population).replace(",", ".") + async def _format_none(self, input_field: str | float | None) -> str | float: + """ + Форматирование поля, которое может принимать значение None. + + :return: + """ + + return input_field if not None else "Неизвестно" + async def _format_currency_rates(self) -> str: """ Форматирование информации о курсах валют. From 50c30e468475c0af1575e84455ef6b619212a92e Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:04:47 +0400 Subject: [PATCH 4/7] Added reader for capital --- src/reader.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/reader.py b/src/reader.py index dd1a74d..a6cb3a0 100644 --- a/src/reader.py +++ b/src/reader.py @@ -6,11 +6,13 @@ from typing import Optional from collectors.collector import ( + CapitalCollector, CountryCollector, CurrencyRatesCollector, WeatherCollector, ) from collectors.models import ( + CapitalDTO, CountryDTO, CurrencyInfoDTO, LocationDTO, @@ -34,6 +36,7 @@ async def find(self, location: str) -> Optional[LocationInfoDTO]: country = await self.find_country(location) if country: + capital = await self.get_capital(country.capital) weather = await self.get_weather( LocationDTO(capital=country.capital, alpha2code=country.alpha2code) ) @@ -41,6 +44,7 @@ async def find(self, location: str) -> Optional[LocationInfoDTO]: return LocationInfoDTO( location=country, + capital=capital, weather=weather, currency_rates=currency_rates, ) @@ -90,6 +94,16 @@ async def find_country(self, search: str) -> Optional[CountryDTO]: return None + @staticmethod + async def get_capital(capital_name: str) -> CapitalDTO: + """ + Получение данных о столице. + + :param capital_name: Название столицы + :return: + """ + return await CapitalCollector.collect(capital_name) + @staticmethod async def _match(search: str, country: CountryDTO) -> bool: """ From b7178a1b04d0fb633264a5dfaaec9a066f6c54f9 Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:05:06 +0400 Subject: [PATCH 5/7] Added table printing --- src/main.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main.py b/src/main.py index f6acf0c..475eeb9 100644 --- a/src/main.py +++ b/src/main.py @@ -3,11 +3,26 @@ """ import asyncclick as click +from prettytable import PrettyTable from reader import Reader from renderer import Renderer +def print_info(title: str, render_result: PrettyTable) -> None: + """ + Вывод информации о сущности в консоль + + :param title: Название таблицы. + :param render_result: Таблица. + """ + + lines = render_result + click.secho(title, bold=True, fg="green") + for line in lines: + click.secho(line, fg="green") + + @click.command() @click.option( "--location", @@ -19,17 +34,22 @@ ) async def process_input(location: str) -> None: """ - Поиск и вывод информации о стране, погоде и курсах валют. + Поиск и вывод информации о стране, столице, погоде и курсах валют. :param str location: Страна и/или город """ location_info = await Reader().find(location) if location_info: - lines = await Renderer(location_info).render() - - for line in lines: - click.secho(line, fg="green") + print_info( + "Информация о стране", await Renderer(location_info).render_country() + ) + print_info( + "Информация о столице", await Renderer(location_info).render_capital() + ) + print_info( + "Информация о погоде", await Renderer(location_info).render_weather() + ) else: click.secho("Информация отсутствует.", fg="yellow") From 89355eb68537d0825934b646b40b9d579dda8ff6 Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:05:12 +0400 Subject: [PATCH 6/7] Added tests --- src/tests/clients/test_currency.py | 26 +++++++ src/tests/clients/test_weather.py | 27 +++++++ src/tests/collectors/test_capital.py | 27 +++++++ src/tests/collectors/test_country.py | 27 +++++++ src/tests/collectors/test_currency.py | 38 ++++++++++ src/tests/collectors/test_weather.py | 32 ++++++++ src/tests/test_reader.py | 75 +++++++++++++++++++ src/tests/test_renderer.py | 104 ++++++++++++++++++++++++++ 8 files changed, 356 insertions(+) create mode 100644 src/tests/collectors/test_capital.py diff --git a/src/tests/clients/test_currency.py b/src/tests/clients/test_currency.py index 104d612..8532957 100644 --- a/src/tests/clients/test_currency.py +++ b/src/tests/clients/test_currency.py @@ -1,3 +1,29 @@ """ Тестирование функций клиента для получения информации о курсах валют. """ +import pytest +from clients.currency import CurrencyClient + + +@pytest.mark.asyncio +class TestClientCurrency: + """ + Тестирование клиента для получения информации о странах. + """ + + base_url = "https://api.apilayer.com/fixer/latest" + + @pytest.fixture + def client(self): + return CurrencyClient() + + async def test_get_base_url(self, client): + assert await client.get_base_url() == self.base_url + + async def test_get_countries(self, mocker, client): + mocker.patch("clients.currency.CurrencyClient._request") + await client.get_rates() + client._request.assert_called_once_with(f"{self.base_url}?base=rub") + + await client.get_rates("usd") + client._request.assert_called_with(f"{self.base_url}?base=usd") diff --git a/src/tests/clients/test_weather.py b/src/tests/clients/test_weather.py index 3c14430..ea7e717 100644 --- a/src/tests/clients/test_weather.py +++ b/src/tests/clients/test_weather.py @@ -1,3 +1,30 @@ """ Тестирование функций клиента для получения информации о погоде. """ +import pytest +from clients.weather import WeatherClient +from settings import API_KEY_OPENWEATHER + + +@pytest.mark.asyncio +class TestClientWeather: + """ + Тестирование клиента для получения информации о странах. + """ + + base_url = "https://api.openweathermap.org/data/2.5/weather" + + @pytest.fixture + def client(self): + return WeatherClient() + + async def test_get_base_url(self, client): + assert await client.get_base_url() == self.base_url + + async def test_get_countries(self, mocker, client): + mocker.patch("clients.weather.WeatherClient._request") + + await client.get_weather("London") + client._request.assert_called_with( + f"{self.base_url}?units=metric&q=London&appid={API_KEY_OPENWEATHER}" + ) diff --git a/src/tests/collectors/test_capital.py b/src/tests/collectors/test_capital.py new file mode 100644 index 0000000..95f6169 --- /dev/null +++ b/src/tests/collectors/test_capital.py @@ -0,0 +1,27 @@ +""" +Тестирование функций сбора информации о странах. +""" + +import pytest + +from collectors.collector import CapitalCollector + + +@pytest.mark.asyncio +class TestCollectorCapital: + @pytest.fixture(autouse=True) + def collector(self): + self.collector = CapitalCollector() + + @pytest.mark.asyncio + async def test_read_capital(self): + """ + Тестирование чтения информации о стране. + """ + capital = await self.collector.collect("Moscow") + assert capital is not None + assert capital.name == "Moscow" + assert round(capital.latitude, 2) == 55.75 + assert round(capital.longitude, 2) == 37.62 + assert capital.timezone == "Europe/Moscow" + assert capital.current_time is not None diff --git a/src/tests/collectors/test_country.py b/src/tests/collectors/test_country.py index 325936d..91eaf76 100644 --- a/src/tests/collectors/test_country.py +++ b/src/tests/collectors/test_country.py @@ -1,3 +1,30 @@ """ Тестирование функций сбора информации о странах. """ + +import pytest + +from collectors.collector import CountryCollector + + +@pytest.mark.asyncio +class TestCollectorCountry: + @pytest.fixture(autouse=True) + def collector(self): + self.collector = CountryCollector() + + @pytest.mark.asyncio + async def test_read_countries(self): + """ + Тестирование чтения информации о стране. + """ + countries = await self.collector.read() + assert len(countries) == 49 + + @pytest.mark.asyncio + async def test_collecting_countries(self): + """ + Тестирование получения информации о стране. + """ + countries = await self.collector.collect() + assert len(countries) == 49 diff --git a/src/tests/collectors/test_currency.py b/src/tests/collectors/test_currency.py index f8982e0..ff5ae9d 100644 --- a/src/tests/collectors/test_currency.py +++ b/src/tests/collectors/test_currency.py @@ -1,3 +1,41 @@ """ Тестирование функций сбора информации о курсах валют. """ +import json + +import aiofiles +import pytest + +from collectors.collector import CurrencyRatesCollector + + +@pytest.mark.asyncio +class TestCollectorCurrency: + @pytest.fixture(autouse=True) + def collector(self): + self.collector = CurrencyRatesCollector() + + @pytest.mark.asyncio + async def test_read_currencies(self): + """ + Тестирование чтения информации о валютах. + """ + currencies = await self.collector.read() + assert currencies is not None + assert currencies.base.lower() == "rub" + assert len(currencies.rates) == 170 + + @pytest.mark.asyncio + async def test_collecting_currencies(self): + """ + Тестирование получения информации о валютах. + """ + await self.collector.collect() + async with aiofiles.open( + await self.collector.get_file_path(), mode="r" + ) as file: + content = await file.read() + currencies = json.loads(content) + read_currencies = await self.collector.read() + assert currencies["base"] == read_currencies.base + assert len(currencies["rates"]) == len(read_currencies.rates) diff --git a/src/tests/collectors/test_weather.py b/src/tests/collectors/test_weather.py index 55b8796..bead339 100644 --- a/src/tests/collectors/test_weather.py +++ b/src/tests/collectors/test_weather.py @@ -1,3 +1,35 @@ """ Тестирование функций сбора информации о погоде. """ +import pytest +from collectors.collector import WeatherCollector +from collectors.models import LocationDTO + + +class TestCollectorWeather: + """ + Тестирование функций сбора информации о погоде. + """ + + @pytest.fixture(autouse=True) + def setup(self): + self.collector = WeatherCollector() + self.location = LocationDTO( + capital="Yerevan", + alpha2code="AM", + ) + + @pytest.mark.asyncio + async def test_read_weather(self): + """ + Тестирование чтения информации о погоде. + """ + weather = await self.collector.read(self.location) + assert weather is not None + + @pytest.mark.asyncio + async def test_collect_weather(self): + """ + Тестирование получения информации о погоде. + """ + await self.collector.collect(frozenset([self.location])) diff --git a/src/tests/test_reader.py b/src/tests/test_reader.py index 0ee6c46..e750dd9 100644 --- a/src/tests/test_reader.py +++ b/src/tests/test_reader.py @@ -1,3 +1,78 @@ """ Тестирование функций поиска (чтения) собранной информации в файлах. """ +import pytest + +from collectors.models import ( + CountryDTO, + LocationDTO, + LocationInfoDTO, + WeatherInfoDTO, + CapitalDTO, +) +from reader import Reader + + +class TestReader: + @pytest.fixture(autouse=True) + def setup(self): + self.reader = Reader() + self.location = LocationDTO( + alpha2code="RU", + capital="Moscow", + ) + + @pytest.mark.asyncio + async def test_find(self): + country = await self.reader.find_country("Moscow") + assert type(country) == CountryDTO + assert country.capital == "Moscow" + assert country.alpha2code == "RU" + assert len(country.alt_spellings) == 5 + assert len(country.currencies) == 1 + assert len(country.languages) == 1 + assert country.name == "Russian Federation" + assert country.population == 146599183 + assert country.area == 17124442.0 + assert country.subregion == "Eastern Europe" + assert len(country.timezones) == 9 + + @pytest.mark.asyncio + async def test_not_found_country(self): + country = await self.reader.find_country("testcountry") + assert country is None + + @pytest.mark.asyncio + async def test_find_capital(self): + capital = await self.reader.get_capital("Moscow") + assert type(capital) == CapitalDTO + assert capital is not None + assert capital.name == "Moscow" + assert round(capital.latitude, 2) == 55.75 + assert round(capital.longitude, 2) == 37.62 + assert capital.timezone == "Europe/Moscow" + assert capital.current_time is not None + + @pytest.mark.asyncio + async def test_not_found_capital(self): + capital = await self.reader.get_capital("testcapital") + assert type(capital) == CapitalDTO + assert capital is not None + assert capital.name == "testcapital" + assert capital.latitude is None + assert capital.longitude is None + assert capital.timezone is None + assert capital.current_time is None + + @pytest.mark.asyncio + async def test_get_weather(self): + weather = await self.reader.get_weather(self.location) + assert type(weather) == WeatherInfoDTO + + @pytest.mark.asyncio + async def test_find_location(self): + location = await self.reader.find("Moscow") + assert type(location) == LocationInfoDTO + assert type(location.location) == CountryDTO + assert type(location.capital) == CapitalDTO + assert type(location.weather) == WeatherInfoDTO diff --git a/src/tests/test_renderer.py b/src/tests/test_renderer.py index 5300cdc..9178738 100644 --- a/src/tests/test_renderer.py +++ b/src/tests/test_renderer.py @@ -1,3 +1,107 @@ """ Тестирование функций генерации выходных данных. """ + +import pytest +from collectors.models import ( + CountryDTO, + CurrencyInfoDTO, + LanguagesInfoDTO, + LocationInfoDTO, + CapitalDTO, + WeatherInfoDTO, +) +from renderer import Renderer + + +class TestRenderer: + @pytest.fixture(autouse=True) + def setup(self): + self.location = LocationInfoDTO( + location=CountryDTO( + name="Russian Federation", + capital="Moscow", + alpha2code="RU", + alt_spellings=["Russia"], + subregion="Eastern Europe", + population=146599183, + area=17124442.0, + longitude=100, + latitude=60, + currencies={CurrencyInfoDTO(code="RUB")}, + languages={LanguagesInfoDTO(name="Russian", native_name="Русский")}, + flag="no", + timezones=["UTC +9"], + ), + capital=CapitalDTO( + name="Moscow", + latitude=55.75, + longitude=37.62, + timezone="Europe/Moscow", + current_time="22:14:18 on Thursday, February 16, 2023", + ), + weather=WeatherInfoDTO( + description="overcast clouds", + temp=-7.05, + pressure=960, + humidity=95, + wind_speed=2.03, + visibility=70, + ), + currency_rates={"USD": 71.0}, + ) + self.renderer = Renderer(self.location) + + @pytest.mark.asyncio + async def test_render_country(self): + table = await self.renderer.render_country() + assert table.field_names == [ + "Страна", + "Регион", + "Площадь (кв. м.)", + "Языки", + "Население страны (чел.)", + "Курсы валют", + ] + assert len(table.rows) == 1 + row = table.rows[0] + assert self.location.location.name == row[0] + assert self.location.location.subregion == row[1] + assert self.location.location.area == row[2] + assert await self.renderer._format_languages() == row[3] + assert await self.renderer._format_population() == row[4] + assert await self.renderer._format_currency_rates() == row[5] + + @pytest.mark.asyncio + async def test_render_capital(self): + table = await self.renderer.render_capital() + assert table.field_names == [ + "Название столицы", + "Широта", + "Долгота", + "Часовой пояс", + "Текущее местное время", + ] + assert len(table.rows) == 1 + row = table.rows[0] + assert self.location.capital.name == row[0] + assert self.location.capital.latitude == row[1] + assert self.location.capital.longitude == row[2] + assert self.location.capital.timezone == row[3] + assert self.location.capital.current_time == row[4] + + @pytest.mark.asyncio + async def test_render_weather(self): + table = await self.renderer.render_weather() + assert table.field_names == [ + "Описание", + "Температура (°C)", + "Видимость (м)", + "Скорость ветра (м/с)", + ] + assert len(table.rows) == 1 + row = table.rows[0] + assert self.location.weather.description == row[0] + assert self.location.weather.temp == row[1] + assert self.location.weather.visibility == row[2] + assert self.location.weather.wind_speed == row[3] From 99006291d9c3e2ad09794636c338a3b7d298ddc6 Mon Sep 17 00:00:00 2001 From: Maria Akhaladze Date: Fri, 17 Feb 2023 19:24:24 +0400 Subject: [PATCH 7/7] Fixed test description --- src/tests/collectors/test_capital.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/collectors/test_capital.py b/src/tests/collectors/test_capital.py index 95f6169..882d75d 100644 --- a/src/tests/collectors/test_capital.py +++ b/src/tests/collectors/test_capital.py @@ -16,7 +16,7 @@ def collector(self): @pytest.mark.asyncio async def test_read_capital(self): """ - Тестирование чтения информации о стране. + Тестирование получения информации о столице. """ capital = await self.collector.collect("Moscow") assert capital is not None