From 318bc2f9bf820f01ca320f3e3d91537d7d4ab3d9 Mon Sep 17 00:00:00 2001 From: Melissari1997 Date: Mon, 15 Jun 2026 17:07:07 +0200 Subject: [PATCH 1/3] Add test coverage for all-equal auto-levels and empty explicit levels (#3352) --- xrspatial/tests/test_contour.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/xrspatial/tests/test_contour.py b/xrspatial/tests/test_contour.py index cacc2d011..7f823123f 100644 --- a/xrspatial/tests/test_contour.py +++ b/xrspatial/tests/test_contour.py @@ -1498,3 +1498,45 @@ def test_nan_dask_cupy_equals_numpy(self): for lvl in np_segs: assert np_segs[lvl] == dc_segs[lvl], ( f"NaN-input dask+cupy result diverges from numpy at level {lvl}") + + +# --------------------------------------------------------------------------- +# Coverage gaps: all-equal auto-levels and empty explicit levels (#3352) +# --------------------------------------------------------------------------- + +class TestIssue3352Coverage: + + def test_contours_flat_auto_levels(self): + """An all-equal raster with auto-levels (levels=None) returns empty. + + When vmin == vmax, np.linspace produces identical levels and no + contours are generated. Regression guard for the auto-level branch. + """ + raster = xr.DataArray( + np.ones((10, 10), dtype=np.float64), dims=["y", "x"] + ) + result = contours(raster, levels=None, n_levels=10) + assert result == [] + + def test_contours_empty_explicit_levels_numpy(self): + """Passing an empty list as levels with numpy return_type returns []. + + No crossing can exist with zero levels, so the function returns an + empty list without raising. + """ + raster = xr.DataArray( + np.random.rand(10, 10), dims=["y", "x"] + ) + result = contours(raster, levels=[], return_type="numpy") + assert result == [] + + def test_contours_empty_explicit_levels_geopandas(self): + """Passing an empty list as levels with geopandas returns empty gdf.""" + pytest.importorskip("geopandas") + import geopandas as gpd + raster = xr.DataArray( + np.random.rand(10, 10), dims=["y", "x"] + ) + result_gdf = contours(raster, levels=[], return_type="geopandas") + assert isinstance(result_gdf, gpd.GeoDataFrame) + assert len(result_gdf) == 0 From ce3644fc935c31e967a7fdfb7fca31932536eb12 Mon Sep 17 00:00:00 2001 From: Melissari1997 Date: Mon, 15 Jun 2026 17:10:38 +0200 Subject: [PATCH 2/3] Address review: use create_test_raster, rename class, add column assertions, fix quotes (#3352) --- xrspatial/tests/test_contour.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/xrspatial/tests/test_contour.py b/xrspatial/tests/test_contour.py index 7f823123f..0e8b44118 100644 --- a/xrspatial/tests/test_contour.py +++ b/xrspatial/tests/test_contour.py @@ -1504,7 +1504,7 @@ def test_nan_dask_cupy_equals_numpy(self): # Coverage gaps: all-equal auto-levels and empty explicit levels (#3352) # --------------------------------------------------------------------------- -class TestIssue3352Coverage: +class TestFlatAutoLevelsAndEmptyLevels: def test_contours_flat_auto_levels(self): """An all-equal raster with auto-levels (levels=None) returns empty. @@ -1512,11 +1512,12 @@ def test_contours_flat_auto_levels(self): When vmin == vmax, np.linspace produces identical levels and no contours are generated. Regression guard for the auto-level branch. """ - raster = xr.DataArray( - np.ones((10, 10), dtype=np.float64), dims=["y", "x"] + raster = create_test_raster( + np.ones((10, 10), dtype=np.float64), backend='numpy' ) result = contours(raster, levels=None, n_levels=10) - assert result == [] + assert isinstance(result, list) + assert len(result) == 0 def test_contours_empty_explicit_levels_numpy(self): """Passing an empty list as levels with numpy return_type returns []. @@ -1524,19 +1525,22 @@ def test_contours_empty_explicit_levels_numpy(self): No crossing can exist with zero levels, so the function returns an empty list without raising. """ - raster = xr.DataArray( - np.random.rand(10, 10), dims=["y", "x"] + raster = create_test_raster( + np.random.rand(10, 10), backend='numpy' ) - result = contours(raster, levels=[], return_type="numpy") + result = contours(raster, levels=[], return_type='numpy') + assert isinstance(result, list) assert result == [] def test_contours_empty_explicit_levels_geopandas(self): """Passing an empty list as levels with geopandas returns empty gdf.""" - pytest.importorskip("geopandas") + pytest.importorskip('geopandas') import geopandas as gpd - raster = xr.DataArray( - np.random.rand(10, 10), dims=["y", "x"] + raster = create_test_raster( + np.random.rand(10, 10), backend='numpy' ) - result_gdf = contours(raster, levels=[], return_type="geopandas") + result_gdf = contours(raster, levels=[], return_type='geopandas') assert isinstance(result_gdf, gpd.GeoDataFrame) assert len(result_gdf) == 0 + assert 'level' in result_gdf.columns + assert 'geometry' in result_gdf.columns From 7443af4898e17632ea912dbacf68fc96145dde7b Mon Sep 17 00:00:00 2001 From: Melissari1997 Date: Mon, 15 Jun 2026 17:12:36 +0200 Subject: [PATCH 3/3] Consistent assert style in numpy empty-levels test (#3352) --- xrspatial/tests/test_contour.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrspatial/tests/test_contour.py b/xrspatial/tests/test_contour.py index 0e8b44118..c3ee0ff35 100644 --- a/xrspatial/tests/test_contour.py +++ b/xrspatial/tests/test_contour.py @@ -1530,7 +1530,7 @@ def test_contours_empty_explicit_levels_numpy(self): ) result = contours(raster, levels=[], return_type='numpy') assert isinstance(result, list) - assert result == [] + assert len(result) == 0 def test_contours_empty_explicit_levels_geopandas(self): """Passing an empty list as levels with geopandas returns empty gdf."""