Completed
Push — master ( e4d4aa...7735e4 )
by Angeline
13s queued 11s
created

test_dep_aacgmv2   F

Complexity

Total Complexity 66

Size/Duplication

Total Lines 210
Duplicated Lines 13.81 %

Importance

Changes 0
Metric Value
wmc 66
eloc 153
dl 29
loc 210
rs 3.1913
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A TestDepAACGMV2.teardown() 0 3 1
A TestDepAACGMV2.setup() 0 6 1
A TestDepAACGMV2.test_convert_arr_single() 0 9 4
B TestDepAACGMV2.test_convert_location_failure() 0 7 5
A TestDepAACGMV2.test_convert_mult_array_mix() 14 14 4
A TestDepAACGMV2.test_gc2gd_lat_list() 0 6 1
A TestDepAACGMV2.test_convert_arr_mix() 0 9 4
A TestDepAACGMV2.test_warning_below_ground_convert() 0 10 3
A TestDepAACGMV2.test_convert_list_mix() 0 8 4
A TestDepAACGMV2.test_gc2gd_lat_arr() 0 6 1
A TestDepAACGMV2.test_convert_badidea_failure() 0 5 2
A TestDepAACGMV2.test_convert_lat_failure() 0 4 2
A TestDepAACGMV2.test_convert_unequal_arra() 15 15 4
B TestDepAACGMV2.test_module_structure() 0 8 7
A TestDepAACGMV2.test_convert_time_failure() 0 4 2
A TestDepAACGMV2.test_subsol() 0 9 1
B TestDepAACGMV2.test_convert_list() 0 16 7
A TestDepAACGMV2.test_gc2gd_lat() 0 5 1
A TestDepAACGMV2.test_convert_maxalt_failure() 0 5 2
A TestDepAACGMV2.test_convert_arr() 0 10 4
A TestDepAACGMV2.test_convert_single_val() 0 8 4
A TestDepAACGMV2.test_convert_datetime_date() 0 5 1
A TestDepAACGMV2.test_igrf_dipole_axis() 0 6 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_dep_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
import numpy as np
6
import pytest
7
import aacgmv2
8
9
class TestDepAACGMV2:
10
    def setup(self):
11
        """Runs before every method to create a clean testing setup"""
12
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
13
        self.ddate = dt.date(2015, 1, 1)
14
        self.lat = None
15
        self.lon = None
16
17
    def teardown(self):
18
        """Runs after every method to clean up previous testing"""
19
        del self.dtime, self.ddate, self.lat, self.lon
20
21
    def test_module_structure(self):
22
        """Test module structure for deprecated routines"""
23
        assert aacgmv2
24
        assert aacgmv2.convert
25
        assert aacgmv2.deprecated.subsol
26
        assert aacgmv2.deprecated
27
        assert aacgmv2.deprecated.gc2gd_lat
28
        assert aacgmv2.deprecated.igrf_dipole_axis
29
30
    def test_convert_single_val(self):
31
        """Test conversion for a single value"""
32
        self.lat, self.lon = aacgmv2.convert(60, 0, 300, self.dtime)
33
        assert isinstance(self.lat, np.ndarray)
34
        assert isinstance(self.lon, np.ndarray)
35
        assert self.lat.shape == self.lon.shape and self.lat.shape == (1,)
36
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
37
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
38
39
    def test_convert_list(self):
40
        """Test conversion for list input"""
41
        self.lat, self.lon = aacgmv2.convert([60], [0], [300], self.dtime)
42
        assert isinstance(self.lat, np.ndarray)
43
        assert isinstance(self.lon, np.ndarray)
44
        assert self.lat.shape == self.lon.shape and self.lat.shape == (1,)
45
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
46
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
47
48
        self.lat, self.lon = aacgmv2.convert([60, 61], [0, 0], [300, 300],
49
                                             self.dtime)
50
        assert isinstance(self.lat, np.ndarray)
51
        assert isinstance(self.lon, np.ndarray)
52
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2,)
53
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
54
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
55
56
    def test_convert_arr_single(self):
57
        """Test conversion for array input with one element"""
58
        self.lat, self.lon = aacgmv2.convert(np.array([60]), np.array([0]),
59
                                   np.array([300]), self.dtime)
60
        assert isinstance(self.lat, np.ndarray)
61
        assert isinstance(self.lon, np.ndarray)
62
        assert self.lat.shape == self.lon.shape and self.lat.shape == (1,)
63
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
64
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
65
66
    def test_convert_arr(self):
67
        """Test conversion for array input"""
68
        self.lat, self.lon = aacgmv2.convert(np.array([60, 61]),
69
                                             np.array([0, 0]),
70
                                             np.array([300, 300]), self.dtime)
71
        assert isinstance(self.lat, np.ndarray)
72
        assert isinstance(self.lon, np.ndarray)
73
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2,)
74
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
75
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
76
77
    def test_convert_list_mix(self):
78
        """Test conversion for a list and floats"""
79
        self.lat, self.lon = aacgmv2.convert([60, 61], 0, 300, self.dtime)
80
        assert isinstance(self.lat, np.ndarray)
81
        assert isinstance(self.lon, np.ndarray)
82
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2,)
83
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
84
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
85
86
    def test_convert_arr_mix(self):
87
        """Test conversion for an array and floats"""
88
        self.lat, self.lon = aacgmv2.convert(np.array([60, 61]), 0, 300,
89
                                             self.dtime)
90
        assert isinstance(self.lat, np.ndarray)
91
        assert isinstance(self.lon, np.ndarray)
92
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2,)
93
        np.testing.assert_allclose(self.lat, [58.2258, 59.3186], rtol=1e-4)
94
        np.testing.assert_allclose(self.lon, [81.1685, 81.6140], rtol=1e-4)
95
96 View Code Duplication
    def test_convert_mult_array_mix(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
97
        """Test conversion for a multi-dim array and floats"""
98
        self.lat, self.lon = aacgmv2.convert(np.array([[60, 61, 62],
99
                                                       [63, 64, 65]]), 0,
100
                                             300, self.dtime)
101
        assert isinstance(self.lat, np.ndarray)
102
        assert isinstance(self.lon, np.ndarray)
103
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2, 3)
104
        np.testing.assert_allclose(self.lat, [[58.2258, 59.3186, 60.4040],
105
                                         [61.4820, 62.5528, 63.6164]],
106
                                   rtol=1e-4)
107
        np.testing.assert_allclose(self.lon, [[81.1685, 81.6140, 82.0872],
108
                                         [82.5909, 83.1286, 83.7039]],
109
                                   rtol=1e-4)
110
111 View Code Duplication
    def test_convert_unequal_arra(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
112
        """Test conversion for unequal sized arrays"""
113
        self.lat, self.lon = aacgmv2.convert(np.array([[60, 61, 62],
114
                                                       [63, 64, 65]]),
115
                                             np.array([0]), np.array([300]),
116
                                             self.dtime)
117
        assert isinstance(self.lat, np.ndarray)
118
        assert isinstance(self.lon, np.ndarray)
119
        assert self.lat.shape == self.lon.shape and self.lat.shape == (2, 3)
120
        np.testing.assert_allclose(self.lat, [[58.2258, 59.3186, 60.4040],
121
                                              [61.4820, 62.5528, 63.6164]],
122
                                   rtol=1e-4)
123
        np.testing.assert_allclose(self.lon, [[81.1685, 81.6140, 82.0872],
124
                                              [82.5909, 83.1286, 83.7039]],
125
                                   rtol=1e-4)
126
127
    def test_convert_badidea_failure(self):
128
        """Test conversion failure for BADIDEA"""
129
        with pytest.raises(ValueError):
130
            self.lat, self.lon = aacgmv2.convert([60], [0], [3000], self.dtime,
131
                                                 badidea=True)
132
133
    def test_convert_location_failure(self):
134
        """Test conversion with a bad location"""
135
        self.lat, self.lon = aacgmv2.convert([0], [0], [0], self.dtime)
136
        assert isinstance(self.lat, np.ndarray)
137
        assert isinstance(self.lon, np.ndarray)
138
        assert self.lat.shape == self.lon.shape and self.lat.shape == (1,)
139
        assert np.all([np.isnan(self.lat), np.isnan(self.lon)])
140
141
    def test_convert_time_failure(self):
142
        """Test conversion with a bad time"""
143
        with pytest.raises(AssertionError):
144
            self.lat, self.lon = aacgmv2.convert([60], [0], [300], None)
145
146
    def test_convert_datetime_date(self):
147
        """Test conversion with date and datetime input"""
148
        self.lat, self.lon = aacgmv2.convert([60], [0], [300], self.ddate)
149
        np.testing.assert_allclose(self.lat, [58.2258], rtol=1e-4)
150
        np.testing.assert_allclose(self.lon, [81.1685], rtol=1e-4)
151
152
    def test_warning_below_ground_convert(self):
153
        """ Test that a warning is issued if altitude is below zero"""
154
        import logbook
155
        lwarn = u"conversion not intended for altitudes < 0 km"
156
157
        with logbook.TestHandler() as handler:
158
            self.lat, self.lon = aacgmv2.convert([60], [0], [-1], self.dtime)
159
            assert handler.has_warning(lwarn)
160
161
        handler.close()
162
163
    def test_convert_maxalt_failure(self):
164
        """For an array, test failure for an altitude too high for
165
        coefficients"""
166
        self.lat, self.lon = aacgmv2.convert([60], [0], [2001], self.dtime)
167
        assert np.all([np.isnan(self.lat), np.isnan(self.lon)])
168
169
    def test_convert_lat_failure(self):
170
        """Test error return for co-latitudes above 90 for an array"""
171
        with pytest.raises(AssertionError):
172
            aacgmv2.convert([91, 60, -91], 0, 300, self.dtime)
173
174
    def test_subsol(self):
175
        """Test the subsolar calculation"""
176
        doy = int(self.dtime.strftime("%j"))
177
        ut = self.dtime.hour * 3600.0 + self.dtime.minute * 60.0 + \
178
             self.dtime.second
179
        self.lon, self.lat = aacgmv2.deprecated.subsol(self.dtime.year, doy, ut)
180
181
        np.testing.assert_almost_equal(self.lon, -179.2004, decimal=4)
182
        np.testing.assert_almost_equal(self.lat, -23.0431, decimal=4)
183
184
    def test_gc2gd_lat(self):
185
        """Test the geocentric to geodetic conversion"""
186
        self.lat = aacgmv2.deprecated.gc2gd_lat(45.0)
187
188
        np.testing.assert_almost_equal(self.lat, 45.1924, decimal=4)
189
190
    def test_gc2gd_lat_list(self):
191
        """Test the geocentric to geodetic conversion"""
192
        self.lat = [45.0, -45.0]
193
        self.lat = aacgmv2.deprecated.gc2gd_lat(self.lat)
194
195
        np.testing.assert_allclose(self.lat, [45.1924, -45.1924], rtol=1.0e-4)
196
197
    def test_gc2gd_lat_arr(self):
198
        """Test the geocentric to geodetic conversion"""
199
        self.lat = np.array([45.0, -45.0])
200
        self.lat = aacgmv2.deprecated.gc2gd_lat(self.lat)
201
202
        np.testing.assert_allclose(self.lat, [45.1924, -45.1924], rtol=1.0e-4)
203
204
    def test_igrf_dipole_axis(self):
205
        """Test the IGRF dipole axis calculation"""
206
        m = aacgmv2.deprecated.igrf_dipole_axis(self.dtime)
207
208
        np.testing.assert_allclose(m, [0.050253, -0.160608, 0.985738],
209
                                   rtol=1.0e-4)
210