Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tests #1

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/tests-with-i18n.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: tests-with-i18n

on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
run-tests:
runs-on: ubuntu-latest
strategy:
max-parallel: 1
matrix:
python-version: [ '3.12' ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install packages
run: |
pip install --upgrade pip
pip install --upgrade build
pip install -e .[test]
#pip install -e .[i18n]
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
- name: Run tests
run: pytest -v -m "not network_dependent"
4 changes: 1 addition & 3 deletions .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,5 @@ jobs:
pip install --upgrade pip
pip install --upgrade build
pip install -e .[test]
pip install -e .[i18n]
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
- name: Run unit-tests
run: pytest -v -m "not network_dependent"
run: pytest -v -m unit
5 changes: 3 additions & 2 deletions src/deepfacility/utils/spatial.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
from pathlib import Path
from pyproj import CRS
from shapely import Geometry, Polygon
from sklearn.cluster import KMeans
from typing import Any

from deepfacility.utils import util
from typing import Any
from sklearn.cluster import KMeans


# Frequently used spatial global variables
geom_col = 'geometry'
Expand Down
7 changes: 6 additions & 1 deletion tests/test_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def mock_config():

rel = 1e-9



@pytest.mark.unit
def test_convert_to_cartesian():
# Test case 1: lon = 0, lat = 0, elevation = 0
# This is the prime meridian, equator, and sea level
Expand Down Expand Up @@ -47,6 +48,7 @@ def test_convert_to_cartesian():
assert round(z1) == 1366661


@pytest.mark.unit
def test_calculate_minkowski_from_cartesian():
# Test with sample data
df_loc = pd.DataFrame(
Expand All @@ -63,6 +65,7 @@ def test_calculate_minkowski_from_cartesian():
assert result['minkowski'][2] == pytest.approx(2.0408871750129656, rel=rel)


@pytest.mark.unit
def test_find_nearest_facility():
# generate two data frame with id and x, y columns
df_loc = pd.DataFrame({'id': ['a', 'b', 'c'], 'x': [0, 1, 2], 'y': [0, 1, 2]})
Expand All @@ -83,6 +86,7 @@ def test_find_nearest_facility():
assert df_loc['distance'].tolist() == pytest.approx(expected_distances, rel=4)


@pytest.mark.unit
def test_calculate_distance_df():
# Create sample data
df = pd.DataFrame({'id': ['a', 'b', 'c'], 'lon': [0, 1, 2], 'lat': [0, 1, 2]})
Expand Down Expand Up @@ -110,6 +114,7 @@ def cal_dist(a, b, p): return [np.power(np.sum(np.abs(a - b) ** p), 1 / p), 0, 0
assert all(abs(result['distance_minkowski'].values - expected_distances_minkowski) == 0), msg


@pytest.mark.unit
def test_plot_ecdf_distance(mock_config):
# Create sample data
df = pd.DataFrame({'minkowski': [1.5, 2.0, 1.8, 1.2, 1.6]})
Expand Down
17 changes: 14 additions & 3 deletions tests/test_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pandas as pd

from pathlib import Path
from tempfile import mkdtemp
from unittest.mock import MagicMock, patch

from deepfacility.data.inputs import DataInputs
Expand All @@ -21,15 +22,17 @@ def mock_data_inputs(mock_config):

# prepare_country_shapes tests

@pytest.mark.unit
def test_prepare_country_shapes_when_shape_files_exist(mock_data_inputs):
mock_data_inputs.cfg.inputs.shape_files = [Path('shape1.shp'), Path('shape2.shp')]
with patch('pathlib.Path.is_file', return_value=True):
result = mock_data_inputs.prepare_country_shapes(Path('zipfile.zip'))
assert result == mock_data_inputs.cfg.inputs.shape_files


@pytest.mark.unit
def test_prepare_country_shapes_when_shape_files_do_not_exist(mock_data_inputs):
mock_data_inputs.cfg.inputs.shape_files = [Path('shape1.shp'), Path('shape2.shp')]
mock_data_inputs.cfg.inputs.shape_files = [Path('shape1.shp'), Path('shape2.shp')]
with patch.object(Path, 'is_file') as mock_is_file:
mock_is_file.return_value = True

Expand All @@ -43,6 +46,7 @@ def test_prepare_country_shapes_when_shape_files_do_not_exist(mock_data_inputs):
assert result == mock_data_inputs.cfg.inputs.shape_files


@pytest.mark.unit
def test_prepare_country_shapes_when_zip_file_does_not_exist(mock_data_inputs):
with pytest.raises(AssertionError, match="Raw shape file not found."):
mock_data_inputs.prepare_country_shapes(Path('nonexistent.zip'))
Expand All @@ -51,15 +55,17 @@ def test_prepare_country_shapes_when_zip_file_does_not_exist(mock_data_inputs):
# prepare_households tests


@pytest.mark.unit
def test_households_preparation_when_file_exists(mock_data_inputs):
mock_data_inputs.cfg.inputs.households.file = Path('existing_file.csv')
with patch.object(Path, 'is_file', return_value=True):
result = mock_data_inputs.prepare_households(Path('buildings_file.feather'), ['lon', 'lat'], Path('shapes_file.shp'), ['adm1', 'adm2'])
assert result == mock_data_inputs.cfg.inputs.households.file


@pytest.mark.unit
def test_households_preparation_when_file_does_not_exist(mock_data_inputs):
mock_data_inputs.cfg.inputs.households.file = Path('nonexistent_file.csv')
mock_data_inputs.cfg.inputs.households.file = Path(mkdtemp()) / Path('nonexistent_file.csv')
with patch.object(Path, 'is_file', return_value=False), \
patch('geopandas.read_file', return_value=MagicMock()), \
patch('pandas.read_feather', return_value=MagicMock()), \
Expand Down Expand Up @@ -88,12 +94,14 @@ def mock_df_xy():
})


@pytest.mark.unit
def test_buildings_processing_happy_path(mock_data_inputs, mock_gdf_shapes, mock_df_xy):
with patch('deepfacility.data.inputs.process_google_buildings', return_value=mock_df_xy):
result = mock_data_inputs.process_buildings(mock_gdf_shapes, ['x', 'y'], mock_df_xy, ['x', 'y'])
assert result.equals(mock_df_xy)


@pytest.mark.unit
def test_buildings_processing_with_empty_dataframe(mock_data_inputs, mock_gdf_shapes):
with patch('deepfacility.data.inputs.process_google_buildings', return_value=pd.DataFrame()):
result = mock_data_inputs.process_buildings(mock_gdf_shapes, ['x', 'y'], pd.DataFrame(), ['x', 'y'])
Expand All @@ -113,8 +121,9 @@ def mock_shape_files():
return [Path('shape1.shp'), Path('shape2.shp')]


@pytest.mark.unit
def test_village_locality_preparation(mock_data_inputs, mock_village_locality, mock_shape_files):
mock_data_inputs.cfg.inputs.village_centers.file = Path('nonexistent_file.csv')
mock_data_inputs.cfg.inputs.village_centers.file = Path(mkdtemp()) / Path('nonexistent_file.csv')
with patch('pandas.read_csv', return_value=MagicMock()), \
patch('geopandas.read_file', return_value=MagicMock()), \
patch('deepfacility.data.inputs.DataInputs.prepare_village_centers', return_value=MagicMock()), \
Expand Down Expand Up @@ -153,6 +162,7 @@ def mock_baseline_file():
return Path('baseline.csv')


@pytest.mark.unit
def test_village_centers_preparation_happy_path(
mock_data_inputs,
mock_village_locality,
Expand Down Expand Up @@ -191,6 +201,7 @@ def test_village_centers_preparation_happy_path(
# prepare_baseline_facilities tests


@pytest.mark.unit
def test_baseline_facilities_preparation(
mock_data_inputs,
mock_baseline_file,
Expand Down
4 changes: 4 additions & 0 deletions tests/test_session.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import pytest
from requests import Request

from unittest.mock import Mock, MagicMock, patch

from deepfacility.ux.session import Session


@pytest.mark.unit
def test_get_session_id_from_query_string():
request: Request = MagicMock(query_params={'sid': 'test123'}, cookies={})
assert Session.get_session_id(request) == 'test123'


@pytest.mark.unit
def test_get_session_id_from_cookie():
request: Request = MagicMock(query_params={}, cookies={'session_id': 'test123'})
assert Session.get_session_id(request) == 'test123'


@pytest.mark.unit
def test_generate_new_session_id_when_no_source_provided():
request: Request = MagicMock(query_params={}, cookies={})
assert Session.get_session_id(request) is not None
Expand Down
11 changes: 9 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import geopandas as gpd
import requests
import shutil
import tempfile

Expand Down Expand Up @@ -53,9 +54,15 @@ def tmp_dir() -> Path:


# download_url tests
def has_internet():
try:
requests.get("https://gadm.org/", timeout=5)
return True
except requests.exceptions.RequestException:
return False


@pytest.mark.network_dependent
@pytest.mark.skipif(not has_internet(), reason="No internet connection")
def test_download_url_ok(tmp_dir, url_pattern):
expected, actual = download_url_test(tmp_dir, url_pattern, 0)
assert expected == actual, "File name is not expected."
Expand All @@ -66,7 +73,7 @@ def test_download_url_ok(tmp_dir, url_pattern):
return False


@pytest.mark.network_dependent
@pytest.mark.skipif(not has_internet(), reason="No internet connection")
def test_download_url_404(tmp_dir, url_pattern):
expected, actual = download_url_test(tmp_dir, url_pattern, level=4)
assert actual is None, "404 didn't return None."
Expand Down
Loading