Skip to content
This repository was archived by the owner on Apr 27, 2022. It is now read-only.

Commit dfc4814

Browse files
authored
Merge pull request #30 from bjlittle/more-tests
more test coverage
2 parents 3a3a2e8 + 9860755 commit dfc4814

File tree

2 files changed

+140
-36
lines changed

2 files changed

+140
-36
lines changed

agg_regrid/__init__.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,17 @@ def __init__(self, src_grid_cube, tgt_grid_cube):
9898

9999
# Snapshot the state of the grid cubes to ensure that the regridder
100100
# is impervious to external changes to the original cubes.
101-
self._src_grid = snapshot_grid(src_grid_cube)
101+
self._sx, self._sy = snapshot_grid(src_grid_cube)
102102
self._gx, self._gy = snapshot_grid(tgt_grid_cube)
103103

104-
# Check the grid cube coordinate system.
104+
# Check the source grid cube coordinate system.
105+
if self._sx.coord_system is None or self._sy.coord_system is None:
106+
emsg = 'The source grid cube requires a native coordinate system.'
107+
raise ValueError(emsg)
108+
109+
# Check the target grid cube coordinate system.
105110
if self._gx.coord_system is None or self._gy.coord_system is None:
106-
emsg = 'The grid cube requires a native coordinate system.'
111+
emsg = 'The target grid cube requires a native coordinate system.'
107112
raise ValueError(emsg)
108113

109114
# Cache the grid bounds converted to the source crs.
@@ -138,17 +143,16 @@ def __call__(self, src_cube):
138143
"""
139144
# Sanity check the supplied source cube.
140145
if not isinstance(src_cube, iris.cube.Cube):
141-
raise TypeError('The source must be a cube.')
146+
emsg = 'The source must be a cube, got {}.'
147+
raise TypeError(emsg.format(type(src_cube)))
142148

143149
# Get the source cube x and y coordinates.
144150
sx, sy = get_xy_dim_coords(src_cube)
145-
if (sx, sy) != self._src_grid:
151+
152+
if (sx, sy) != (self._sx, self._sy):
146153
emsg = 'The source cube is not defined on the same source grid ' \
147154
'as this regridder.'
148155
raise ValueError(emsg)
149-
if sx.coord_system is None:
150-
msg = 'The source cube requires a native coordinate system.'
151-
raise ValueError(msg)
152156

153157
# Convert the contiguous bounds of the grid to the source crs.
154158
gxx, gyy = np.meshgrid(self._gx.contiguous_bounds(),
@@ -182,7 +186,6 @@ def __call__(self, src_cube):
182186
#
183187
result_cube = iris.cube.Cube(result)
184188
result_cube.metadata = copy.deepcopy(src_cube.metadata)
185-
coord_mapping = {}
186189

187190
def copy_coords(coords, add_coord):
188191
for coord in coords:
@@ -195,7 +198,6 @@ def copy_coords(coords, add_coord):
195198
continue
196199
result_coord = coord.copy()
197200
add_coord(result_coord, dims)
198-
coord_mapping[id(coord)] = result_coord
199201

200202
copy_coords(src_cube.dim_coords, result_cube.add_dim_coord)
201203
copy_coords(src_cube.aux_coords, result_cube.add_aux_coord)

agg_regrid/tests/test__AreadWeightedRegridder.py

Lines changed: 128 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ class Test(unittest.TestCase):
3535
def setUp(self):
3636
self.src_cube = mock.Mock(spec=iris.cube.Cube)
3737
self.tgt_cube = mock.Mock(spec=iris.cube.Cube)
38+
scs = mock.sentinel.srs
39+
self.sx = mock.Mock(coord_system=scs)
40+
self.sy = mock.Mock(coord_system=scs)
41+
tcs = mock.sentinel.tcs
42+
self.gx = mock.Mock(coord_system=tcs)
43+
self.gy = mock.Mock(coord_system=tcs)
44+
self.src_grid = (self.sx, self.sy)
45+
self.tgt_grid = (self.gx, self.gy)
46+
self.side_effect = (self.src_grid, self.tgt_grid)
47+
self.snapshot_grid = 'agg_regrid.snapshot_grid'
3848

3949
def test_bad_src_grid_cube(self):
4050
emsg = 'source grid must be a cube'
@@ -46,51 +56,143 @@ def test_bad_tgt_grid_cube(self):
4656
with assertRaisesRegex(self, TypeError, emsg):
4757
Regridder(self.src_cube, 'dummy')
4858

49-
def test_snapshot_grid(self):
50-
snapshot = 'agg_regrid.snapshot_grid'
51-
src_grid = mock.sentinel.src_grid
52-
gx = mock.Mock(coord_system=True)
53-
gy = mock.Mock(coord_system=True)
54-
tgt_grid = (gx, gy)
55-
side_effect = [src_grid, tgt_grid]
56-
57-
with mock.patch(snapshot, side_effect=side_effect):
59+
def test_src_grid_tgt_grid(self):
60+
with mock.patch(self.snapshot_grid, side_effect=self.side_effect):
5861
regridder = Regridder(self.src_cube, self.tgt_cube)
5962

60-
self.assertEqual(regridder._src_grid, src_grid)
61-
self.assertEqual(regridder._gx, gx)
62-
self.assertEqual(regridder._gy, gy)
63+
self.assertEqual(regridder._sx, self.sx)
64+
self.assertEqual(regridder._sy, self.sy)
65+
self.assertEqual(regridder._gx, self.gx)
66+
self.assertEqual(regridder._gy, self.gy)
6367
self.assertIsNone(regridder._gx_bounds)
6468
self.assertIsNone(regridder._gy_bounds)
6569
self.assertIsNone(regridder._sx_bounds)
6670
self.assertIsNone(regridder._sy_bounds)
6771

72+
def test_snapshot_grid__no_sx_coord_system(self):
73+
sx = mock.Mock(coord_system=None)
74+
src_grid = (sx, self.sy)
75+
side_effect = (src_grid, self.tgt_grid)
76+
77+
with mock.patch(self.snapshot_grid, side_effect=side_effect):
78+
emsg = 'source grid cube requires a native coordinate system'
79+
with assertRaisesRegex(self, ValueError, emsg):
80+
Regridder(self.src_cube, self.tgt_cube)
81+
82+
def test_snapshot_grid__no_sy_coord_system(self):
83+
sy = mock.Mock(coord_system=None)
84+
src_grid = (self.sx, sy)
85+
side_effect = (src_grid, self.tgt_grid)
86+
87+
with mock.patch(self.snapshot_grid, side_effect=side_effect):
88+
emsg = 'source grid cube requires a native coordinate system'
89+
with assertRaisesRegex(self, ValueError, emsg):
90+
Regridder(self.src_cube, self.tgt_cube)
91+
6892
def test_snapshot_grid__no_gx_coord_system(self):
69-
snapshot = 'agg_regrid.snapshot_grid'
70-
src_grid = mock.sentinel.src_grid
7193
gx = mock.Mock(coord_system=None)
72-
gy = mock.Mock(coord_system=True)
73-
tgt_grid = (gx, gy)
74-
side_effect = [src_grid, tgt_grid]
94+
tgt_grid = (gx, self.gy)
95+
side_effect = (self.src_grid, tgt_grid)
7596

76-
with mock.patch(snapshot, side_effect=side_effect):
77-
emsg = 'grid cube requires a native coordinate system'
97+
with mock.patch(self.snapshot_grid, side_effect=side_effect):
98+
emsg = 'target grid cube requires a native coordinate system'
7899
with assertRaisesRegex(self, ValueError, emsg):
79100
Regridder(self.src_cube, self.tgt_cube)
80101

81102
def test_snapshot_grid__no_gy_coord_system(self):
82-
snapshot = 'agg_regrid.snapshot_grid'
83-
src_grid = mock.sentinel.src_grid
84-
gx = mock.Mock(coord_system=True)
85103
gy = mock.Mock(coord_system=None)
86-
tgt_grid = (gx, gy)
87-
side_effect = [src_grid, tgt_grid]
104+
tgt_grid = (self.gx, gy)
105+
side_effect = (self.src_grid, tgt_grid)
88106

89-
with mock.patch(snapshot, side_effect=side_effect):
90-
emsg = 'grid cube requires a native coordinate system'
107+
with mock.patch(self.snapshot_grid, side_effect=side_effect):
108+
emsg = 'target grid cube requires a native coordinate system'
91109
with assertRaisesRegex(self, ValueError, emsg):
92110
Regridder(self.src_cube, self.tgt_cube)
93111

94112

113+
class Test___call__(unittest.TestCase):
114+
def setUp(self):
115+
self.src_cube = mock.Mock(spec=iris.cube.Cube)
116+
self.tgt_cube = mock.Mock(spec=iris.cube.Cube)
117+
self.sx_dim = mock.sentinel.sx_dim
118+
self.sy_dim = mock.sentinel.sy_dim
119+
coord_dims = mock.Mock(side_effect=([self.sx_dim], [self.sy_dim]))
120+
self.metadata = dict(standard_name='air_pressure',
121+
long_name='long_name', var_name='var_name',
122+
units='Pa', attributes={}, cell_methods=())
123+
self.data = mock.sentinel.data
124+
self.cube = mock.Mock(spec=iris.cube.Cube, coord_dims=coord_dims,
125+
metadata=self.metadata, dim_coords=(),
126+
aux_coords=(), data=self.data)
127+
scrs = mock.sentinel.scrs
128+
self.sxp = mock.sentinel.sx_points
129+
self.sxb = mock.sentinel.sx_contiguous_bounds
130+
self.syp = mock.sentinel.sy_points
131+
self.syb = mock.sentinel.sy_contiguous_bounds
132+
self.sx = mock.Mock(coord_system=scrs,
133+
points=self.sxp,
134+
contiguous_bounds=mock.Mock(return_value=self.sxb))
135+
self.sy = mock.Mock(coord_system=scrs,
136+
points=self.syp,
137+
contiguous_bounds=mock.Mock(return_value=self.syb))
138+
tcrs = mock.sentinel.tcrs
139+
gx = mock.Mock(coord_system=tcrs)
140+
gy = mock.Mock(coord_system=tcrs)
141+
self.src_grid = (self.sx, self.sy)
142+
tgt_grid = (gx, gy)
143+
self.side_effect = (self.src_grid, tgt_grid)
144+
self.snapshot_grid = 'agg_regrid.snapshot_grid'
145+
self.get_xy_dim_coords = 'agg_regrid.get_xy_dim_coords'
146+
147+
def test_bad_src_cube(self):
148+
with mock.patch(self.snapshot_grid, side_effect=self.side_effect):
149+
emsg = 'source must be a cube'
150+
with assertRaisesRegex(self, TypeError, emsg):
151+
regridder = Regridder(self.src_cube, self.tgt_cube)
152+
regridder('dummy')
153+
154+
def test_bad_src_cube__sx_different_grid(self):
155+
with mock.patch(self.snapshot_grid, side_effect=self.side_effect):
156+
return_value = (False, self.sy)
157+
with mock.patch(self.get_xy_dim_coords, return_value=return_value):
158+
emsg = 'source cube is not defined on the same source grid'
159+
with assertRaisesRegex(self, ValueError, emsg):
160+
regridder = Regridder(self.src_cube, self.tgt_cube)
161+
regridder(self.cube)
162+
163+
def test_bad_src_cube__sy_different_grid(self):
164+
with mock.patch(self.snapshot_grid, side_effect=self.side_effect):
165+
return_value = (self.sx, False)
166+
with mock.patch(self.get_xy_dim_coords, return_value=return_value):
167+
emsg = 'source cube is not defined on the same source grid'
168+
with assertRaisesRegex(self, ValueError, emsg):
169+
regridder = Regridder(self.src_cube, self.tgt_cube)
170+
regridder(self.cube)
171+
172+
def test_same_crs(self):
173+
side_effect = (self.src_grid, self.src_grid)
174+
with mock.patch(self.snapshot_grid, side_effect=side_effect):
175+
with mock.patch(self.get_xy_dim_coords,
176+
return_value=self.src_grid):
177+
gxx, gyy = (mock.sentinel.gxx, mock.sentinel.gyy)
178+
with mock.patch('numpy.meshgrid', return_value=(gxx, gyy)):
179+
data = 1
180+
with mock.patch('agg_regrid.agg',
181+
return_value=data) as magg:
182+
regridder = Regridder(self.src_cube, self.tgt_cube)
183+
result = regridder(self.cube)
184+
185+
self.assertEqual(regridder._sx_bounds, self.sxb)
186+
self.assertEqual(regridder._sy_bounds, self.syb)
187+
self.assertEqual(regridder._gx_bounds, gxx)
188+
self.assertEqual(regridder._gy_bounds, gyy)
189+
expected = [mock.call(self.data, self.sxp, self.sxb, self.syp,
190+
self.syb, self.sx_dim, self.sy_dim, gxx, gyy)]
191+
self.assertEqual(magg.call_args_list, expected)
192+
cube = iris.cube.Cube(data)
193+
cube.metadata = self.metadata
194+
self.assertEqual(result, cube)
195+
196+
95197
if __name__ == '__main__':
96198
unittest.main()

0 commit comments

Comments
 (0)