Passed
Pull Request — develop (#43)
by Angeline
01:19
created

TestDepAACGMV2.test_convert_unequal_arra()   A

Complexity

Conditions 2

Size

Total Lines 18
Code Lines 16

Duplication

Lines 18
Ratio 100 %

Importance

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