Skip to content

Commit

Permalink
chore: Bing up to speed with dev
Browse files Browse the repository at this point in the history
  • Loading branch information
r-leyshon committed Jan 22, 2024
2 parents fc6688e + e4f27a6 commit ca4ecfa
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/transport_performance/gtfs/multi_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class MultiGtfsInstance:
Plot each of the stops from all GtfsInstance's on a folium Map object.
validate_empty_feeds()
Check if there are empty feeds within the MultiGtfsInstance.
get_dates()
Get the range of dates that the gtfs(s) span.
Raises
------
Expand Down Expand Up @@ -641,3 +643,35 @@ def viz_stops(
if return_viz:
return map
return None

def get_dates(self, return_range: bool = True) -> list:
"""Get all available dates from calendar.txt (or calendar_dates.txt).
Parameters
----------
return_range : bool, optional
Whether to return the raw dates, or the min/max range, by default
True
Returns
-------
list
Either the full set of dates, or the range that the dates span
between
"""
_type_defence(return_range, "return_range", bool)
available_dates = set()
for inst in self.instances:
# gtfs-kit makes calendar None if it isn't present
if isinstance(inst.feed.calendar, type(None)):
available_dates.update(
inst.feed.calendar_dates["date"].unique()
)
else:
available_dates.update(inst.feed.calendar["start_date"])
available_dates.update(inst.feed.calendar["end_date"])
sorted_dates = sorted(available_dates)
if return_range:
return [min(sorted_dates), max(sorted_dates)]
return sorted_dates
3 changes: 3 additions & 0 deletions src/transport_performance/osm/osm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def filter_osm(
"""
# defence
_type_defence(pbf_pth, "pbf_pth", (pathlib.Path, str))
# if pbf_pth is str, convert to Path in order to access as_posix method
pbf_pth = pathlib.Path(pbf_pth)
_is_expected_filetype(pbf_pth, param_nm="pbf_pth", exp_ext=".pbf")
_enforce_file_extension(out_pth, ".pbf", ".pbf", "out_pth")
for nm, val in {
Expand Down
59 changes: 59 additions & 0 deletions tests/gtfs/test_multi_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import glob
import pathlib
import shutil
from copy import deepcopy

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -32,6 +33,23 @@ def multi_gtfs_fixture(multi_gtfs_paths):
return m_gtfs


@pytest.fixture(scope="function")
def multi_gtfs_altered_fixture(multi_gtfs_fixture):
"""Test fixture with calendar_dates.txt in GTFS instance 0."""
# deepcopy otherwise it overwrites multi_gtfs_fixture
mgtfs = deepcopy(multi_gtfs_fixture)
dummy_cdates = pd.DataFrame(
{
"service_id": ["000001", "000001", "000002", "000003"],
"date": ["20231211", "20240601", "20240613", "20220517"],
"exception_type": [1, 1, 1, 1],
}
)
mgtfs.instances[0].feed.calendar_dates = dummy_cdates
mgtfs.instances[0].feed.calendar = None
return mgtfs


class TestMultiGtfsInstance(object):
"""Tests for the MultiGtfsInstance class."""

Expand Down Expand Up @@ -462,3 +480,44 @@ def test_viz_stops(self, multi_gtfs_fixture, tmp_path):
assert isinstance(
no_stop_code_map, folium.Map
), "Map not plotted without stop_code present"

def test_get_dates_defence(self, multi_gtfs_fixture):
"""Defensive tests for .get_dates()."""
with pytest.raises(
TypeError, match=".*return_range.*expected.*bool.*Got.*str.*"
):
multi_gtfs_fixture.get_dates(return_range="test")

def test_get_dates(self, multi_gtfs_fixture, multi_gtfs_altered_fixture):
"""General tests for .get_dates()."""
# multi gtfs with only calendar.txt
# return_range=True
assert (
len(multi_gtfs_fixture.get_dates()) == 2
), "Unexpected number of dates returned"
assert (
multi_gtfs_fixture.get_dates()[0] == "20230605"
), "min not as expected"
assert (
multi_gtfs_fixture.get_dates()[1] == "20240426"
), "max not as expected"
# return_range=False
assert (
len(multi_gtfs_fixture.get_dates(return_range=False)) == 5
), "Unexpected number of dates"
# multi_gtfs with both calendar.txt and calendar_dates.txt
# return_range=True
assert (
len(multi_gtfs_altered_fixture.get_dates()) == 2
), "Unexpected number of dates"
assert (
multi_gtfs_altered_fixture.get_dates()[0] == "20220517"
), "min not as expected"
assert (
multi_gtfs_altered_fixture.get_dates()[1] == "20240613"
), "max not as expected"
# return_range=False
assert (
len(multi_gtfs_altered_fixture.get_dates(return_range=False)) == 6
), "Unexpected number of dates"
pass
21 changes: 21 additions & 0 deletions tests/osm/test_osm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import os
from unittest.mock import patch, call
import re
import glob

from pyprojroot import here

from transport_performance.osm.osm_utils import filter_osm

Expand Down Expand Up @@ -118,3 +121,21 @@ def test_filter_osm_with_osmosis(self, mock_print, tmpdir):
.startswith("call('Filter completed. Written to ")
)
assert out is None

@pytest.mark.runinteg
@patch("builtins.print")
def test_filter_osm_takes_globstring(self, mock_print, tmpdir):
"""Assert filter operation executes when user passes a globstring."""
found_pbf = sorted(glob.glob(str(here("tests/data/*.pbf"))))[0]
target_pth = os.path.join(tmpdir, "test_globstring_input.osm.pbf")
filter_osm(
pbf_pth=found_pbf, out_pth=target_pth, install_osmosis=False
)
# check the file exists
assert os.path.exists(
target_pth
), f"Filtered pbf file not found: {target_pth}"
func_out = mock_print.mock_calls
assert (
func_out[-1].__str__().endswith("test_globstring_input.osm.pbf')")
)

0 comments on commit ca4ecfa

Please sign in to comment.