Skip to content

Commit 62bea34

Browse files
rajeejaerogluorhanpre-commit-ci[bot]
authored
Moving tests from flat to hierarchical structure (#1349)
* o Reorg test files, use paths.py * Fix remaining path references after merge * Clean up remaining redundant variables * o .. Consolidate test file paths: remove redundant gridfile_* variables, use direct imports from paths module * Fix additional redundant variables and indentation in test files * o Missed a few more * o Fix files in test/ folder; add new mesh files to paths; fix more leftover from last time * fix whitespace * o Add pytest fixtures for test data management - Add conftest.py with gridpath and datasetpath fixtures - Migrate test_accessors.py to use fixtures instead of sys.path manipulation - Remove 'from paths import *' anti-pattern - Enable running tests with 'python -m pytest' without path hacks * o Enhance fixtures to support multiple files and migrate test_dataarray.py - Update gridpath and datasetpath fixtures to support returning lists of paths - When last argument is a list, returns list of Path objects - Migrate test_dataarray.py to use fixtures instead of sys.path manipulation - Remove 'from paths import *' anti-pattern from test_dataarray.py * o Migrate to conftest.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update test_plot.py * o Remove unnecessary imports * o Remove stale comments --------- Co-authored-by: Orhan Eroglu <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 612c926 commit 62bea34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+945
-1216
lines changed

test/__init__.py

Whitespace-only changes.

test/conftest.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""Pytest configuration and fixtures for uxarray tests."""
2+
3+
import pytest
4+
import numpy as np
5+
from pathlib import Path
6+
7+
8+
@pytest.fixture
9+
def gridpath():
10+
"""Get the path to test grid/mesh file(s).
11+
12+
Parameters
13+
----------
14+
*args : str
15+
Path components relative to test/meshfiles/
16+
The last argument can be a list of filenames to return multiple paths.
17+
18+
Returns
19+
-------
20+
Path or list of Path
21+
Single path or list of paths to test grid files
22+
"""
23+
base_path = Path(__file__).parent / "meshfiles"
24+
25+
def _get_path(*args):
26+
# If the last argument is a list, handle multiple files
27+
if args and isinstance(args[-1], list):
28+
base_parts = args[:-1]
29+
filenames = args[-1]
30+
paths = []
31+
for filename in filenames:
32+
path = base_path.joinpath(*base_parts, filename)
33+
if not path.exists():
34+
pytest.skip(f"Test grid file not found: {path}")
35+
paths.append(path)
36+
return paths
37+
else:
38+
# Single file case
39+
path = base_path.joinpath(*args)
40+
if not path.exists():
41+
raise FileNotFoundError(f"Test grid file not found: {path}")
42+
return path
43+
44+
return _get_path
45+
46+
47+
@pytest.fixture
48+
def datasetpath():
49+
"""Get the path to test dataset file(s).
50+
51+
Parameters
52+
----------
53+
*args : str
54+
Path components relative to test/meshfiles/
55+
The last argument can be a list of filenames to return multiple paths.
56+
57+
Returns
58+
-------
59+
Path or list of Path
60+
Single path or list of paths to test dataset files
61+
"""
62+
base_path = Path(__file__).parent / "meshfiles"
63+
64+
def _get_path(*args):
65+
# If the last argument is a list, handle multiple files
66+
if args and isinstance(args[-1], list):
67+
base_parts = args[:-1]
68+
filenames = args[-1]
69+
paths = []
70+
for filename in filenames:
71+
path = base_path.joinpath(*base_parts, filename)
72+
if not path.exists():
73+
pytest.skip(f"Test dataset file not found: {path}")
74+
paths.append(path)
75+
return paths
76+
else:
77+
# Single file case
78+
path = base_path.joinpath(*args)
79+
if not path.exists():
80+
raise FileNotFoundError(f"Test dataset file not found: {path}")
81+
return path
82+
83+
return _get_path
84+
85+
86+
@pytest.fixture
87+
def test_data_dir():
88+
"""Return the path to the test data directory."""
89+
return Path(__file__).parent / "meshfiles"
90+
91+
92+
@pytest.fixture
93+
def mesh_constants():
94+
"""Test constants for mesh validation."""
95+
return {
96+
'NNODES_ov_RLL10deg_CSne4': 683,
97+
'NNODES_outCSne8': 386,
98+
'NNODES_outCSne30': 5402,
99+
'NNODES_outRLL1deg': 64442,
100+
'DATAVARS_outCSne30': 4,
101+
'TRI_AREA': 0.02216612469199045,
102+
'CORRECTED_TRI_AREA': 0.02244844510268421,
103+
'MESH30_AREA': 12.566,
104+
'PSI_INTG': 12.566,
105+
'VAR2_INTG': 12.566,
106+
'UNIT_SPHERE_AREA': 4 * np.pi,
107+
'FACE_VERTS_AREA': 0.515838,
108+
}

test/constants.py

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
and return UxDataArray/UxDataset objects.
66
"""
77

8-
import os
9-
from pathlib import Path
108
import numpy as np
119
import pandas as pd
1210
import xarray as xr
@@ -15,19 +13,11 @@
1513
import pytest
1614

1715

18-
current_path = Path(os.path.dirname(os.path.realpath(__file__)))
19-
20-
gridfile_ne30 = current_path / "meshfiles" / "ugrid" / "outCSne30" / "outCSne30.ug"
21-
dsfile_var2_ne30 = current_path / "meshfiles" / "ugrid" / "outCSne30" / "outCSne30_var2.nc"
22-
gridfile_geoflow = current_path / "meshfiles" / "ugrid" / "geoflow-small" / "grid.nc"
23-
dsfile_v1_geoflow = current_path / "meshfiles" / "ugrid" / "geoflow-small" / "v1.nc"
24-
mpas_ds_path = current_path / 'meshfiles' / "mpas" / "QU" / 'mesh.QU.1920km.151026.nc'
25-
26-
27-
def test_groupby_preserves_uxgrid():
16+
def test_groupby_preserves_uxgrid(gridpath):
2817
"""Test that groupby operations preserve the uxgrid attribute."""
2918
# Create a dataset from a file
30-
uxds = ux.open_dataset(mpas_ds_path, mpas_ds_path)
19+
mesh_path = gridpath("mpas", "QU", "mesh.QU.1920km.151026.nc")
20+
uxds = ux.open_dataset(mesh_path, mesh_path)
3121
original_grid = uxds.uxgrid
3222

3323
# Create bins from latitude values (extract data explicitly)
@@ -47,10 +37,12 @@ def test_groupby_preserves_uxgrid():
4737
assert ds_result.uxgrid is not None
4838
assert ds_result.uxgrid == original_grid
4939

50-
def test_groupby_bins_preserves_uxgrid():
40+
41+
def test_groupby_bins_preserves_uxgrid(gridpath):
5142
"""Test that groupby_bins operations preserve the uxgrid attribute."""
5243
# Create a dataset from a file
53-
uxds = ux.open_dataset(mpas_ds_path, mpas_ds_path)
44+
mesh_path = gridpath("mpas", "QU", "mesh.QU.1920km.151026.nc")
45+
uxds = ux.open_dataset(mesh_path, mesh_path)
5446
original_grid = uxds.uxgrid
5547

5648
# Create bins from latitude values (extract data explicitly)
@@ -68,8 +60,7 @@ def test_groupby_bins_preserves_uxgrid():
6860
assert ds_result.uxgrid == original_grid
6961

7062

71-
72-
def test_resample_preserves_uxgrid_and_reduces_time():
63+
def test_resample_preserves_uxgrid_and_reduces_time(gridpath):
7364
"""Test that resample operations preserve uxgrid and reduce time dimension."""
7465

7566
# Create a simple test with only time dimension
@@ -84,7 +75,7 @@ def test_resample_preserves_uxgrid_and_reduces_time():
8475

8576
# Open the minimal dataset with a real grid
8677
# Use existing test file we know works
87-
uxgrid = ux.open_grid(gridfile_ne30)
78+
uxgrid = ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug"))
8879

8980
# Create a UxDataset with this grid
9081
uxds = ux.UxDataset(xr_ds, uxgrid=uxgrid)
@@ -97,7 +88,8 @@ def test_resample_preserves_uxgrid_and_reduces_time():
9788
assert result.uxgrid == uxds.uxgrid, "uxgrid not equal after resample"
9889
assert len(result.time) < len(uxds.time), "time dimension not reduced"
9990

100-
def test_resample_preserves_uxgrid():
91+
92+
def test_resample_preserves_uxgrid(gridpath):
10193
"""Test that resample preserves the uxgrid attribute."""
10294

10395
# Create a simple dataset with a time dimension
@@ -111,7 +103,8 @@ def test_resample_preserves_uxgrid():
111103
)
112104

113105
# Create a UxDataset with a real grid
114-
uxds = ux.open_dataset(gridfile_ne30, gridfile_ne30)
106+
grid_path = gridpath("ugrid", "outCSne30", "outCSne30.ug")
107+
uxds = ux.open_dataset(grid_path, grid_path)
115108
original_uxgrid = uxds.uxgrid
116109

117110
# Create a new UxDataset with our time data and the real grid
@@ -128,7 +121,7 @@ def test_resample_preserves_uxgrid():
128121
assert ds_result.uxgrid is original_uxgrid, "uxgrid not identical after Dataset resample"
129122

130123

131-
def test_resample_reduces_time_dimension():
124+
def test_resample_reduces_time_dimension(gridpath):
132125
"""Test that resample properly reduces the time dimension."""
133126

134127
# Create dataset with daily data for a year
@@ -142,7 +135,7 @@ def test_resample_reduces_time_dimension():
142135
)
143136

144137
# Create a UxDataset
145-
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridfile_ne30))
138+
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug")))
146139

147140
# Test monthly resampling reduces from 365 days to 12 months
148141
monthly = uxds.resample(time="1M").mean()
@@ -151,7 +144,7 @@ def test_resample_reduces_time_dimension():
151144
assert monthly.dims["time"] <= 12, "monthly resampling should give 12 or fewer time points"
152145

153146

154-
def test_resample_with_cftime():
147+
def test_resample_with_cftime(gridpath):
155148
"""Test that resample works with cftime objects."""
156149

157150
try:
@@ -170,7 +163,7 @@ def test_resample_with_cftime():
170163
)
171164

172165
# Create a UxDataset
173-
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridfile_ne30))
166+
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug")))
174167

175168
# Test that quarterly resampling works with cftime
176169
quarterly = uxds.resample(time="Q").mean()
@@ -179,7 +172,7 @@ def test_resample_with_cftime():
179172
assert quarterly.dims["time"] < uxds.dims["time"], "time dimension not reduced with cftime"
180173

181174

182-
def test_rolling_preserves_uxgrid():
175+
def test_rolling_preserves_uxgrid(gridpath):
183176
"""Test that rolling operations preserve the uxgrid attribute."""
184177

185178
# Create a dataset with time dimension
@@ -193,7 +186,7 @@ def test_rolling_preserves_uxgrid():
193186
)
194187

195188
# Create a UxDataset with a real grid
196-
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridfile_ne30))
189+
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug")))
197190
original_uxgrid = uxds.uxgrid
198191

199192
# Test DataArray rolling preserves uxgrid
@@ -213,7 +206,7 @@ def test_rolling_preserves_uxgrid():
213206
assert not np.isnan(da_result.values[6:]).any(), "rolling mean should have valid values after window size"
214207

215208

216-
def test_coarsen_preserves_uxgrid():
209+
def test_coarsen_preserves_uxgrid(gridpath):
217210
"""Test that coarsen operations preserve the uxgrid attribute."""
218211

219212
# Create a dataset with time dimension (multiple of coarsen factor)
@@ -227,7 +220,7 @@ def test_coarsen_preserves_uxgrid():
227220
)
228221

229222
# Create a UxDataset with a real grid
230-
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridfile_ne30))
223+
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug")))
231224
original_uxgrid = uxds.uxgrid
232225

233226
# Test DataArray coarsen preserves uxgrid
@@ -247,14 +240,17 @@ def test_coarsen_preserves_uxgrid():
247240
assert ds_result.dims["time"] == 8, "coarsen should reduce time dimension"
248241

249242

250-
def test_weighted_preserves_uxgrid():
243+
def test_weighted_preserves_uxgrid(gridpath, datasetpath):
251244
"""Test that weighted operations preserve the uxgrid attribute."""
252245

253246
# Create a dataset with time and face dimensions
254247
times = pd.date_range("2000-01-01", periods=10, freq="D")
255248

256249
# Open a real dataset to get face dimension
257-
uxds_base = ux.open_dataset(gridfile_ne30, dsfile_var2_ne30)
250+
uxds_base = ux.open_dataset(
251+
gridpath("ugrid", "outCSne30", "outCSne30.ug"),
252+
datasetpath("ugrid", "outCSne30", "outCSne30_var2.nc")
253+
)
258254
n_face = uxds_base.dims["n_face"]
259255

260256
# Create data with time and face dimensions
@@ -292,7 +288,7 @@ def test_weighted_preserves_uxgrid():
292288
assert da_result.shape == (n_face,), "result should only have face dimension"
293289

294290

295-
def test_cumulative_preserves_uxgrid():
291+
def test_cumulative_preserves_uxgrid(gridpath):
296292
"""Test that cumulative operations preserve the uxgrid attribute."""
297293

298294
# Create a dataset with time dimension
@@ -306,7 +302,7 @@ def test_cumulative_preserves_uxgrid():
306302
)
307303

308304
# Create a UxDataset with a real grid
309-
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridfile_ne30))
305+
uxds = ux.UxDataset(ds, uxgrid=ux.open_grid(gridpath("ugrid", "outCSne30", "outCSne30.ug")))
310306
original_uxgrid = uxds.uxgrid
311307

312308
# Test DataArray cumulative preserves uxgrid

0 commit comments

Comments
 (0)