-
Notifications
You must be signed in to change notification settings - Fork 284
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Corrected behaviour and added tests.
- Loading branch information
1 parent
fa31ff4
commit 5a91088
Showing
1 changed file
with
92 additions
and
0 deletions.
There are no files selected for viewing
92 changes: 92 additions & 0 deletions
92
lib/iris/tests/unit/common/metadata/test_microsecond_future.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# Copyright Iris contributors | ||
# | ||
# This file is part of Iris and is released under the BSD license. | ||
# See LICENSE in the root of the repository for full licensing details. | ||
"""Unit tests for the opt-in FUTURE.date_microseconds behaviour.""" | ||
|
||
import warnings | ||
|
||
import numpy as np | ||
import pytest | ||
|
||
from iris import FUTURE | ||
from iris.coords import DimCoord | ||
from iris.tests._shared_utils import assert_array_equal | ||
|
||
|
||
@pytest.fixture( | ||
params=[0, 1000, 500000], | ||
ids=["no_microseconds", "1_millisecond", "half_second"], | ||
) | ||
def time_coord(request) -> tuple[bool, DimCoord]: | ||
points = np.array([0.0, 1.0, 2.0]) | ||
points += request.param / 1e6 | ||
return request.param, DimCoord( | ||
points, | ||
"time", | ||
units="seconds since 1970-01-01 00:00:00", | ||
) | ||
|
||
|
||
@pytest.fixture( | ||
params=[False, True], | ||
ids=["without_future", "with_future"], | ||
) | ||
def future_date_microseconds(request): | ||
FUTURE.date_microseconds = request.param | ||
yield request.param | ||
FUTURE.date_microseconds = False | ||
|
||
|
||
def test_warning(time_coord, future_date_microseconds): | ||
# Warning should be raised whether the coordinate has microseconds or not. | ||
# Want users to be aware, and opt-in, as early as possible. | ||
n_microseconds, coord = time_coord | ||
|
||
def _op(): | ||
_ = coord.units.num2date(coord.points) | ||
|
||
if future_date_microseconds: | ||
with warnings.catch_warnings(): | ||
warnings.simplefilter("error", FutureWarning) | ||
_op() | ||
else: | ||
with pytest.warns(FutureWarning): | ||
_op() | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"indexing", | ||
(np.s_[0], np.s_[:], np.s_[:, np.newaxis]), | ||
ids=("single", "array", "array_2d"), | ||
) | ||
def test_num2date(time_coord, future_date_microseconds, indexing): | ||
n_microseconds, coord = time_coord | ||
result = coord.units.num2date(coord.points[indexing]) | ||
|
||
if indexing == np.s_[0]: | ||
assert hasattr(result, "microsecond") | ||
# Convert to iterable for more consistency downstream. | ||
result = [result] | ||
else: | ||
assert hasattr(result, "shape") | ||
assert hasattr(result.flatten()[0], "microsecond") | ||
result = result.flatten() | ||
|
||
expected_microseconds = n_microseconds | ||
if not future_date_microseconds: | ||
expected_microseconds = 0 | ||
|
||
assert all(r.microsecond == expected_microseconds for r in result) | ||
|
||
|
||
def test_roundup(time_coord, future_date_microseconds): | ||
n_microseconds, coord = time_coord | ||
result = coord.units.num2date(coord.points) | ||
|
||
expected_seconds = np.floor(coord.points) | ||
if n_microseconds >= 500000 and not future_date_microseconds: | ||
expected_seconds += 1 | ||
|
||
result_seconds = np.array([r.second for r in result]) | ||
assert_array_equal(result_seconds, expected_seconds) |