4
4
# See LICENSE in the root of the repository for full licensing details.
5
5
"""Unit tests for :class:`iris.analysis._area_weighted.AreaWeightedRegridder`."""
6
6
7
- # Import iris.tests first so that some things can be initialised before
8
- # importing anything else.
9
- import iris .tests as tests # isort:skip
10
- from unittest import mock
11
-
12
7
import numpy as np
8
+ import pytest
13
9
14
10
from iris import load_cube
15
11
from iris .analysis ._area_weighted import (
19
15
from iris .coord_systems import GeogCS
20
16
from iris .coords import DimCoord
21
17
from iris .cube import Cube
18
+ from iris .tests import _shared_utils
22
19
23
20
24
- class Test ( tests . IrisTest ) :
21
+ class Test :
25
22
def cube (self , x , y ):
26
23
data = np .arange (len (x ) * len (y )).reshape (len (y ), len (x ))
27
24
cube = Cube (data )
@@ -41,96 +38,96 @@ def grids(self):
41
38
def extract_grid (self , cube ):
42
39
return cube .coord ("latitude" ), cube .coord ("longitude" )
43
40
44
- def check_mdtol (self , mdtol = None ):
41
+ def check_mdtol (self , mocker , mdtol = None ):
45
42
src_grid , target_grid = self .grids ()
46
43
# Get _regrid_info result
47
44
_regrid_info = _regrid_area_weighted_rectilinear_src_and_grid__prepare (
48
45
src_grid , target_grid
49
46
)
50
- self . assertEqual ( len (_regrid_info ), 9 )
51
- with mock .patch (
47
+ assert len (_regrid_info ) == 9
48
+ prepare = mocker .patch (
52
49
"iris.analysis._area_weighted."
53
50
"_regrid_area_weighted_rectilinear_src_and_grid__prepare" ,
54
51
return_value = _regrid_info ,
55
- ) as prepare :
56
- with mock .patch (
57
- "iris.analysis._area_weighted."
58
- "_regrid_area_weighted_rectilinear_src_and_grid__perform" ,
59
- return_value = mock .sentinel .result ,
60
- ) as perform :
61
- # Setup the regridder
62
- if mdtol is None :
63
- regridder = AreaWeightedRegridder (src_grid , target_grid )
64
- mdtol = 1
65
- else :
66
- regridder = AreaWeightedRegridder (
67
- src_grid , target_grid , mdtol = mdtol
68
- )
69
- # Now regrid the source cube
70
- src = src_grid
71
- result = regridder (src )
52
+ )
53
+ perform = mocker .patch (
54
+ "iris.analysis._area_weighted."
55
+ "_regrid_area_weighted_rectilinear_src_and_grid__perform" ,
56
+ return_value = mocker .sentinel .result ,
57
+ )
72
58
73
- # Make a new cube to regrid with different data so we can
74
- # distinguish between regridding the original src grid
75
- # definition cube and the cube passed to the regridder.
76
- src = src_grid .copy ()
77
- src .data += 10
78
- result = regridder (src )
59
+ # Setup the regridder
60
+ if mdtol is None :
61
+ regridder = AreaWeightedRegridder (src_grid , target_grid )
62
+ mdtol = 1
63
+ else :
64
+ regridder = AreaWeightedRegridder (src_grid , target_grid , mdtol = mdtol )
65
+ # Now regrid the source cube
66
+ src = src_grid
67
+ result = regridder (src )
68
+
69
+ # Make a new cube to regrid with different data so we can
70
+ # distinguish between regridding the original src grid
71
+ # definition cube and the cube passed to the regridder.
72
+ src = src_grid .copy ()
73
+ src .data += 10
74
+ result = regridder (src )
79
75
80
76
# Prepare:
81
- self . assertEqual ( prepare .call_count , 1 )
77
+ assert prepare .call_count == 1
82
78
_ , args , kwargs = prepare .mock_calls [0 ]
83
- self .assertEqual ( self . extract_grid (args [1 ]), self .extract_grid (target_grid ) )
79
+ assert self .extract_grid (args [1 ]) == self .extract_grid (target_grid )
84
80
85
81
# Perform:
86
- self . assertEqual ( perform .call_count , 2 )
82
+ assert perform .call_count == 2
87
83
_ , args , kwargs = perform .mock_calls [1 ]
88
- self . assertEqual ( args [0 ], src )
89
- self . assertEqual ( kwargs , {"mdtol" : mdtol })
90
- self . assertIs ( result , mock .sentinel .result )
84
+ assert args [0 ] == src
85
+ assert kwargs == {"mdtol" : mdtol }
86
+ assert result is mocker .sentinel .result
91
87
92
- def test_default (self ):
93
- self .check_mdtol ()
88
+ def test_default (self , mocker ):
89
+ self .check_mdtol (mocker )
94
90
95
- def test_specified_mdtol (self ):
96
- self .check_mdtol (0.5 )
91
+ def test_specified_mdtol (self , mocker ):
92
+ self .check_mdtol (mocker , mdtol = 0.5 )
97
93
98
94
def test_invalid_high_mdtol (self ):
99
95
src , target = self .grids ()
100
96
msg = "mdtol must be in range 0 - 1"
101
- with self . assertRaisesRegex (ValueError , msg ):
97
+ with pytest . raises (ValueError , match = msg ):
102
98
AreaWeightedRegridder (src , target , mdtol = 1.2 )
103
99
104
100
def test_invalid_low_mdtol (self ):
105
101
src , target = self .grids ()
106
102
msg = "mdtol must be in range 0 - 1"
107
- with self . assertRaisesRegex (ValueError , msg ):
103
+ with pytest . raises (ValueError , match = msg ):
108
104
AreaWeightedRegridder (src , target , mdtol = - 0.2 )
109
105
110
- def test_mismatched_src_coord_systems (self ):
106
+ def test_mismatched_src_coord_systems (self , mocker ):
111
107
src = Cube (np .zeros ((3 , 4 )))
112
108
cs = GeogCS (6543210 )
113
109
lat = DimCoord (np .arange (3 ), "latitude" , coord_system = cs )
114
110
lon = DimCoord (np .arange (4 ), "longitude" )
115
111
src .add_dim_coord (lat , 0 )
116
112
src .add_dim_coord (lon , 1 )
117
- target = mock .Mock ()
118
- with self .assertRaises (ValueError ):
113
+ target = mocker .Mock ()
114
+ emsg = "coordinates must have the same coordinate system"
115
+ with pytest .raises (ValueError , match = emsg ):
119
116
AreaWeightedRegridder (src , target )
120
117
121
118
def test_src_and_target_are_the_same (self ):
122
119
src = self .cube (np .linspace (20 , 30 , 3 ), np .linspace (10 , 25 , 4 ))
123
120
target = self .cube (np .linspace (20 , 30 , 3 ), np .linspace (10 , 25 , 4 ))
124
121
regridder = AreaWeightedRegridder (src , target )
125
122
result = regridder (src )
126
- self . assertArrayAllClose (result .data , target .data )
123
+ _shared_utils . assert_array_all_close (result .data , target .data )
127
124
128
125
def test_multiple_src_on_same_grid (self ):
129
126
coord_names = ["latitude" , "longitude" ]
130
127
src1 = self .cube (np .linspace (20 , 32 , 4 ), np .linspace (10 , 22 , 4 ))
131
128
src2 = self .cube (np .linspace (20 , 32 , 4 ), np .linspace (10 , 22 , 4 ))
132
129
src2 .data *= 4
133
- self . assertArrayEqual (src1 .data * 4 , src2 .data )
130
+ _shared_utils . assert_array_equal (src1 .data * 4 , src2 .data )
134
131
for name in coord_names :
135
132
# Remove coords system and units so it is no longer spherical.
136
133
src1 .coord (name ).coord_system = None
@@ -192,15 +189,17 @@ def test_multiple_src_on_same_grid(self):
192
189
reference2 .coord (name ).units = None
193
190
194
191
# Compare the cubes rather than just the data.
195
- self . assertEqual ( result1 , reference1 )
196
- self . assertEqual ( result2 , reference2 )
192
+ assert result1 == reference1
193
+ assert result2 == reference2
197
194
198
195
def test_src_data_different_dims (self ):
199
196
src , target = self .grids ()
200
197
regridder = AreaWeightedRegridder (src , target )
201
198
result = regridder (src )
202
199
expected_mean , expected_std = 4.772097735195653 , 2.211698479817678
203
- self .assertArrayShapeStats (result , (9 , 8 ), expected_mean , expected_std )
200
+ _shared_utils .assert_array_shape_stats (
201
+ result , (9 , 8 ), expected_mean , expected_std
202
+ )
204
203
# New source cube with additional "levels" dimension
205
204
# Each level has identical x-y data so the mean and std stats remain
206
205
# identical when x, y and z dims are reordered
@@ -213,7 +212,9 @@ def test_src_data_different_dims(self):
213
212
src .add_dim_coord (lat , 1 )
214
213
src .add_dim_coord (lon , 2 )
215
214
result = regridder (src )
216
- self .assertArrayShapeStats (result , (5 , 9 , 8 ), expected_mean , expected_std )
215
+ _shared_utils .assert_array_shape_stats (
216
+ result , (5 , 9 , 8 ), expected_mean , expected_std
217
+ )
217
218
# Check data with dims in different order
218
219
# Reshape src so that the coords are ordered [x, z, y],
219
220
# the mean and std statistics should be the same
@@ -223,7 +224,9 @@ def test_src_data_different_dims(self):
223
224
src .add_dim_coord (levels , 1 )
224
225
src .add_dim_coord (lat , 2 )
225
226
result = regridder (src )
226
- self .assertArrayShapeStats (result , (8 , 5 , 9 ), expected_mean , expected_std )
227
+ _shared_utils .assert_array_shape_stats (
228
+ result , (8 , 5 , 9 ), expected_mean , expected_std
229
+ )
227
230
# Check data with dims in different order
228
231
# Reshape src so that the coords are ordered [y, x, z],
229
232
# the mean and std statistics should be the same
@@ -233,18 +236,23 @@ def test_src_data_different_dims(self):
233
236
src .add_dim_coord (lon , 1 )
234
237
src .add_dim_coord (levels , 2 )
235
238
result = regridder (src )
236
- self .assertArrayShapeStats (result , (9 , 8 , 5 ), expected_mean , expected_std )
239
+ _shared_utils .assert_array_shape_stats (
240
+ result , (9 , 8 , 5 ), expected_mean , expected_std
241
+ )
237
242
238
243
239
- @tests .skip_data
240
- class TestLazy (tests .IrisTest ):
244
+ @_shared_utils .skip_data
245
+ class TestLazy :
246
+ @pytest .fixture (autouse = True )
241
247
# Setup
242
- def setUp (self ) -> None :
248
+ def _setup (self ) -> None :
243
249
# Prepare a cube and a template
244
- cube_file_path = tests .get_data_path (["NetCDF" , "regrid" , "regrid_xyt.nc" ])
250
+ cube_file_path = _shared_utils .get_data_path (
251
+ ["NetCDF" , "regrid" , "regrid_xyt.nc" ]
252
+ )
245
253
self .cube = load_cube (cube_file_path )
246
254
247
- template_file_path = tests .get_data_path (
255
+ template_file_path = _shared_utils .get_data_path (
248
256
["NetCDF" , "regrid" , "regrid_template_global_latlon.nc" ]
249
257
)
250
258
self .template_cube = load_cube (template_file_path )
@@ -258,16 +266,12 @@ def test_src_stays_lazy(self) -> None:
258
266
regridder = AreaWeightedRegridder (cube , self .template_cube )
259
267
regridder (cube )
260
268
# Base cube stays lazy
261
- self . assertTrue ( cube .has_lazy_data () )
269
+ assert cube .has_lazy_data ()
262
270
263
271
def test_output_lazy (self ) -> None :
264
272
cube = self .cube .copy ()
265
273
# Regrid the cube onto the template.
266
274
regridder = AreaWeightedRegridder (cube , self .template_cube )
267
275
out = regridder (cube )
268
276
# Lazy base cube means lazy output
269
- self .assertTrue (out .has_lazy_data ())
270
-
271
-
272
- if __name__ == "__main__" :
273
- tests .main ()
277
+ assert out .has_lazy_data ()
0 commit comments