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

test_py_aacgmv2   F

Complexity

Total Complexity 185

Size/Duplication

Total Lines 950
Duplicated Lines 15.68 %

Importance

Changes 0
Metric Value
wmc 185
eloc 640
dl 149
loc 950
rs 1.96
c 0
b 0
f 0

115 Methods

Rating   Name   Duplication   Size   Complexity  
A TestConvertLatLonArr.test_convert_latlon_arr_list() 12 12 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_arr_mix() 12 12 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_datetime_date() 15 15 2
A TestCoeffPath.test_set_coeff_path_default() 0 8 3
A TestPyLogging.setup() 0 8 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_maxalt_failure() 0 12 1
A TestMLTConvert.test_inv_convert_mlt_wrapping() 0 9 1
A TestConvertCode.test_convert_bool_to_bit_trace() 0 5 2
A TestMLTConvert.test_inv_convert_mlt_arr() 0 6 1
A TestMLTConvert.test_datetime_exception() 0 4 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_list() 0 12 2
A TestMLTConvert.test_inv_convert_mlt_single() 0 6 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_arr() 13 13 2
A TestConvertCode.test_convert_str_to_bit_a2g() 0 5 2
A TestConvertLatLonArr.setup() 12 12 1
A TestHeightReturns.test_high_trace_good() 0 4 1
A TestCoeffPath.test_set_coeff_path_string() 0 9 3
A TestHeightReturns.test_high_coeff_good() 0 5 1
A TestConvertLatLonArr.test_convert_latlon_arr_mult_failure() 0 5 2
A TestConvertCode.test_convert_str_to_bit_lowercase() 0 5 2
A TestCoeffPath.setup() 0 6 1
A TestPyLogging.test_warning_high_coeff() 0 8 2
A TestConvertLatLonArr.test_convert_latlon_arr_time_failure() 0 5 2
A TestCoeffPath.test_set_only_aacgm_coeff_path() 0 8 3
A TestTimeReturns.test_good_time_with_nonzero_time() 0 4 1
A TestMLTConvert.test_mlt_convert_single() 0 6 2
A TestMLTConvert.teardown() 0 4 1
A TestConvertLatLonArr.test_convert_latlon_arr_lat_failure() 0 4 2
A TestConvertLatLonArr.test_convert_latlon_arr_badidea() 12 12 2
A TestConvertCode.test_convert_str_to_bit_g2a() 0 5 2
A TestHeightReturns.setup() 0 5 1
A TestCoeffPath.test_set_coeff_path_true() 0 9 3
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_list_mix() 12 12 2
A TestTimeReturns.setup() 0 5 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_list_single() 0 12 2
A TestTimeReturns.test_good_date() 0 4 1
A TestMLTConvert.test_inv_convert_mlt_list() 0 4 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_arr_single() 0 13 2
A TestConvertLatLon.test_convert_latlon_location_failure() 0 4 1
A TestGetAACGMCoord.test_get_aacgm_coord() 0 4 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_mlat_failure() 0 8 2
A TestConvertLatLonArr.test_convert_latlon_arr_maxalt_failure() 0 6 1
A TestTimeReturns.teardown() 0 3 1
A TestCoeffPath.teardown() 0 3 1
A TestGetAACGMCoord.test_get_aacgm_coord_maxalt_failure() 0 6 1
A TestConvertLatLon.test_convert_latlon() 0 4 1
A TestTimeReturns.test_bad_time() 0 4 2
A TestGetAACGMCoord.test_get_aacgm_coord_datetime_date() 0 5 1
A TestConvertLatLon.test_convert_latlon_badidea() 0 7 1
A TestPyLogging.test_warning_below_ground() 0 8 2
A TestMLTConvert.test_mlt_convert_change() 0 7 1
A TestPyLogging.test_warning_single_loc_in_arr() 0 8 2
A TestConvertCode.test_convert_str_to_bit_spaces() 0 6 2
A TestConvertCode.test_convert_str_to_bit_trace() 0 5 2
A TestGetAACGMCoord.test_get_aacgm_coord_location_failure() 0 7 1
A TestMLTConvert.setup() 0 13 1
A TestGetAACGMCoordArr.teardown() 0 4 1
A TestConvertCode.test_convert_str_to_bit_geocentric() 0 6 2
A TestConvertCode.test_convert_bool_to_bit_g2a() 0 5 2
A TestCoeffPath.test_set_both_mixed() 0 9 3
A TestTimeReturns.test_good_time() 0 4 1
A TestMLTConvert.test_mlt_convert_list() 0 5 1
A TestConvertLatLonArr.test_convert_latlon_arr_list_mix() 12 12 2
A TestGetAACGMCoord.test_get_aacgm_coord_time_failure() 0 5 2
A TestConvertLatLonArr.test_convert_latlon_arr_arr_single() 0 12 2
A TestConvertLatLon.test_convert_latlon_lat_high_failure() 0 4 2
A TestConvertLatLonArr.test_convert_latlon_arr_arr() 0 13 2
A TestConvertCode.test_convert_bool_to_bit_a2g() 0 5 2
A TestConvertLatLon.teardown() 0 3 1
A TestPyLogging.test_warning_magnetosphere() 0 8 2
A TestConvertLatLonArr.teardown() 0 4 1
A TestConvertCode.test_convert_str_to_bit_allowtrace() 0 6 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_single_val() 0 11 2
A TestConvertLatLonArr.test_convert_latlon_arr_badidea_trace() 12 12 2
A TestConvertLatLonArr.test_convert_latlon_arr_single_val() 0 11 2
A TestConvertCode.test_convert_str_to_bit_badidea() 0 6 2
A TestConvertLatLon.test_convert_latlon_trace_badidea() 0 7 1
A TestHeightReturns.teardown() 0 3 1
A TestConvertCode.test_convert_bool_to_bit_allowtrace() 0 6 2
A TestHeightReturns.test_high_trace_bad() 0 4 1
A TestGetAACGMCoord.setup() 0 8 1
A TestGetAACGMCoord.test_get_aacgm_coord_badidea() 0 7 1
A TestConvertLatLonArr.test_convert_latlon_arr_location_failure() 0 13 2
A TestConvertLatLon.setup() 0 8 1
A TestConvertLatLonArr.test_convert_latlon_arr_mult_arr_unequal_failure() 0 5 2
A TestGetAACGMCoord.test_get_aacgm_coord_mlat_high_failure() 0 5 2
A TestMLTConvert.test_mlt_convert_mismatch_failure() 0 5 2
A TestGetAACGMCoord.test_get_aacgm_coord_mlat_low_failure() 0 5 2
A TestMLTConvert.test_mlt_convert_arr() 0 5 1
A TestConvertLatLonArr.test_convert_latlon_arr_datetime_date() 0 12 2
A TestHeightReturns.test_high_coeff_bad() 0 5 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_badidea() 13 13 2
A TestConvertLatLon.test_convert_latlon_maxalt_failure() 0 6 1
A TestConvertLatLon.test_convert_latlon_datetime_date() 0 5 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_mult_failure() 0 7 2
A TestMLTConvert.test_mlt_convert_multidim_failure() 0 5 2
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_location_failure() 0 9 1
A TestGetAACGMCoordArr.test_get_aacgm_coord_arr_time_failure() 0 5 2
A TestConvertLatLon.test_convert_latlon_time_failure() 0 5 2
A TestPyLogging.teardown() 0 4 1
A TestConvertCode.test_convert_bool_to_bit_geocentric() 0 6 2
A TestConvertLatLonArr.test_convert_latlon_arr_list_single() 0 12 2
A TestMLTConvert.test_mlt_convert_list_w_times() 0 6 1
A TestConvertCode.test_convert_bool_to_bit_badidea() 0 6 2
A TestConvertLatLonArr.test_convert_latlon_arr_arr_mix() 12 12 2
A TestMLTConvert.test_date_input() 0 5 1
A TestHeightReturns.test_low_coeff_good() 0 4 1
A TestGetAACGMCoordArr.setup() 12 12 1
A TestGetAACGMCoord.teardown() 0 3 1
A TestHeightReturns.test_low_trace_good() 0 4 1
A TestHeightReturns.test_low_height_good() 0 4 1
A TestConvertLatLon.test_convert_latlon_lat_low_failure() 0 4 2
A TestCoeffPath.test_set_only_igrf_coeff_path() 0 8 3
A TestConvertCode.test_convert_str_to_bit_invalid() 0 5 2
A TestMLTConvert.test_mlt_convert_mlon_wrapping() 0 9 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like test_py_aacgmv2 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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 os
9
from sys import version_info
10
import pytest
11
import warnings
12
13
import aacgmv2
14
15
if version_info.major == 2:
16
    warnings.filterwarnings('error')
17
18
class TestConvertLatLon:
19
    def setup(self):
20
        """Runs before every method to create a clean testing setup"""
21
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
22
        self.ddate = dt.date(2015, 1, 1)
23
        self.in_args = [60, 0, 300, self.dtime, 'TRACE']
24
        self.out = None
25
        self.ref = [58.2258, 81.1685, 1.0457]
26
        self.rtol = 1.0e-4
27
28
    def teardown(self):
29
        """Runs after every method to clean up previous testing"""
30
        del self.out, self.in_args, self.ref, self.rtol, self.dtime, self.ddate
31
32
    def test_convert_latlon(self):
33
        """Test single value latlon conversion"""
34
        self.out = aacgmv2.convert_latlon(*self.in_args)
35
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
36
37
    def test_convert_latlon_badidea(self):
38
        """Test single value latlon conversion with a bad flag"""
39
        self.in_args[2] = 3000.0
40
        self.in_args[-1] = "G2A|BADIDEA"
41
        self.ref = [64.3568, 83.3027, 1.4694]
42
        self.out = aacgmv2.convert_latlon(*self.in_args)
43
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
44
45
    def test_convert_latlon_trace_badidea(self):
46
        """Test single value latlon conversion with a bad flag for trace"""
47
        self.in_args[2] = 7000.0
48
        self.in_args[-1] = "G2A|TRACE|BADIDEA"
49
        self.ref = [69.3174, 85.0995, 2.0973]
50
        self.out = aacgmv2.convert_latlon(*self.in_args)
51
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
52
53
    def test_convert_latlon_location_failure(self):
54
        """Test single value latlon conversion with a bad location"""
55
        self.out = aacgmv2.convert_latlon(0, 0, 0, self.dtime, self.in_args[-1])
56
        assert np.all(np.isnan(np.array(self.out)))
57
58
    def test_convert_latlon_time_failure(self):
59
        """Test single value latlon conversion with a bad datetime"""
60
        self.in_args[3] = None
61
        with pytest.raises(ValueError):
62
            self.out = aacgmv2.convert_latlon(*self.in_args)
63
64
    def test_convert_latlon_datetime_date(self):
65
        """Test single latlon conversion with date and datetime input"""
66
        self.in_args[3] = self.ddate
67
        self.out = aacgmv2.convert_latlon(*self.in_args)
68
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
69
70
    def test_convert_latlon_maxalt_failure(self):
71
        """test convert_latlon failure for an altitude too high for coeffs"""
72
        self.in_args[2] = 2001
73
        self.in_args[-1] = ""
74
        self.out = aacgmv2.convert_latlon(*self.in_args)
75
        assert np.all(np.isnan(np.array(self.out)))
76
77
    def test_convert_latlon_lat_high_failure(self):
78
        """Test error return for co-latitudes above 90 for a single value"""
79
        with pytest.raises(ValueError):
80
            aacgmv2.convert_latlon(91, 0, 300, self.dtime)
81
82
    def test_convert_latlon_lat_low_failure(self):
83
        """Test error return for co-latitudes below -90 for a single value"""
84
        with pytest.raises(ValueError):
85
            aacgmv2.convert_latlon(-91, 0, 300, self.dtime)
86
87
class TestConvertLatLonArr:
88 View Code Duplication
    def setup(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
89
        """Runs before every method to create a clean testing setup"""
90
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
91
        self.ddate = dt.date(2015, 1, 1)
92
        self.lat_in = [60.0, 61.0]
93
        self.lon_in = [0.0, 0.0]
94
        self.alt_in = [300.0, 300.0]
95
        self.method = 'TRACE'
96
        self.out = None
97
        self.ref = [[58.22474610, 59.31648007], [81.17611033, 81.62281360],
98
                    [1.04566346, 1.04561304]]
99
        self.rtol = 1.0e-4
100
101
    def teardown(self):
102
        """Runs after every method to clean up previous testing"""
103
        del self.lat_in, self.lon_in, self.alt_in, self.dtime, self.ddate
104
        del self.method, self.out, self.ref, self.rtol
105
106
    def test_convert_latlon_arr_single_val(self):
107
        """Test array latlon conversion for a single value"""
108
        self.out = aacgmv2.convert_latlon_arr(self.lat_in[0], self.lon_in[0],
109
                                              self.alt_in[0], self.dtime,
110
                                              self.method)
111
112
        assert len(self.out) == len(self.ref)
113
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
114
115
        for i, oo in enumerate(self.out):
116
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
117
118
    def test_convert_latlon_arr_list_single(self):
119
        """Test array latlon conversion for list input of single values"""
120
        self.out = aacgmv2.convert_latlon_arr([self.lat_in[0]],
121
                                              [self.lon_in[0]],
122
                                              [self.alt_in[0]], self.dtime,
123
                                              self.method)
124
125
        assert len(self.out) == len(self.ref)
126
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
127
128
        for i, oo in enumerate(self.out):
129
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
130
131 View Code Duplication
    def test_convert_latlon_arr_list(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
132
        """Test array latlon conversion for list input"""
133
        self.out = aacgmv2.convert_latlon_arr(self.lat_in, self.lon_in,
134
                                              self.alt_in, self.dtime,
135
                                              self.method)
136
137
        assert len(self.out) == len(self.ref)
138
        assert [isinstance(oo, list) and len(oo) == len(self.ref[i])
139
                for i, oo in enumerate(self.out)]
140
141
        for i, oo in enumerate(self.out):
142
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
143
144
    def test_convert_latlon_arr_arr_single(self):
145
        """Test array latlon conversion for array input of shape (1,)"""
146
        self.out = aacgmv2.convert_latlon_arr(np.array([self.lat_in[0]]),
147
                                              np.array([self.lon_in[0]]),
148
                                              np.array([self.alt_in[0]]),
149
                                              self.dtime, self.method)
150
151
        assert len(self.out) == len(self.ref)
152
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
153
154
        for i, oo in enumerate(self.out):
155
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
156
157
    def test_convert_latlon_arr_arr(self):
158
        """Test array latlon conversion for array input"""
159
        self.out = aacgmv2.convert_latlon_arr(np.array(self.lat_in),
160
                                              np.array(self.lon_in),
161
                                              np.array(self.alt_in),
162
                                              self.dtime, self.method)
163
164
        assert len(self.out) == len(self.ref)
165
        assert [isinstance(oo, list) and len(oo) == len(self.ref[i])
166
                for i, oo in enumerate(self.out)]
167
168
        for i, oo in enumerate(self.out):
169
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
170
171 View Code Duplication
    def test_convert_latlon_arr_list_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
172
        """Test array latlon conversion for mixed types with list"""
173
        self.out = aacgmv2.convert_latlon_arr(self.lat_in, self.lon_in[0],
174
                                              self.alt_in[0], self.dtime,
175
                                              self.method)
176
177
        assert len(self.out) == len(self.ref)
178
        assert [isinstance(oo, list) and len(oo) == len(self.ref[i])
179
                for i, oo in enumerate(self.out)]
180
181
        for i, oo in enumerate(self.out):
182
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
183
184 View Code Duplication
    def test_convert_latlon_arr_arr_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
185
        """Test array latlon conversion for mixed type with an array"""
186
        self.out = aacgmv2.convert_latlon_arr(np.array(self.lat_in),
187
                                              self.lon_in[0], self.alt_in[0],
188
                                              self.dtime, self.method)
189
190
        assert len(self.out) == len(self.ref)
191
        assert [isinstance(oo, list) and len(oo) == len(self.ref[i])
192
                for i, oo in enumerate(self.out)]
193
194
        for i, oo in enumerate(self.out):
195
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
196
197
    def test_convert_latlon_arr_mult_failure(self):
198
        """Test array latlon conversion for mix type with multi-dim array"""
199
        with pytest.raises(ValueError):
200
            aacgmv2.convert_latlon_arr(np.full(shape=(3,2), fill_value=50.0),
201
                                       0, 300, self.dtime)
202
203
204 View Code Duplication
    def test_convert_latlon_arr_badidea(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
205
        """Test array latlon conversion for BADIDEA"""
206
        self.method = "G2A | BADIDEA"
207
        self.ref = [64.35677791, 83.30272053, 1.46944431]
208
        self.out = aacgmv2.convert_latlon_arr(self.lat_in[0], self.lon_in[0],
209
                                              [3000], self.dtime, self.method)
210
211
        assert len(self.out) == len(self.ref)
212
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
213
214
        for i, oo in enumerate(self.out):
215
            np.testing.assert_allclose(oo, [self.ref[i]], rtol=self.rtol)
216
217 View Code Duplication
    def test_convert_latlon_arr_badidea_trace(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
218
        """Test array latlon conversion for BADIDEA with trace"""
219
        self.method = "G2A | BADIDEA | TRACE"
220
        self.ref = [69.317391, 85.099499, 2.09726]
221
        self.out = aacgmv2.convert_latlon_arr(self.lat_in[0], self.lon_in[0],
222
                                              [7000], self.dtime, self.method)
223
224
        assert len(self.out) == len(self.ref)
225
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
226
227
        for i, oo in enumerate(self.out):
228
            np.testing.assert_allclose(oo, [self.ref[i]], rtol=self.rtol)
229
230
    def test_convert_latlon_arr_location_failure(self):
231
        """Test array latlon conversion with a bad location"""
232
233
        with warnings.catch_warnings():
234
            # Causes all warnings to be surpressed
235
            warnings.simplefilter("ignore")
236
237
            # Trigger a warning
238
            self.out = aacgmv2.convert_latlon_arr([0], [0], [0], self.dtime, "")
239
240
            # Test the output
241
            assert len(self.out) == len(self.ref)
242
            assert np.any(~np.isfinite(np.array(self.out)))
243
244
    def test_convert_latlon_arr_mult_arr_unequal_failure(self):
245
        """Test array latlon conversion for unequal sized arrays"""
246
        with pytest.raises(ValueError):
247
            aacgmv2.convert_latlon_arr(np.array([[60, 61, 62], [63, 64, 65]]),
248
                                       np.array([0, 1]), 300, self.dtime)
249
250
    def test_convert_latlon_arr_time_failure(self):
251
        """Test array latlon conversion with a bad time"""
252
        with pytest.raises(ValueError):
253
            aacgmv2.convert_latlon_arr(self.lat_in, self.lon_in, self.alt_in,
254
                                       None, self.method)
255
256
    def test_convert_latlon_arr_datetime_date(self):
257
        """Test array latlon conversion with date and datetime input"""
258
        self.out = aacgmv2.convert_latlon_arr(self.lat_in, self.lon_in,
259
                                              self.alt_in, self.ddate,
260
                                              self.method)
261
262
        assert len(self.out) == len(self.ref)
263
        assert [isinstance(oo, list) and len(oo) == len(self.ref[i])
264
                for i, oo in enumerate(self.out)]
265
266
        for i, oo in enumerate(self.out):
267
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
268
269
    def test_convert_latlon_arr_maxalt_failure(self):
270
        """test convert_latlon_arr failure for altitudes too high for coeffs"""
271
        self.method = ""
272
        self.out = aacgmv2.convert_latlon_arr(self.lat_in[0], self.lon_in[0],
273
                                              [2001], self.dtime, self.method)
274
        assert np.all(np.isnan(np.array(self.out)))
275
276
    def test_convert_latlon_arr_lat_failure(self):
277
        """Test error return for co-latitudes above 90 for an array"""
278
        with pytest.raises(ValueError):
279
            aacgmv2.convert_latlon_arr([91, 60, -91], 0, 300, self.dtime)
280
281
class TestGetAACGMCoord:
282
    def setup(self):
283
        """Runs before every method to create a clean testing setup"""
284
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
285
        self.ddate = dt.date(2015, 1, 1)
286
        self.in_args = [60, 0, 300, self.dtime, 'TRACE']
287
        self.out = None
288
        self.ref = [58.22474610, 81.17611033, 0.18892]
289
        self.rtol = 1.0e-4
290
291
    def teardown(self):
292
        """Runs after every method to clean up previous testing"""
293
        del self.out, self.in_args, self.ref, self.rtol, self.dtime, self.ddate
294
295
    def test_get_aacgm_coord(self):
296
        """Test single value AACGMV2 calculation, defaults to TRACE"""
297
        self.out = aacgmv2.get_aacgm_coord(*self.in_args)
298
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
299
300
    def test_get_aacgm_coord_badidea(self):
301
        """Test single value AACGMV2 calculation with a bad flag"""
302
        self.in_args[-1] = "BADIDEA"
303
        self.in_args[2] = 3000
304
        self.ref = [64.3568, 83.3027, 0.3307]
305
        self.out = aacgmv2.get_aacgm_coord(*self.in_args)
306
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
307
308
    def test_get_aacgm_coord_location_failure(self):
309
        """Test single value AACGMV2 calculation with a bad location"""
310
311
        self.in_args[0] = 0.0
312
        self.in_args[2] = 0.0
313
        self.out = aacgmv2.get_aacgm_coord(*self.in_args)
314
        np.all(np.isnan(np.array(self.out)))
315
316
    def test_get_aacgm_coord_time_failure(self):
317
        """Test single value AACGMV2 calculation with a bad datetime"""
318
        self.in_args[3] = None
319
        with pytest.raises(ValueError):
320
            self.out = aacgmv2.get_aacgm_coord(*self.in_args)
321
322
    def test_get_aacgm_coord_mlat_high_failure(self):
323
        """Test error return for co-latitudes above 90 for a single value"""
324
        self.in_args[0] = 91.0
325
        with pytest.raises(ValueError):
326
            aacgmv2.get_aacgm_coord(*self.in_args)
327
328
    def test_get_aacgm_coord_mlat_low_failure(self):
329
        """Test error return for co-latitudes below -90 for a single value"""
330
        self.in_args[0] = -91.0
331
        with pytest.raises(ValueError):
332
            aacgmv2.get_aacgm_coord(*self.in_args)
333
334
    def test_get_aacgm_coord_datetime_date(self):
335
        """Test single AACGMV2 calculation with date and datetime input"""
336
        self.in_args[3] = self.ddate
337
        self.out = aacgmv2.get_aacgm_coord(*self.in_args)
338
        np.testing.assert_allclose(self.out, self.ref, rtol=self.rtol)
339
340
    def test_get_aacgm_coord_maxalt_failure(self):
341
        """test get_aacgm_coord failure for an altitude too high for coeffs"""
342
        self.in_args[2] = 2001
343
        self.in_args[-1] = ""
344
        self.out = aacgmv2.get_aacgm_coord(*self.in_args)
345
        assert np.all(np.isnan(np.array(self.out)))
346
347
class TestGetAACGMCoordArr:
348 View Code Duplication
    def setup(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
349
        """Runs before every method to create a clean testing setup"""
350
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
351
        self.ddate = dt.date(2015, 1, 1)
352
        self.lat_in = [60.0, 61.0]
353
        self.lon_in = [0.0, 0.0]
354
        self.alt_in = [300.0, 300.0]
355
        self.method = 'TRACE'
356
        self.out = None
357
        self.ref = [[58.22474610, 59.31648007], [81.17611033, 81.62281360],
358
                    [0.18891995, 0.21870017]]
359
        self.rtol = 1.0e-4
360
361
    def teardown(self):
362
        """Runs after every method to clean up previous testing"""
363
        del self.out, self.ref, self.lat_in, self.dtime, self.ddate
364
        del self.lon_in, self.alt_in, self.method, self.rtol
365
366
    def test_get_aacgm_coord_arr_single_val(self):
367
        """Test array AACGMV2 calculation for a single value"""
368
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in[0], self.lon_in[0],
369
                                               self.alt_in[0], self.dtime,
370
                                               self.method)
371
372
        assert len(self.out) == len(self.ref)
373
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
374
375
        for i, oo in enumerate(self.out):
376
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
377
378
    def test_get_aacgm_coord_arr_list_single(self):
379
        """Test array AACGMV2 calculation for list input of single values"""
380
        self.out = aacgmv2.get_aacgm_coord_arr([self.lat_in[0]],
381
                                               [self.lon_in[0]],
382
                                               [self.alt_in[0]], self.dtime,
383
                                               self.method)
384
385
        assert len(self.out) == len(self.ref)
386
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
387
388
        for i, oo in enumerate(self.out):
389
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
390
391
    def test_get_aacgm_coord_arr_list(self):
392
        """Test array AACGMV2 calculation for list input"""
393
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in,self.lon_in,
394
                                               self.alt_in, self.dtime,
395
                                               self.method)
396
397
        assert len(self.out) == len(self.ref)
398
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
399
                for oo in self.out]
400
401
        for i, oo in enumerate(self.out):
402
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
403
404
    def test_get_aacgm_coord_arr_arr_single(self):
405
        """Test array AACGMV2 calculation for array with a single value"""
406
        self.out = aacgmv2.get_aacgm_coord_arr(np.array([self.lat_in[0]]),
407
                                               np.array([self.lon_in[0]]),
408
                                               np.array([self.alt_in[0]]),
409
                                               self.dtime, self.method)
410
411
412
        assert len(self.out) == len(self.ref)
413
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
414
415
        for i, oo in enumerate(self.out):
416
            np.testing.assert_allclose(oo, [self.ref[i][0]], rtol=self.rtol)
417
418 View Code Duplication
    def test_get_aacgm_coord_arr_arr(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
419
        """Test array AACGMV2 calculation for an array"""
420
        self.out = aacgmv2.get_aacgm_coord_arr(np.array(self.lat_in),
421
                                               np.array(self.lon_in),
422
                                               np.array(self.alt_in),
423
                                               self.dtime, self.method)
424
425
        assert len(self.out) == len(self.ref)
426
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
427
                for oo in self.out]
428
429
        for i, oo in enumerate(self.out):
430
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
431
432 View Code Duplication
    def test_get_aacgm_coord_arr_list_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
433
        """Test array AACGMV2 calculation for a list and floats"""
434
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in[0],
435
                                               self.alt_in[0], self.dtime,
436
                                               self.method)
437
438
        assert len(self.out) == len(self.ref)
439
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
440
                for oo in self.out]
441
442
        for i, oo in enumerate(self.out):
443
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)  
444
445 View Code Duplication
    def test_get_aacgm_coord_arr_arr_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
446
        """Test array AACGMV2 calculation for an array and floats"""
447
        self.out = aacgmv2.get_aacgm_coord_arr(np.array(self.lat_in),
448
                                               self.lon_in[0], self.alt_in[0],
449
                                               self.dtime, self.method)
450
451
        assert len(self.out) == len(self.ref)
452
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
453
                for oo in self.out]
454
455
        for i, oo in enumerate(self.out):
456
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
457
458
    def test_get_aacgm_coord_arr_mult_failure(self):
459
        """Test aacgm_coord_arr failure with multi-dim array input"""
460
461
        with pytest.raises(ValueError):
462
            (self.mlat_out, self.mlon_out,
463
             self.mlt_out) = aacgmv2.get_aacgm_coord_arr(
464
                 np.array([[60, 61, 62], [63, 64, 65]]), 0, 300, self.dtime)
465
466 View Code Duplication
    def test_get_aacgm_coord_arr_badidea(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
467
        """Test array AACGMV2 calculation for BADIDEA"""
468
        self.method = "|".join([self.method, "BADIDEA"])
469
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in[0], self.lon_in[0],
470
                                               [3000.0], self.dtime,
471
                                               self.method)
472
473
        assert len(self.out) == len(self.ref)
474
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
475
476
        self.ref = [64.34650424987989, 83.30339395305012, 0.3307388620896745]
477
        for i, oo in enumerate(self.out):
478
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
479
480
    def test_get_aacgm_coord_arr_location_failure(self):
481
        """Test array AACGMV2 calculation with a bad location"""
482
        self.out = aacgmv2.get_aacgm_coord_arr([0], [0], [0], self.dtime,
483
                                               self.method)
484
485
        
486
        assert len(self.out) == len(self.ref)
487
        assert [isinstance(oo, list) and len(oo) == 1 for oo in self.out]
488
        assert np.any([np.isnan(oo) for oo in self.out])
489
490
    def test_get_aacgm_coord_arr_time_failure(self):
491
        """Test array AACGMV2 calculation with a bad time"""
492
        with pytest.raises(ValueError):
493
            aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in, self.alt_in,
494
                                        None, self.method)
495
496
    def test_get_aacgm_coord_arr_mlat_failure(self):
497
        """Test error return for co-latitudes above 90 for an array"""
498
499
        self.lat_in = [91, 60, -91]
500
        with pytest.raises(ValueError):
501
            self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in[0],
502
                                                   self.alt_in[0], self.dtime,
503
                                                   self.method)
504
505 View Code Duplication
    def test_get_aacgm_coord_arr_datetime_date(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
506
        """Test array AACGMV2 calculation with date and datetime input"""
507
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in,
508
                                               self.alt_in, self.ddate,
509
                                               self.method)
510
        self.ref = aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in,
511
                                               self.alt_in, self.dtime,
512
                                               self.method)
513
514
        assert len(self.out) == len(self.ref)
515
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
516
                for oo in self.out]
517
518
        for i, oo in enumerate(self.out):
519
            np.testing.assert_allclose(oo, self.ref[i], rtol=self.rtol)
520
521
    def test_get_aacgm_coord_arr_maxalt_failure(self):
522
        """test aacgm_coord_arr failure for an altitude too high for coeff"""
523
        self.method = ""
524
        self.alt_in = [2001 for ll in self.lat_in]
525
        self.out = aacgmv2.get_aacgm_coord_arr(self.lat_in, self.lon_in,
526
                                               self.alt_in, self.dtime,
527
                                               self.method)
528
529
        assert len(self.out) == len(self.ref)
530
        assert [isinstance(oo, list) and len(oo) == len(self.lat_in)
531
                for oo in self.out]
532
        assert np.all(np.isnan(np.array(self.out)))
533
534
535
class TestConvertCode:
536
    @classmethod
537
    def test_convert_str_to_bit_g2a(self):
538
        """Test conversion from string code to bit G2A"""
539
        if aacgmv2.convert_str_to_bit("G2A") != aacgmv2._aacgmv2.G2A:
540
            raise AssertionError()
541
542
    @classmethod
543
    def test_convert_str_to_bit_a2g(self):
544
        """Test conversion from string code to bit A2G"""
545
        if aacgmv2.convert_str_to_bit("A2G") != aacgmv2._aacgmv2.A2G:
546
            raise AssertionError()
547
548
    @classmethod
549
    def test_convert_str_to_bit_trace(self):
550
        """Test conversion from string code to bit TRACE"""
551
        if aacgmv2.convert_str_to_bit("TRACE") != aacgmv2._aacgmv2.TRACE:
552
            raise AssertionError()
553
554
    @classmethod
555
    def test_convert_str_to_bit_allowtrace(self):
556
        """Test conversion from string code to bit ALLOWTRACE"""
557
        if(aacgmv2.convert_str_to_bit("ALLOWTRACE") !=
558
           aacgmv2._aacgmv2.ALLOWTRACE):
559
            raise AssertionError()
560
561
    @classmethod
562
    def test_convert_str_to_bit_badidea(self):
563
        """Test conversion from string code to bit BADIDEA"""
564
        if(aacgmv2.convert_str_to_bit("BADIDEA") !=
565
           aacgmv2._aacgmv2.BADIDEA):
566
            raise AssertionError()
567
568
    @classmethod
569
    def test_convert_str_to_bit_geocentric(self):
570
        """Test conversion from string code to bit GEOCENTRIC"""
571
        if(aacgmv2.convert_str_to_bit("GEOCENTRIC") !=
572
           aacgmv2._aacgmv2.GEOCENTRIC):
573
            raise AssertionError()
574
575
    @classmethod
576
    def test_convert_str_to_bit_lowercase(self):
577
        """Test conversion from string code to bit for a lowercase code"""
578
        if aacgmv2.convert_str_to_bit("g2a") != aacgmv2._aacgmv2.G2A:
579
            raise AssertionError()
580
581
    @classmethod
582
    def test_convert_str_to_bit_spaces(self):
583
        """Test conversion from string code to bit for a code with spaces"""
584
        if(aacgmv2.convert_str_to_bit("G2A | trace") !=
585
           aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.TRACE):
586
            raise AssertionError()
587
588
    @classmethod
589
    def test_convert_str_to_bit_invalid(self):
590
        """Test conversion from string code to bit for an invalid code"""
591
        if aacgmv2.convert_str_to_bit("ggoogg|") != aacgmv2._aacgmv2.G2A:
592
            raise AssertionError()
593
594
    @classmethod
595
    def test_convert_bool_to_bit_g2a(self):
596
        """Test conversion from string code to bit G2A"""
597
        if aacgmv2.convert_bool_to_bit() != aacgmv2._aacgmv2.G2A:
598
            raise AssertionError()
599
600
    @classmethod
601
    def test_convert_bool_to_bit_a2g(self):
602
        """Test conversion from string code to bit A2G"""
603
        if aacgmv2.convert_bool_to_bit(a2g=True) != aacgmv2._aacgmv2.A2G:
604
            raise AssertionError()
605
606
    @classmethod
607
    def test_convert_bool_to_bit_trace(self):
608
        """Test conversion from string code to bit TRACE"""
609
        if aacgmv2.convert_bool_to_bit(trace=True) != aacgmv2._aacgmv2.TRACE:
610
            raise AssertionError()
611
612
    @classmethod
613
    def test_convert_bool_to_bit_allowtrace(self):
614
        """Test conversion from string code to bit ALLOWTRACE"""
615
        if(aacgmv2.convert_bool_to_bit(allowtrace=True) !=
616
           aacgmv2._aacgmv2.ALLOWTRACE):
617
            raise AssertionError()
618
619
    @classmethod
620
    def test_convert_bool_to_bit_badidea(self):
621
        """Test conversion from string code to bit BADIDEA"""
622
        if(aacgmv2.convert_bool_to_bit(badidea=True) !=
623
           aacgmv2._aacgmv2.BADIDEA):
624
            raise AssertionError()
625
626
    @classmethod
627
    def test_convert_bool_to_bit_geocentric(self):
628
        """Test conversion from string code to bit GEOCENTRIC"""
629
        if(aacgmv2.convert_bool_to_bit(geocentric=True) !=
630
           aacgmv2._aacgmv2.GEOCENTRIC):
631
            raise AssertionError()
632
633
class TestMLTConvert:
634
    def setup(self):
635
        """Runs before every method to create a clean testing setup"""
636
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
637
        self.dtime2 = dt.datetime(2015, 1, 1, 10, 0, 0)
638
        self.ddate = dt.date(2015, 1, 1)
639
        self.mlon_out = None
640
        self.mlt_out = None
641
        self.mlt_diff = None
642
        self.mlon_list = [270.0, 80.0, -95.0]
643
        self.mlt_list = [12.0, 25.0, -1.0]
644
        self.mlon_comp = [-101.657689, 93.34231102, 63.34231102]
645
        self.mlt_comp = [12.77717927, 0.1105126, 12.44384593]
646
        self.diff_comp = np.ones(shape=(3,)) * -10.52411552
647
648
    def teardown(self):
649
        """Runs after every method to clean up previous testing"""
650
        del self.mlon_out, self.mlt_out, self.mlt_list, self.mlon_list
651
        del self.mlon_comp, self.mlt_comp, self.mlt_diff, self.diff_comp
652
653
    def test_date_input(self):
654
        """Test to see that the date input works"""
655
        self.mlt_out = aacgmv2.convert_mlt(self.mlon_list, self.ddate,
656
                                           m2a=False)
657
        np.testing.assert_allclose(self.mlt_out, self.mlt_comp, rtol=1.0e-4)
658
659
    def test_datetime_exception(self):
660
        """Test to see that a value error is raised with bad time input"""
661
        with pytest.raises(ValueError):
662
            self.mlt_out = aacgmv2.wrapper.convert_mlt(self.mlon_list, 1997)
663
664
    def test_inv_convert_mlt_single(self):
665
        """Test MLT inversion for a single value"""
666
        for i,mlt in enumerate(self.mlt_list):
667
            self.mlon_out = aacgmv2.convert_mlt(mlt, self.dtime, m2a=True)
668
            np.testing.assert_almost_equal(self.mlon_out, self.mlon_comp[i],
669
                                           decimal=4)
670
671
    def test_inv_convert_mlt_list(self):
672
        """Test MLT inversion for a list"""
673
        self.mlon_out = aacgmv2.convert_mlt(self.mlt_list, self.dtime, m2a=True)
674
        np.testing.assert_allclose(self.mlon_out, self.mlon_comp, rtol=1.0e-4)
675
676
    def test_inv_convert_mlt_arr(self):
677
        """Test MLT inversion for an array"""
678
        self.mlon_out = aacgmv2.convert_mlt(np.array(self.mlt_list), self.dtime,
679
                                            m2a=True)
680
681
        np.testing.assert_allclose(self.mlon_out, self.mlon_comp, rtol=1.0e-4)
682
683
    def test_inv_convert_mlt_wrapping(self):
684
        """Test MLT wrapping"""
685
        self.mlon_out = aacgmv2.convert_mlt(np.array([1, 25, -1, 23]),
686
                                            self.dtime, m2a=True)
687
688
        np.testing.assert_almost_equal(self.mlon_out[0], self.mlon_out[1],
689
                                       decimal=6)
690
        np.testing.assert_almost_equal(self.mlon_out[2], self.mlon_out[3],
691
                                       decimal=6)
692
693
    def test_mlt_convert_mlon_wrapping(self):
694
        """Test mlon wrapping"""
695
        self.mlt_out = aacgmv2.convert_mlt(np.array([270, -90, 1, 361]),
696
                                           self.dtime, m2a=False)
697
698
        np.testing.assert_almost_equal(self.mlt_out[0], self.mlt_out[1],
699
                                       decimal=6)
700
        np.testing.assert_almost_equal(self.mlt_out[2], self.mlt_out[3],
701
                                       decimal=6)
702
703
    def test_mlt_convert_single(self):
704
        """Test MLT calculation for a single value"""
705
        for i,mlon in enumerate(self.mlon_list):
706
            self.mlt_out = aacgmv2.convert_mlt(mlon, self.dtime, m2a=False)
707
            np.testing.assert_almost_equal(self.mlt_out, self.mlt_comp[i],
708
                                           decimal=4)
709
710
    def test_mlt_convert_list(self):
711
        """Test MLT calculation for a list"""
712
        self.mlt_out = aacgmv2.convert_mlt(self.mlon_list, self.dtime,
713
                                           m2a=False)
714
        np.testing.assert_allclose(self.mlt_out, self.mlt_comp, rtol=1.0e-4)
715
716
    def test_mlt_convert_arr(self):
717
        """Test MLT calculation for an array"""
718
        self.mlt_out = aacgmv2.convert_mlt(np.array(self.mlon_list),
719
                                           self.dtime, m2a=False)
720
        np.testing.assert_allclose(self.mlt_out, self.mlt_comp, rtol=1.0e-4)
721
722
    def test_mlt_convert_list_w_times(self):
723
        """Test MLT calculation for data and time arrays"""
724
        self.dtime = [self.dtime for dd in self.mlon_list]
725
        self.mlt_out = aacgmv2.convert_mlt(self.mlon_list, self.dtime,
726
                                           m2a=False)
727
        np.testing.assert_allclose(self.mlt_out, self.mlt_comp, rtol=1.0e-4)
728
729
    def test_mlt_convert_change(self):
730
        """Test that MLT changes with UT"""
731
        self.mlt_out = aacgmv2.convert_mlt(self.mlon_list, self.dtime)
732
        self.mlt_diff = np.array(self.mlt_out) \
733
            - np.array(aacgmv2.convert_mlt(self.mlon_list, self.dtime2))
734
735
        np.testing.assert_allclose(self.mlt_diff, self.diff_comp, rtol=1.0e-4)
736
737
    def test_mlt_convert_multidim_failure(self):
738
        """Test MLT calculation failure for multi-dimensional arrays"""
739
        self.mlon_list = np.full(shape=(3,2), fill_value=50.0)
740
        with pytest.raises(ValueError):
741
            aacgmv2.convert_mlt(self.mlon_list, self.dtime, m2a=False)
742
743
    def test_mlt_convert_mismatch_failure(self):
744
        """Test MLT calculation failure for mismatched array input"""
745
        with pytest.raises(ValueError):
746
            aacgmv2.convert_mlt(self.mlon_list, [self.dtime, self.dtime2],
747
                                m2a=False)
748
749
class TestCoeffPath:
750
751
    def setup(self):
752
        """Runs before every method to create a clean testing setup"""
753
        os.environ['IGRF_COEFFS'] = "default_igrf"
754
        os.environ['AACGM_v2_DAT_PREFIX'] = "default_coeff"
755
        self.default_igrf = os.environ['IGRF_COEFFS']
756
        self.default_coeff = os.environ['AACGM_v2_DAT_PREFIX']
757
758
    def teardown(self):
759
        """Runs after every method to clean up previous testing"""
760
        del self.default_igrf, self.default_coeff
761
762
    def test_set_coeff_path_default(self):
763
        """Test the coefficient path setting using default values"""
764
        aacgmv2.wrapper.set_coeff_path()
765
766
        if os.environ['IGRF_COEFFS'] != self.default_igrf:
767
            raise AssertionError()
768
        if os.environ['AACGM_v2_DAT_PREFIX'] != self.default_coeff:
769
            raise AssertionError()
770
771
    @classmethod
772
    def test_set_coeff_path_string(self):
773
        """Test the coefficient path setting using two user specified values"""
774
        aacgmv2.wrapper.set_coeff_path("hi", "bye")
775
776
        if os.environ['IGRF_COEFFS'] != "hi":
777
            raise AssertionError()
778
        if os.environ['AACGM_v2_DAT_PREFIX'] != "bye":
779
            raise AssertionError()
780
781
    @classmethod
782
    def test_set_coeff_path_true(self):
783
        """Test the coefficient path setting using the module values"""
784
        aacgmv2.wrapper.set_coeff_path(True, True)
785
786
        if os.environ['IGRF_COEFFS'] != aacgmv2.IGRF_COEFFS:
787
            raise AssertionError()
788
        if os.environ['AACGM_v2_DAT_PREFIX'] != aacgmv2.AACGM_v2_DAT_PREFIX:
789
            raise AssertionError()
790
791
    def test_set_only_aacgm_coeff_path(self):
792
        """Test the coefficient path setting using a mix of input"""
793
        aacgmv2.wrapper.set_coeff_path(coeff_prefix="hi")
794
795
        if os.environ['IGRF_COEFFS'] != self.default_igrf:
796
            raise AssertionError()
797
        if os.environ['AACGM_v2_DAT_PREFIX'] != "hi":
798
            raise AssertionError()
799
800
    def test_set_only_igrf_coeff_path(self):
801
        """Test the coefficient path setting using a mix of input"""
802
        aacgmv2.wrapper.set_coeff_path(igrf_file="hi")
803
804
        if os.environ['IGRF_COEFFS'] != "hi":
805
            raise AssertionError()
806
        if os.environ['AACGM_v2_DAT_PREFIX'] != self.default_coeff:
807
            raise AssertionError()
808
809
    @classmethod
810
    def test_set_both_mixed(self):
811
        """Test the coefficient path setting using a mix of input"""
812
        aacgmv2.wrapper.set_coeff_path(igrf_file=True, coeff_prefix="hi")
813
814
        if os.environ['IGRF_COEFFS'] != aacgmv2.IGRF_COEFFS:
815
            raise AssertionError()
816
        if os.environ['AACGM_v2_DAT_PREFIX'] != "hi":
817
            raise AssertionError()
818
819
class TestHeightReturns:
820
    def setup(self):
821
        """Runs before every method to create a clean testing setup"""
822
        self.code = aacgmv2._aacgmv2.A2G
823
        self.bad_code = aacgmv2._aacgmv2.BADIDEA
824
        self.trace_code = aacgmv2._aacgmv2.TRACE
825
        
826
    def teardown(self):
827
        """Runs after every method to clean up previous testing"""
828
        del self.code, self.bad_code
829
830
    def test_low_height_good(self):
831
        """ Test to see that a very low height is still accepted"""
832
833
        assert aacgmv2.wrapper.test_height(-1, self.code)
834
835
    def test_high_coeff_bad(self):
836
        """ Test to see that a high altitude for coefficent use fails"""
837
838
        assert not aacgmv2.wrapper.test_height(aacgmv2.high_alt_coeff+10.0,
839
                                               self.code)
840
841
    def test_high_coeff_good(self):
842
        """ Test a high altitude for coefficent use with badidea """
843
844
        assert aacgmv2.wrapper.test_height(aacgmv2.high_alt_coeff+10.0,
845
                                           self.bad_code)
846
847
    def test_low_coeff_good(self):
848
        """ Test that a normal height succeeds"""
849
        assert aacgmv2.wrapper.test_height(aacgmv2.high_alt_coeff*0.5,
850
                                           self.code)
851
852
    def test_high_trace_bad(self):
853
        """ Test that a high trace height fails"""
854
        assert not aacgmv2.wrapper.test_height(aacgmv2.high_alt_trace+10.0,
855
                                               self.code)
856
857
    def test_low_trace_good(self):
858
        """ Test that a high coefficient height succeeds with trace"""
859
        assert aacgmv2.wrapper.test_height(aacgmv2.high_alt_coeff+10.0,
860
                                           self.trace_code)
861
862
    def test_high_trace_good(self):
863
        """ Test that a high trace height succeeds with badidea"""
864
        assert aacgmv2.wrapper.test_height(aacgmv2.high_alt_trace+10.0,
865
                                           self.bad_code)
866
867
868
class TestPyLogging:
869
    def setup(self):
870
        """Runs before every method to create a clean testing setup"""
871
872
        self.lwarn = u""
873
        self.lout = u""
874
        self.log_capture = StringIO()
875
        aacgmv2.logger.addHandler(logging.StreamHandler(self.log_capture))
876
        aacgmv2.logger.setLevel(logging.INFO)
877
878
    def teardown(self):
879
        """Runs after every method to clean up previous testing"""
880
        self.log_capture.close()
881
        del self.lwarn, self.lout, self.log_capture
882
883
884
    def test_warning_below_ground(self):
885
        """ Test that a warning is issued if height < 0 for height test """
886
        self.lwarn = u"conversion not intended for altitudes < 0 km"
887
888
        aacgmv2.wrapper.test_height(-1, 0)
889
        self.lout = self.log_capture.getvalue()
890
        if self.lout.find(self.lwarn) < 0:
891
            raise AssertionError()
892
893
    def test_warning_magnetosphere(self):
894
        """ Test that a warning is issued if altitude is very high"""
895
        self.lwarn = u"coordinates are not intended for the magnetosphere"
896
897
        aacgmv2.wrapper.test_height(70000, aacgmv2._aacgmv2.TRACE)
898
        self.lout = self.log_capture.getvalue()
899
        if self.lout.find(self.lwarn) < 0:
900
            raise AssertionError()
901
902
    def test_warning_high_coeff(self):
903
        """ Test that a warning is issued if altitude is very high"""
904
        self.lwarn = u"must either use field-line tracing (trace=True"
905
906
        aacgmv2.wrapper.test_height(3000, 0)
907
        self.lout = self.log_capture.getvalue()
908
        if self.lout.find(self.lwarn) < 0:
909
            raise AssertionError()
910
911
    def test_warning_single_loc_in_arr(self):
912
        """ Test that user is warned they should be using simpler routine"""
913
        self.lwarn = u"for a single location, consider using"
914
915
        aacgmv2.convert_latlon_arr(60, 0, 300, dt.datetime(2015,1,1,0,0,0))
916
        self.lout = self.log_capture.getvalue()
917
        if self.lout.find(self.lwarn) < 0:
918
            raise AssertionError()
919
920
class TestTimeReturns:
921
    def setup(self):
922
        """Runs before every method to create a clean testing setup"""
923
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
924
        self.dtime2 = dt.datetime(2015, 1, 1, 10, 10, 10)
925
        self.ddate = dt.date(2015, 1, 1)
926
        
927
    def teardown(self):
928
        """Runs after every method to clean up previous testing"""
929
        del self.dtime, self.ddate, self.dtime2
930
931
    def test_good_time(self):
932
        """ Test to see that a good datetime is accepted"""
933
934
        assert self.dtime == aacgmv2.wrapper.test_time(self.dtime)
935
936
    def test_good_time_with_nonzero_time(self):
937
        """ Test to see that a good datetime with h/m/s is accepted"""
938
939
        assert self.dtime2 == aacgmv2.wrapper.test_time(self.dtime2)
940
941
    def test_good_date(self):
942
        """ Test to see that a good date has a good datetime output"""
943
944
        assert self.dtime == aacgmv2.wrapper.test_time(self.dtime)
945
946
    def test_bad_time(self):
947
        """ Test to see that a warning is raised with a bad time input"""
948
        with pytest.raises(ValueError):
949
            aacgmv2.wrapper.test_time(2015)
950