From c6b314a1c7e33df200a3bba2bd0e73ae0748acad Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Mon, 10 Jun 2024 14:49:08 -0700 Subject: [PATCH] Add coverage for new code --- tests/fixtures.py | 54 +++++++++++++++++++++++++++++++++++++++++--- tests/test_bounds.py | 15 ++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index 4da71a7e..81f594bb 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -92,6 +92,22 @@ "standard_name": "time", }, ) +time_hourly_dt = xr.DataArray( + data=np.array( + [ + "2000-01-01T00:00:00.000000000", + "2000-01-01T01:00:00.000000000", + "2000-01-01T02:00:00.000000000", + ], + dtype="datetime64[ns]", + ), + dims=["time"], + attrs={ + "axis": "T", + "long_name": "time", + "standard_name": "time", + }, +) time_subhourly = xr.DataArray( data=np.array( [ @@ -189,6 +205,30 @@ "xcdat_bounds": "True", }, ) +time_bnds_hourly_dt = xr.DataArray( + name="time_bnds", + data=np.array( + [ + [ + "2000-01-01T00:00:00.000000000", + "2000-01-01T01:00:00.000000000", + ], + [ + "2000-01-01T01:00:00.000000000", + "2000-01-01T02:00:00.000000000", + ], + [ + "2000-01-01T02:00:00.000000000", + "2000-01-01T03:00:00.000000000", + ], + ], + dtype="datetime64[ns]", + ), + dims=["time", "bnds"], + attrs={ + "xcdat_bounds": "True", + }, +) time_bnds_subhourly = xr.DataArray( name="time_bnds", data=np.array( @@ -495,7 +535,8 @@ def generate_dataset( def generate_dataset_by_frequency( - freq: Literal["subhour", "hour", "day", "month", "year"] = "month" + freq: Literal["subhour", "hour", "day", "month", "year"] = "month", + obj_type: Literal["cftime", "datetime"] = "cftime", ) -> xr.Dataset: """Generates a dataset for a given temporal frequency. @@ -523,8 +564,15 @@ def generate_dataset_by_frequency( time = time_daily.copy() time_bnds = time_bnds_daily.copy() elif freq == "hour": - time = time_hourly.copy() - time_bnds = time_bnds_hourly.copy() + # Test cftime and datetime. datetime subtraction results in + # dtype=timedelta64[ns] objects, which need to be converted to Pandas + # TimeDelta objects to use the `.seconds` time component. + if obj_type == "cftime": + time = time_hourly.copy() + time_bnds = time_bnds_hourly.copy() + else: + time = time_hourly_dt.copy() + time_bnds = time_bnds_hourly_dt.copy() elif freq == "subhour": time = time_subhourly.copy() time_bnds = time_bnds_subhourly.copy() diff --git a/tests/test_bounds.py b/tests/test_bounds.py index 4e2fd028..2952b05e 100644 --- a/tests/test_bounds.py +++ b/tests/test_bounds.py @@ -826,6 +826,21 @@ def test_add_bounds_for_time_coords_with_different_frequencies(self): assert monthly_bounds.identical(ds_monthly_with_bnds) assert yearly_bounds.identical(ds_yearly_with_bnds) + def test_add_bounds_for_hourly_time_coords_as_datetime_bojects(self): + # get reference datasets + ds_hrly_with_bnds = generate_dataset_by_frequency("hour", "datetime") + + # drop bounds for testing + ds_hrly_wo_bnds = ds_hrly_with_bnds.drop_vars("time_bnds") + + # test adding bounds + hourly_bounds = ds_hrly_wo_bnds.bounds.add_time_bounds( + method="freq", freq="hour" + ) + + # ensure identical + assert hourly_bounds.identical(ds_hrly_with_bnds) + def test_add_monthly_bounds_for_end_of_month_set_to_true(self): ds_with_bnds = self.ds_with_bnds.copy()