From d77532664dd6bb45dfb47219e5c1fe36f9517c18 Mon Sep 17 00:00:00 2001 From: elbeejay Date: Sun, 14 Apr 2024 11:56:52 -0400 Subject: [PATCH] testing --- src/GOSTurban/UrbanRaster.py | 23 +++++++------ tests/test_UrbanRaster.py | 63 ++++++++++++++++++++++++++++++++++-- tests/test_country_helper.py | 37 ++++++++++++++++++++- 3 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/GOSTurban/UrbanRaster.py b/src/GOSTurban/UrbanRaster.py index ca07f93..e74e98e 100644 --- a/src/GOSTurban/UrbanRaster.py +++ b/src/GOSTurban/UrbanRaster.py @@ -115,6 +115,14 @@ def __init__(self, inRaster): ) ) + def _burnValue(self, mask, val, final_raster, allFeatures, idx, pop, cShape): + """Private function to burn value into final mask.""" + mask = (mask ^ 1) * val + yy = np.dstack([final_raster, mask]) + final_raster = np.amax(yy, axis=2) + allFeatures.append([idx, pop, val, shape(geojson.loads(json.dumps(cShape)))]) + return final_raster, allFeatures + def calculateDegurba( self, urbDens=300, @@ -218,11 +226,8 @@ def modal(P): val = 30 # Burn value into the final raster - mask = (mask ^ 1) * val - yy = np.dstack([final_raster, mask]) - final_raster = np.amax(yy, axis=2) - allFeatures.append( - [idx, pop, val, shape(geojson.loads(json.dumps(cShape)))] + final_raster, allFeatures = self._burnValue( + mask, val, final_raster, allFeatures, idx, pop, cShape ) HD_raster = final_raster @@ -257,12 +262,10 @@ def modal(P): if pop > urbThresh: val = 21 # Burn value into the final raster - mask = (mask ^ 1) * val - yy = np.dstack([final_raster, mask]) - final_raster = np.amax(yy, axis=2) - allFeatures.append( - [idx, pop, val, shape(geojson.loads(json.dumps(cShape)))] + final_raster, allFeatures = self._burnValue( + mask, val, final_raster, allFeatures, idx, pop, cShape ) + URB_raster = final_raster # Combine the urban layers diff --git a/tests/test_UrbanRaster.py b/tests/test_UrbanRaster.py index ccca959..2a23fe9 100644 --- a/tests/test_UrbanRaster.py +++ b/tests/test_UrbanRaster.py @@ -2,14 +2,28 @@ import pytest # noqa: F401 import geopandas as gpd from GOSTurban import UrbanRaster +from unittest.mock import MagicMock +from unittest import mock +import numpy as np + + +def test_tprint(capfd): + """Test tprint function.""" + # call function + UrbanRaster.tPrint("mymsg") + # captured output + captured = capfd.readouterr() + assert captured.out.split("\t")[1][:5] == "mymsg" class TestGeocodeCities: """Tests for the geocode_cities() function.""" + # read some of the tutorial data to test + gdf = gpd.read_file("data/tutorial_data/AOI.geojson") + def test_geocode_cities(self): - # read some of the tutorial data to test - gdf = gpd.read_file("data/tutorial_data/AOI.geojson") + gdf = self.gdf # run the function - adding city/state/country info result = UrbanRaster.geocode_cities(gdf) # assert things about the result @@ -17,3 +31,48 @@ def test_geocode_cities(self): assert "City" in result.columns assert "State" in result.columns assert "Country" in result.columns + + +class TestUrbanGriddedPop: + """Testing the urban gridded population data class.""" + + def mocked_rasterio_open(self, t="w"): + """Mocked function for rasterio.open()""" + + class tmpOutput: + def __init__(self): + self.crs = "EPSG:4326" + self.meta = MagicMock() + + def read(self): + raster = np.zeros((10, 10)) + raster[:5, :5] = 4 + raster[5:, 5:] = 3 + raster = np.reshape(raster, [1, 10, 10]) + return raster + + return_val = tmpOutput() + return return_val + + @mock.patch("rasterio.open", mocked_rasterio_open) + def test_init_class(self): + """Init with string that uses rasterio.open""" + ugp = UrbanRaster.urbanGriddedPop("str") + # assert known properties of the mocked object + assert ugp.inR.crs == "EPSG:4326" + + def test_init_value_error(self): + """Init with wrong type, raising a value error.""" + with pytest.raises(ValueError): + UrbanRaster.urbanGriddedPop(5) + + # @mock.patch("rasterio.open", mocked_rasterio_open) + # def test_burn_value(self): + # """Testing the private burn value function.""" + # # make the object + # ugp = UrbanRaster.urbanGriddedPop('str') + # with patch("shapely.geometry") as mock_shape: + # mock_shape = MagicMock() + # final_raster, allFeatures = ugp._burnValue( + # np.ones((5, 5), dtype=bool), 1, np.zeros((5, 5)), [], 'a', 'pop', mock_shape + # ) diff --git a/tests/test_country_helper.py b/tests/test_country_helper.py index d7b2a16..8701954 100644 --- a/tests/test_country_helper.py +++ b/tests/test_country_helper.py @@ -8,6 +8,8 @@ import GOSTrocks.rasterMisc as rMisc from unittest.mock import MagicMock from unittest.mock import patch +from unittest import mock +import numpy as np class TestUrbanHelper: @@ -78,7 +80,7 @@ def test_summarize_ghsl(self, tmp_path): rMisc.zonalStats.assert_called() def test_summarize_ghsl02(self, tmp_path): - """Test the summarize_ghsl method.""" + """Test the summarize_ghsl method with clip_raster=True.""" # make a tmp location for output out_folder = tmp_path / "output" # make the class @@ -98,6 +100,39 @@ def test_summarize_ghsl02(self, tmp_path): rMisc.zonalStats.assert_called() rMisc.clipRaster.assert_called() + def mocked_rasterio_open(self, t="w"): + """Mocked function for rasterio.open()""" + + class tmpOutput: + def __init__(self): + self.crs = "EPSG:4326" + self.meta = MagicMock() + + def read(self): + raster = np.zeros((10, 10)) + raster[:5, :5] = 1500 + raster[5:, 5:] = 3 + return raster + + return_val = tmpOutput() + return return_val + + @mock.patch("rasterio.open", mocked_rasterio_open) + def test_summarize_ghsl03(self, tmp_path): + """Test the summarize_ghsl method with binary_calc=True. + Have not clipped local ghsl data so will throw error.""" + # make a tmp location for output + out_folder = tmp_path / "output" + # make the class + ch = country_helper.urban_country( + iso3="USA", sel_country="placeholder", cur_folder=out_folder, inP=[1, 2, 3] + ) + # mock zonalStats + rMisc.zonalStats = MagicMock() + # try calling the method expecting the value error + with pytest.raises(ValueError): + ch.summarize_ghsl(ghsl_files=["a_a_a_e", "b_b_b_f"], binary_calc=True) + def test_delete_urban_data(self, tmp_path): """Test the delete_urban_data method.""" # make a tmp location for output