Completed
Pull Request — develop (#43)
by Angeline
01:17
created

TestDepAACGMV2.test_convert_mult_array_failure()   A

Complexity

Conditions 3

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nop 1
1
# -*- coding: utf-8 -*-
2
from __future__ import division, absolute_import, unicode_literals
3
4
import datetime as dt
5
from io import StringIO
6
import logging
7
import numpy as np
8
import pytest
9
from sys import version_info
10
import warnings
11
12
import aacgmv2
13
14
if version_info.major == 2:
15
    warnings.filterwarnings('error')
16
17
class TestFutureDepWarning:
18
    def setup(self):
19
        # Initialize the routine to be tested
20
        self.test_routine = None
21
        self.test_args = []
22
        self.test_kwargs = {}
23
24
    def teardown(self):
25
        del self.test_routine, self.test_args, self.test_kwargs
26
27
    def test_future_dep_warning(self):
28
        """Test the implementation of FutureWarning for deprecated routines"""
29
        if self.test_routine is None:
30
            assert True
31
        else:
32
            with warnings.catch_warnings(record=True) as wout:
33
                # Cause all warnings to always be triggered.
34
                warnings.simplefilter("always")
35
36
                # Trigger a warning.
37
                self.test_routine(*self.test_args, **self.test_kwargs)
38
39
                # Verify some things
40
                assert len(wout) == 1
41
                assert issubclass(wout[-1].category, FutureWarning)
42
                assert "Deprecated routine" in str(wout[-1].message)
43
44
45
class TestDepAACGMV2Warning(TestFutureDepWarning):
46
    def setup(self):
47
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
48
        self.test_routine = None
49
        self.test_args = []
50
        self.test_kwargs = {}
51
52
    def teardown(self):
53
        del self.dtime, self.test_routine, self.test_args, self.test_kwargs
54
55
    def test_convert_warning(self):
56
        """Test future deprecation warning for convert"""
57
58
        self.test_routine = aacgmv2.deprecated.convert
59
        self.test_args = [60, 0, 300, self.dtime]
60
        self.test_future_dep_warning()
61
62
    def test_subsol_warning(self):
63
        """Test future deprecation warning for subsol"""
64
65
        self.test_routine = aacgmv2.deprecated.subsol
66
        self.test_args = [self.dtime.year, int(self.dtime.strftime("%j")),
67
                          self.dtime.second + self.dtime.minute * 60 +
68
                          self.dtime.hour * 3600]
69
        self.test_future_dep_warning()
70
71
    def test_gc2gd_lat_warning(self):
72
        """Test future deprecation warning for gc2gd_lat"""
73
74
        self.test_routine = aacgmv2.deprecated.gc2gd_lat
75
        self.test_args = [60.0]
76
        self.test_future_dep_warning()
77
78
    def test_igrf_dipole_axis_warning(self):
79
        """Test future deprecation warning for igrf_dipole_axis"""
80
81
        self.test_routine = aacgmv2.deprecated.igrf_dipole_axis
82
        self.test_args = [self.dtime]
83
        self.test_future_dep_warning()
84
85
86
class TestDepLogging:
87
    def setup(self):
88
        """Runs before every method to create a clean testing setup"""
89
90
        self.log_capture = StringIO()
91
        aacgmv2.logger.addHandler(logging.StreamHandler(self.log_capture))
92
93
        self.in_convert = [[60], [0], [-1], dt.datetime(2015, 1, 1, 0, 0, 0)]
94
        self.lout = ''
95
        self.lwarn = ''
96
97
    def teardown(self):
98
        """Runs after every method to clean up previous testing"""
99
        self.log_capture.close()
100
        del self.in_convert, self.lwarn, self.lout
101
102
    def test_warning_below_ground_convert(self):
103
        """ Test that a warning is issued if altitude is below zero"""
104
        self.lwarn = u"conversion not intended for altitudes < 0 km"
105
106
        with warnings.catch_warnings():
107
            # Cause all warnings to be ignored
108
            warnings.simplefilter("ignore")
109
110
            # Trigger the below ground warning
111
            aacgmv2.convert(*self.in_convert)
112
113
            # Test the logging output
114
            self.lout = self.log_capture.getvalue()
115
            assert self.lout.find(self.lwarn) >= 0
116
117
    @pytest.mark.skipif(version_info.major == 2,
118
                        reason='Not raised in Python 2')
119
    def test_warning_c_failure_convert(self):
120
        """ Test that a warning is issued if the C routine exits with failure"""
121
        self.lwarn = u"C Error encountered: "
122
        self.in_convert[0] = [0]
123
        self.in_convert[2] = [0]
124
125
        with warnings.catch_warnings():
126
            # Cause all warnings to be ignored
127
            warnings.simplefilter("ignore")
128
129
            # Trigger the C failure logger warning
130
            aacgmv2.convert(*self.in_convert)
131
132
            # Test the logging output
133
            self.lout = self.log_capture.getvalue()
134
            assert self.lout.find(self.lwarn) >= 0
135
136
137
class TestDepAACGMV2:
138
    def setup(self):
139
        """Runs before every method to create a clean testing setup"""
140
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
141
        self.ddate = dt.date(2015, 1, 1)
142
        self.lat = None
143
        self.lon = None
144
145
    def teardown(self):
146
        """Runs after every method to clean up previous testing"""
147
        del self.dtime, self.ddate, self.lat, self.lon
148
149 View Code Duplication
    def test_convert_single_val(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
150
        """Test conversion for a single value"""
151
        with warnings.catch_warnings():
152
            warnings.simplefilter("ignore")
153
            self.lat, self.lon = aacgmv2.convert(60, 0, 300, self.dtime)
154
155
        assert isinstance(self.lat, list)
156
        assert isinstance(self.lon, list)
157
        assert len(self.lat) == len(self.lon) and len(self.lat) == 1
158
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
159
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
160
161
    def test_convert_list(self):
162
        """Test conversion for list input"""
163
        with warnings.catch_warnings():
164
            warnings.simplefilter("ignore")
165
            self.lat, self.lon = aacgmv2.convert([60], [0], [300], self.dtime)
166
167
        assert isinstance(self.lat, list)
168
        assert isinstance(self.lon, list)
169
        assert len(self.lat) == len(self.lon) and len(self.lat) == 1
170
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
171
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
172
173
        with warnings.catch_warnings():
174
            warnings.simplefilter("ignore")
175
            self.lat, self.lon = aacgmv2.convert([60, 61], [0, 0], [300, 300],
176
                                                 self.dtime)
177
178
        assert isinstance(self.lat, list)
179
        assert isinstance(self.lon, list)
180
        assert len(self.lat) == len(self.lon) and len(self.lat) == 2
181
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
182
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
183
184
    def test_convert_arr_single(self):
185
        """Test conversion for array input with one element"""
186
        with warnings.catch_warnings():
187
            warnings.simplefilter("ignore")
188
            self.lat, self.lon = aacgmv2.convert(np.array([60]), np.array([0]),
189
                                                 np.array([300]), self.dtime)
190
191
        assert isinstance(self.lat, list)
192
        assert isinstance(self.lon, list)
193
        assert len(self.lat) == len(self.lon) and len(self.lat) == 1
194
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
195
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
196
197
    def test_convert_arr(self):
198
        """Test conversion for array input"""
199
        
200
        with warnings.catch_warnings():
201
            warnings.simplefilter("ignore")
202
            self.lat, self.lon = aacgmv2.convert(np.array([60, 61]),
203
                                                 np.array([0, 0]),
204
                                                 np.array([300, 300]),
205
                                                 self.dtime)
206
207
        assert isinstance(self.lat, list)
208
        assert isinstance(self.lon, list)
209
        assert len(self.lat) == len(self.lon) and len(self.lat) == 2
210
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
211
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
212
213 View Code Duplication
    def test_convert_list_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
214
        """Test conversion for a list and floats"""
215
        
216
        with warnings.catch_warnings():
217
            warnings.simplefilter("ignore")
218
            self.lat, self.lon = aacgmv2.convert([60, 61], 0, 300, self.dtime)
219
220
        assert isinstance(self.lat, list)
221
        assert isinstance(self.lon, list)
222
        assert len(self.lat) == len(self.lon) and len(self.lat) == 2
223
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
224
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
225
226 View Code Duplication
    def test_convert_arr_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
227
        """Test conversion for an array and floats"""
228
        with warnings.catch_warnings():
229
            warnings.simplefilter("ignore")
230
            self.lat, self.lon = aacgmv2.convert(np.array([60, 61]), 0, 300,
231
                                                 self.dtime)
232
233
        assert isinstance(self.lat, list)
234
        assert isinstance(self.lon, list)
235
        assert len(self.lat) == len(self.lon) and len(self.lat) == 2
236
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
237
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
238
239
    def test_convert_mult_array_failure(self):
240
        """Test conversion for a multi-dim array and floats"""
241
        with warnings.catch_warnings():
242
            warnings.simplefilter("ignore")
243
            with pytest.raises(ValueError):
244
                self.lat, self.lon = aacgmv2.convert(np.array([[60, 61, 62],
245
                                                               [63, 64, 65]]),
246
                                                     0, 300, self.dtime)
247
248
    def test_convert_location_failure(self):
249
        """Test conversion with a bad location"""
250
        self.lat, self.lon = aacgmv2.convert([0], [0], [0], self.dtime)
251
252
        assert len(self.lat) == len(self.lon) and len(self.lat) == 1
253
        assert np.all([~np.isfinite(self.lat), ~np.isfinite(self.lon)])
254
255
    def test_convert_time_failure(self):
256
        """Test conversion with a bad time"""
257
        with pytest.raises(ValueError):
258
            with warnings.catch_warnings():
259
                warnings.simplefilter("ignore")
260
                self.lat, self.lon = aacgmv2.convert([60], [0], [300], None)
261
262
    def test_convert_datetime_date(self):
263
        """Test conversion with date and datetime input"""
264
        with warnings.catch_warnings():
265
            warnings.simplefilter("ignore")
266
            self.lat, self.lon = aacgmv2.convert([60], [0], [300], self.ddate)
267
268
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
269
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
270
271
    def test_convert_maxalt_failure(self):
272
        """For an array, test failure for an altitude too high for
273
        coefficients"""
274
        with pytest.raises(ValueError):
275
            with warnings.catch_warnings():
276
                warnings.simplefilter("ignore")
277
                aacgmv2.convert([60], [0], [2001], self.dtime)
278
279
    def test_convert_lat_failure(self):
280
        """Test error return for co-latitudes above 90 for an array"""
281
        with pytest.raises(ValueError):
282
            with warnings.catch_warnings():
283
                warnings.simplefilter("ignore")
284
                aacgmv2.convert([91, 60, -91], 0, 300, self.dtime)
285
286
    def test_subsol(self):
287
        """Test the subsolar calculation"""
288
        doy = int(self.dtime.strftime("%j"))
289
        ut = self.dtime.hour * 3600.0 + self.dtime.minute * 60.0 + \
290
             self.dtime.second
291
        with warnings.catch_warnings():
292
            warnings.simplefilter("ignore")
293
            self.lon, self.lat = aacgmv2.deprecated.subsol(self.dtime.year,
294
                                                           doy, ut)
295
296
        np.testing.assert_almost_equal(self.lon, -179.2004, decimal=4)
297
        np.testing.assert_almost_equal(self.lat, -23.0431, decimal=4)
298
299
    def test_gc2gd_lat(self):
300
        """Test the geocentric to geodetic conversion"""
301
        with warnings.catch_warnings():
302
            warnings.simplefilter("ignore")
303
            self.lat = aacgmv2.deprecated.gc2gd_lat(45.0)
304
305
        np.testing.assert_almost_equal(self.lat, 45.1924, decimal=4)
306
307
    def test_gc2gd_lat_list(self):
308
        """Test the geocentric to geodetic conversion"""
309
        self.lat = [45.0, -45.0]
310
        with warnings.catch_warnings():
311
            warnings.simplefilter("ignore")
312
            self.lat = aacgmv2.deprecated.gc2gd_lat(self.lat)
313
314
        np.testing.assert_allclose(self.lat, [45.1924, -45.1924], rtol=1.0e-4)
315
316
    def test_gc2gd_lat_arr(self):
317
        """Test the geocentric to geodetic conversion"""
318
        self.lat = np.array([45.0, -45.0])
319
        with warnings.catch_warnings():
320
            warnings.simplefilter("ignore")
321
            self.lat = aacgmv2.deprecated.gc2gd_lat(self.lat)
322
323
        np.testing.assert_allclose(self.lat, [45.1924, -45.1924], rtol=1.0e-4)
324
325
    def test_igrf_dipole_axis(self):
326
        """Test the IGRF dipole axis calculation"""
327
        with warnings.catch_warnings():
328
            warnings.simplefilter("ignore")
329
            m = aacgmv2.deprecated.igrf_dipole_axis(self.dtime)
330
331
        np.testing.assert_allclose(m, [0.050253, -0.160608, 0.985738],
332
                                   rtol=1.0e-4)
333