Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move tests.pp to tests.__init__ #5679

Merged
merged 1 commit into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions lib/iris/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import iris.config
import iris.cube
import iris.fileformats
import iris.tests.graphics as graphics
import iris.util

Expand Down Expand Up @@ -883,6 +884,93 @@ class GraphicsTest(graphics.GraphicsTestMixin, IrisTest):
pass


class PPTest:
"""A mixin class to provide PP-specific utilities to subclasses of tests.IrisTest."""

@contextlib.contextmanager
def cube_save_test(
self,
reference_txt_path,
reference_cubes=None,
reference_pp_path=None,
**kwargs,
):
"""A context manager for testing the saving of Cubes to PP files.

Args:

* reference_txt_path:
The path of the file containing the textual PP reference data.

Kwargs:

* reference_cubes:
The cube(s) from which the textual PP reference can be re-built if necessary.
* reference_pp_path:
The location of a PP file from which the textual PP reference can be re-built if necessary.
NB. The "reference_cubes" argument takes precedence over this argument.

The return value from the context manager is the name of a temporary file
into which the PP data to be tested should be saved.

Example::
with self.cube_save_test(reference_txt_path, reference_cubes=cubes) as temp_pp_path:
iris.save(cubes, temp_pp_path)

"""
# Watch out for a missing reference text file
if not os.path.isfile(reference_txt_path):
if reference_cubes:
temp_pp_path = iris.util.create_temp_filename(".pp")
try:
iris.save(reference_cubes, temp_pp_path, **kwargs)
self._create_reference_txt(reference_txt_path, temp_pp_path)
finally:
os.remove(temp_pp_path)
elif reference_pp_path:
self._create_reference_txt(reference_txt_path, reference_pp_path)
else:
raise ValueError(
"Missing all of reference txt file, cubes, and PP path."
)

temp_pp_path = iris.util.create_temp_filename(".pp")
try:
# This value is returned to the target of the "with" statement's "as" clause.
yield temp_pp_path

# Load deferred data for all of the fields (but don't do anything with it)
pp_fields = list(iris.fileformats.pp.load(temp_pp_path))
for pp_field in pp_fields:
pp_field.data
with open(reference_txt_path, "r") as reference_fh:
reference = "".join(reference_fh)
self._assert_str_same(
reference + "\n",
str(pp_fields) + "\n",
reference_txt_path,
type_comparison_name="PP files",
)
finally:
os.remove(temp_pp_path)

def _create_reference_txt(self, txt_path, pp_path):
# Load the reference data
pp_fields = list(iris.fileformats.pp.load(pp_path))
for pp_field in pp_fields:
pp_field.data

# Clear any header words we don't use
unused = ("lbexp", "lbegin", "lbnrec", "lbproj", "lbtyp")
for pp_field in pp_fields:
for word_name in unused:
setattr(pp_field, word_name, 0)

# Save the textual representation of the PP fields
with open(txt_path, "w") as txt_file:
txt_file.writelines(str(pp_fields))


def skip_data(fn):
"""Decorator to choose whether to run tests, based on the availability of
external data.
Expand Down
96 changes: 0 additions & 96 deletions lib/iris/tests/pp.py

This file was deleted.

3 changes: 1 addition & 2 deletions lib/iris/tests/test_cdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import iris.cube
import iris.fileformats
import iris.fileformats.dot
import iris.tests.pp as pp
import iris.tests.stock


Expand Down Expand Up @@ -1287,7 +1286,7 @@ def test_non_string_attributes(self):


@tests.skip_data
class TestMaskedData(tests.IrisTest, pp.PPTest):
class TestMaskedData(tests.IrisTest, tests.PPTest):
def _load_3d_cube(self):
# This 3D data set has a missing a slice with SOME missing values.
# The missing data is in the pressure = 1000 hPa, forcast_period = 0,
Expand Down
5 changes: 2 additions & 3 deletions lib/iris/tests/test_cube_to_pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import iris.coords
import iris.fileformats.pp
from iris.fileformats.pp import PPField3
import iris.tests.pp as pp
import iris.tests.stock as stock
import iris.util

Expand All @@ -36,7 +35,7 @@ def itab_callback(cube, field, filename):


@tests.skip_data
class TestPPSave(tests.IrisTest, pp.PPTest):
class TestPPSave(tests.IrisTest, tests.PPTest):
def test_no_forecast_time(self):
cube = stock.lat_lon_cube()
coord = iris.coords.DimCoord(
Expand Down Expand Up @@ -276,7 +275,7 @@ def geog_cs(self):
return iris.coord_systems.GeogCS(6371229.0)


class TestPPSaveRules(tests.IrisTest, pp.PPTest):
class TestPPSaveRules(tests.IrisTest, tests.PPTest):
def test_default_coord_system(self):
GeogCS = iris.coord_systems.GeogCS
cube = iris.tests.stock.lat_lon_cube()
Expand Down
3 changes: 1 addition & 2 deletions lib/iris/tests/test_pp_cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import iris.coords
from iris.fileformats.netcdf import _thread_safe_nc
from iris.fileformats.pp import STASH
import iris.tests.pp as pp
import iris.util


Expand Down Expand Up @@ -64,7 +63,7 @@ def callback_aaxzc_n10r13xy_b_pp(cube, field, filename):


@tests.skip_data
class TestAll(tests.IrisTest, pp.PPTest):
class TestAll(tests.IrisTest, tests.PPTest):
_ref_dir = ("usecases", "pp_to_cf_conversion")

def _test_file(self, name):
Expand Down