mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 18:03:07 +02:00
- Add comprehensive tests for all packages (3572 tests, 100% branch coverage) - Split oversized test files to stay under 500-line limit - Add per-file ruff ignores for test-appropriate suppressions - Fix _cache_decks.py to properly convert JSON lists to tuples - Add session-scoped conftest fixture for logging handler cleanup (Python 3.14) - Update ruff pre-commit hook to v0.15.2 - Add codespell ignore words for test data - Add generated output files to .gitignore
177 lines
5.8 KiB
Python
177 lines
5.8 KiB
Python
"""Tests for metro stations and osiedla download paths."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import geopandas as gpd
|
|
|
|
from python_pkg.geo_data._warsaw import (
|
|
get_warsaw_metro_stations,
|
|
get_warsaw_osiedla,
|
|
)
|
|
|
|
|
|
def _make_relation_element(name: str, *, include_outer: bool = True) -> dict[str, Any]:
|
|
"""Create a mock OSM relation element."""
|
|
members = []
|
|
if include_outer:
|
|
members.append(
|
|
{
|
|
"role": "outer",
|
|
"geometry": [
|
|
{"lon": 0, "lat": 0},
|
|
{"lon": 1, "lat": 0},
|
|
{"lon": 1, "lat": 1},
|
|
{"lon": 0, "lat": 1},
|
|
],
|
|
}
|
|
)
|
|
return {"type": "relation", "tags": {"name": name}, "members": members}
|
|
|
|
|
|
class TestGetWarsawMetroStations:
|
|
"""Tests for get_warsaw_metro_stations."""
|
|
|
|
@patch("python_pkg.geo_data._warsaw.gpd.read_file")
|
|
@patch("python_pkg.geo_data._warsaw.CACHE_DIR")
|
|
def test_cached(self, mock_cache_dir: MagicMock, mock_read: MagicMock) -> None:
|
|
mock_path = MagicMock()
|
|
mock_cache_dir.__truediv__ = MagicMock(return_value=mock_path)
|
|
mock_path.exists.return_value = True
|
|
mock_gdf = MagicMock(spec=gpd.GeoDataFrame)
|
|
mock_read.return_value = mock_gdf
|
|
result = get_warsaw_metro_stations()
|
|
assert result is mock_gdf
|
|
|
|
@patch("python_pkg.geo_data._warsaw.gpd.GeoDataFrame.from_features")
|
|
@patch("python_pkg.geo_data._warsaw._ensure_cache_dir")
|
|
@patch("python_pkg.geo_data._warsaw._overpass_query")
|
|
@patch("python_pkg.geo_data._warsaw.CACHE_DIR")
|
|
@patch("python_pkg.geo_data._warsaw.sys.stdout")
|
|
def test_downloads_metro(
|
|
self,
|
|
mock_stdout: MagicMock,
|
|
mock_cache_dir: MagicMock,
|
|
mock_query: MagicMock,
|
|
mock_ensure: MagicMock,
|
|
mock_from_features: MagicMock,
|
|
) -> None:
|
|
mock_path = MagicMock()
|
|
mock_cache_dir.__truediv__ = MagicMock(return_value=mock_path)
|
|
mock_path.exists.return_value = False
|
|
|
|
mock_query.return_value = {
|
|
"elements": [
|
|
# M1 only station
|
|
{
|
|
"type": "node",
|
|
"tags": {"name": "Kabaty"},
|
|
"lon": 21.0,
|
|
"lat": 52.1,
|
|
},
|
|
# M2 only station
|
|
{
|
|
"type": "node",
|
|
"tags": {"name": "Bródno"},
|
|
"lon": 21.0,
|
|
"lat": 52.3,
|
|
},
|
|
# M1/M2 interchange
|
|
{
|
|
"type": "node",
|
|
"tags": {"name": "Świętokrzyska"},
|
|
"lon": 21.0,
|
|
"lat": 52.2,
|
|
},
|
|
# Unknown station
|
|
{
|
|
"type": "node",
|
|
"tags": {"name": "Nowa Stacja"},
|
|
"lon": 21.0,
|
|
"lat": 52.4,
|
|
},
|
|
# Not a node -> skip
|
|
{
|
|
"type": "way",
|
|
"tags": {"name": "Metro Line"},
|
|
},
|
|
# Node without name -> skip
|
|
{
|
|
"type": "node",
|
|
"tags": {},
|
|
"lon": 21.0,
|
|
"lat": 52.0,
|
|
},
|
|
# Duplicate
|
|
{
|
|
"type": "node",
|
|
"tags": {"name": "Kabaty"},
|
|
"lon": 21.0,
|
|
"lat": 52.1,
|
|
},
|
|
]
|
|
}
|
|
|
|
mock_gdf = MagicMock(spec=gpd.GeoDataFrame)
|
|
mock_from_features.return_value = mock_gdf
|
|
|
|
result = get_warsaw_metro_stations()
|
|
assert result is mock_gdf
|
|
|
|
|
|
class TestGetWarsawOsiedla:
|
|
"""Tests for get_warsaw_osiedla."""
|
|
|
|
@patch("python_pkg.geo_data._warsaw.gpd.read_file")
|
|
@patch("python_pkg.geo_data._warsaw.CACHE_DIR")
|
|
def test_cached(self, mock_cache_dir: MagicMock, mock_read: MagicMock) -> None:
|
|
mock_path = MagicMock()
|
|
mock_cache_dir.__truediv__ = MagicMock(return_value=mock_path)
|
|
mock_path.exists.return_value = True
|
|
mock_gdf = MagicMock(spec=gpd.GeoDataFrame)
|
|
mock_read.return_value = mock_gdf
|
|
result = get_warsaw_osiedla()
|
|
assert result is mock_gdf
|
|
|
|
@patch("python_pkg.geo_data._warsaw.gpd.GeoDataFrame.from_features")
|
|
@patch("python_pkg.geo_data._warsaw._ensure_cache_dir")
|
|
@patch("python_pkg.geo_data._warsaw._overpass_query")
|
|
@patch("python_pkg.geo_data._warsaw.CACHE_DIR")
|
|
@patch("python_pkg.geo_data._warsaw.sys.stdout")
|
|
def test_downloads_osiedla(
|
|
self,
|
|
mock_stdout: MagicMock,
|
|
mock_cache_dir: MagicMock,
|
|
mock_query: MagicMock,
|
|
mock_ensure: MagicMock,
|
|
mock_from_features: MagicMock,
|
|
) -> None:
|
|
mock_path = MagicMock()
|
|
mock_cache_dir.__truediv__ = MagicMock(return_value=mock_path)
|
|
mock_path.exists.return_value = False
|
|
|
|
mock_query.return_value = {
|
|
"elements": [
|
|
_make_relation_element("Mokotów"),
|
|
# Not a relation -> skip
|
|
{
|
|
"type": "way",
|
|
"tags": {"name": "Way Osiedle"},
|
|
},
|
|
# No name
|
|
{"type": "relation", "tags": {}, "members": []},
|
|
# Duplicate
|
|
_make_relation_element("Mokotów"),
|
|
# No outer rings
|
|
_make_relation_element("Empty", include_outer=False),
|
|
]
|
|
}
|
|
|
|
mock_gdf = MagicMock(spec=gpd.GeoDataFrame)
|
|
mock_from_features.return_value = mock_gdf
|
|
|
|
result = get_warsaw_osiedla()
|
|
assert result is mock_gdf
|