Completed
Push — master ( 7b8fc2...c09cea )
by Jeffrey
03:35
created

AprsUtilTestCase.test_latitude_south()   B

Complexity

Conditions 1

Size

Total Lines 30

Duplication

Lines 4
Ratio 13.33 %

Importance

Changes 0
Metric Value
cc 1
dl 4
loc 30
rs 8.8571
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
"""Tests for Python APRS util methods."""
5
6
# These imports are for python3 compatability inside python2
7
from __future__ import absolute_import
8
from __future__ import division
9
from __future__ import print_function
10
11
import logging
12
import logging.handlers
13
import unittest
14
15
import apex.aprs.util
16
from apex.aprs import constants as aprsConstants
17
18
__author__ = 'Jeffrey Phillips Freeman (WI2ARD)'
19
__maintainer__ = "Jeffrey Phillips Freeman (WI2ARD)"
20
__email__ = "[email protected]"
21
__license__ = 'Apache License, Version 2.0'
22
__copyright__ = 'Copyright 2016, Syncleus, Inc. and contributors'
23
__credits__ = []
24
25
ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
26
NUMBERS = '0123456789'
27
POSITIVE_NUMBERS = NUMBERS[1:]
28
ALPHANUM = ''.join([ALPHABET, NUMBERS])
29
30
VALID_CALLSIGNS = ['W2GMD', 'W2GMD-1', 'KF4MKT', 'KF4MKT-1', 'KF4LZA-15']
31
INVALID_CALLSIGNS = ['xW2GMDx', 'W2GMD-16', 'W2GMD-A', 'W', 'W2GMD-1-0',
32
                     'W*GMD', 'W2GMD-123']
33
34
35
class AprsUtilTestCase(unittest.TestCase):  # pylint: disable=R0904
36
    """Tests for Python APRS Utils."""
37
38
    logger = logging.getLogger(__name__)
39
    logger.setLevel(aprsConstants.LOG_LEVEL)
40
    console_handler = logging.StreamHandler()
41
    console_handler.setLevel(aprsConstants.LOG_LEVEL)
42 View Code Duplication
    formatter = logging.Formatter(aprsConstants.LOG_FORMAT)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
43
    console_handler.setFormatter(formatter)
44
    logger.addHandler(console_handler)
45
    logger.propagate = False
46
47
    def test_latitude_north(self):
48
        """Test Decimal to APRS Latitude conversion.
49
50
        Spec per ftp://ftp.tapr.org/aprssig/aprsspec/spec/aprs101/APRS101.pdf
51
        --
52
        Latitude is expressed as a fixed 8-character field, in degrees and
53
        decimal minutes (to two decimal places), followed by the letter N for
54
        north or S for south. Latitude degrees are in the range 00 to 90.
55
        Latitude minutes are expressed as whole minutes and hundredths of a
56
        minute, separated by a decimal point.
57
58
        For example:
59
60
            4903.50N is 49 degrees 3 minutes 30 seconds north.
61
62
        In generic format examples, the latitude is shown as the 8-character
63
        string ddmm.hhN (i.e. degrees, minutes and hundredths of a minute
64
        north).
65
        """
66
        test_lat = 37.7418096
67
        aprs_lat = apex.aprs.util.dec2dm_lat(test_lat)
68
        self.logger.debug('aprs_lat=%s', aprs_lat)
69
70
        lat_deg = int(aprs_lat.split('.')[0][:1])
71
        # lat_hsec = aprs_lat.split('.')[1]
72
73
        self.assertTrue(len(aprs_lat) == 8)
74
        self.assertTrue(lat_deg >= 00)
75
        self.assertTrue(lat_deg <= 90)
76
        self.assertTrue(aprs_lat.endswith('N'))
77
78
    def test_latitude_south(self):
79
        """Test Decimal to APRS Latitude conversion.
80
81
        Spec per ftp://ftp.tapr.org/aprssig/aprsspec/spec/aprs101/APRS101.pdf
82
        --
83
        Latitude is expressed as a fixed 8-character field, in degrees and
84
        decimal minutes (to two decimal places), followed by the letter N for
85
        north or S for south. Latitude degrees are in the range 00 to 90.
86
        Latitude minutes are expressed as whole minutes and hundredths of a
87
        minute, separated by a decimal point.
88
89
        For example:
90
91
            4903.50N is 49 degrees 3 minutes 30 seconds north.
92
93
        In generic format examples, the latitude is shown as the 8-character
94
        string ddmm.hhN (i.e. degrees, minutes and hundredths of a minute
95
        north).
96
        """
97
        test_lat = -37.7418096
98
        aprs_lat = apex.aprs.util.dec2dm_lat(test_lat)
99
        self.logger.debug('aprs_lat=%s', aprs_lat)
100
101
        lat_deg = int(aprs_lat.split('.')[0][:1])
102
        # lat_hsec = aprs_lat.split('.')[1]
103
104 View Code Duplication
        self.assertTrue(len(aprs_lat) == 8)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
105
        self.assertTrue(lat_deg >= 00)
106
        self.assertTrue(lat_deg <= 90)
107
        self.assertTrue(aprs_lat.endswith('S'))
108
109
    def test_longitude_west(self):
110
        """Test Decimal to APRS Longitude conversion.
111
112
        Spec per ftp://ftp.tapr.org/aprssig/aprsspec/spec/aprs101/APRS101.pdf
113
        --
114
        Longitude is expressed as a fixed 9-character field, in degrees and
115
        decimal minutes (to two decimal places), followed by the letter E for
116
        east or W for west.
117
118
        Longitude degrees are in the range 000 to 180. Longitude minutes are
119
        expressed as whole minutes and hundredths of a minute, separated by a
120
        decimal point.
121
122
        For example:
123
124
            07201.75W is 72 degrees 1 minute 45 seconds west.
125
126
        In generic format examples, the longitude is shown as the 9-character
127
        string dddmm.hhW (i.e. degrees, minutes and hundredths of a minute
128
        west).
129
        """
130
        test_lng = -122.38833
131
        aprs_lng = apex.aprs.util.dec2dm_lng(test_lng)
132
        self.logger.debug('aprs_lng=%s', aprs_lng)
133
134
        lng_deg = int(aprs_lng.split('.')[0][:2])
135
        # lng_hsec = aprs_lng.split('.')[1]
136
137
        self.assertTrue(len(aprs_lng) == 9)
138
        self.assertTrue(lng_deg >= 000)
139
        self.assertTrue(lng_deg <= 180)
140
        self.assertTrue(aprs_lng.endswith('W'))
141
142
    def test_longitude_east(self):
143
        """Test Decimal to APRS Longitude conversion.
144
145
        Spec per ftp://ftp.tapr.org/aprssig/aprsspec/spec/aprs101/APRS101.pdf
146
        --
147
        Longitude is expressed as a fixed 9-character field, in degrees and
148
        decimal minutes (to two decimal places), followed by the letter E for
149
        east or W for west.
150
151
        Longitude degrees are in the range 000 to 180. Longitude minutes are
152
        expressed as whole minutes and hundredths of a minute, separated by a
153
        decimal point.
154
155
        For example:
156
157
            07201.75W is 72 degrees 1 minute 45 seconds west.
158
159
        In generic format examples, the longitude is shown as the 9-character
160
        string dddmm.hhW (i.e. degrees, minutes and hundredths of a minute
161
        west).
162
        """
163
        test_lng = 122.38833
164
        aprs_lng = apex.aprs.util.dec2dm_lng(test_lng)
165
        self.logger.debug('aprs_lng=%s', aprs_lng)
166
167
        lng_deg = int(aprs_lng.split('.')[0][:2])
168
        # lng_hsec = aprs_lng.split('.')[1]
169
170
        self.assertTrue(len(aprs_lng) == 9)
171
        self.assertTrue(lng_deg >= 000)
172
        self.assertTrue(lng_deg <= 180)
173
        self.assertTrue(aprs_lng.endswith('E'))
174
175
    def test_valid_callsign_valid(self):
176
        """
177
        Tests valid callsigns using `aprs.util.valid_callsign()`.
178
        """
179
        for i in VALID_CALLSIGNS:
180
            self.assertTrue(
181
                apex.aprs.util.valid_callsign(i), "%s is a valid call" % i)
182
183
    def test_valid_callsign_invalid(self):
184
        """
185
        Tests invalid callsigns using `aprs.util.valid_callsign()`.
186
        """
187
        for i in INVALID_CALLSIGNS:
188
            self.assertFalse(
189
                apex.aprs.util.valid_callsign(i), "%s is an invalid call" % i)
190
191
    def test_decode_aprs_ascii_frame(self):
192
        """
193
        Tests creating an APRS frame-as-dict from an APRS frame-as-string
194
        using `aprs.util.decode_aprs_ascii_frame()`.
195
        """
196
        ascii_frame = (
197
            'W2GMD-9>APOTC1,WIDE1-1,WIDE2-1:!3745.94N/12228.05W>118/010/'
198
            'A=000269 38C=Temp http://w2gmd.org/ Twitter: @ampledata')
199
        frame = apex.aprs.util.decode_aprs_ascii_frame(ascii_frame)
200
        self.assertEqual(
201
            {
202
                'source': 'W2GMD-9',
203
                'destination': 'APOTC1',
204
                'path': 'APOTC1,WIDE1-1,WIDE2-1',
205
                'text': ('!3745.94N/12228.05W>118/010/A=000269 38C=Temp '
206
                         'http://w2gmd.org/ Twitter: @ampledata'),
207
            },
208
            frame
209
        )
210
211
    # All other tests only work on python2
212
    # if sys.version_info < (3, 0):
213
    #     def setUp(self):  # pylint: disable=C0103
214
    #         """Setup."""
215
    #         self.test_frames = open(constants.TEST_FRAMES, 'r')
216
    #         self.test_frame = self.test_frames.readlines()[0].strip()
217
    #
218
    #     def tearDown(self):  # pylint: disable=C0103
219
    #         """Teardown."""
220
    #         self.test_frames.close()
221
    #
222
    #     def test_format_aprs_frame(self):
223
    #         """
224
    #         Tests formatting an APRS frame-as-string from an APRS frame-as-dict
225
    #         using `aprs.util.format_aprs_frame()`.
226
    #         """
227
    #         frame = {
228
    #             'source': 'W2GMD-1',
229
    #             'destination': 'OMG',
230
    #             'path': 'WIDE1-1',
231
    #             'text': 'test_format_aprs_frame'
232
    #         }
233
    #         formatted_frame = apex.aprs.util.format_aprs_frame(frame)
234
    #         self.assertEqual(
235
    #             formatted_frame,
236
    #             'W2GMD-1>OMG,WIDE1-1:test_format_aprs_frame'
237
    #         )
238
239
        # def test_extract_callsign_source(self):
240
        #     """
241
        #     Tests extracting the source callsign from a KISS-encoded APRS frame
242
        #     using `aprs.util.extract_callsign()`.
243
        #     """
244
        #     callsign = {'callsign': 'W2GMD', 'ssid': 6}
245
        #     extracted_callsign = apex.aprs.util.extract_callsign(self.test_frame[7:])
246
        #     self.assertEqual(callsign, extracted_callsign)
247
        #
248
        # def test_extract_callsign_dest(self):
249
        #     """
250
        #     Tests extracting the destination callsign from a KISS-encoded APRS
251
        #     frame using `aprs.util.extract_callsign()`.
252
        #     """
253
        #     extracted_callsign = apex.aprs.util.extract_callsign(self.test_frame)
254
        #     self.assertEqual(extracted_callsign['callsign'], 'APRX24')
255
        #
256
        # def test_full_callsign_with_ssid(self):
257
        #     """
258
        #     Tests creating a full callsign string from a callsign+ssid dict using
259
        #     `aprs.util.full_callsign()`.
260
        #     """
261
        #     callsign = {
262
        #         'callsign': 'W2GMD',
263
        #         'ssid': 1
264
        #     }
265
        #     full_callsign = apex.aprs.util.full_callsign(callsign)
266
        #     self.assertEqual(full_callsign, 'W2GMD-1')
267
        #
268
        # def test_full_callsign_sans_ssid(self):
269
        #     """
270
        #     Tests creating a full callsign string from a callsign dict using
271
        #     `aprs.util.full_callsign()`.
272
        #     """
273
        #     callsign = {
274
        #         'callsign': 'W2GMD',
275
        #         'ssid': 0
276
        #     }
277
        #     full_callsign = apex.aprs.util.full_callsign(callsign)
278
        #     self.assertEqual(full_callsign, 'W2GMD')
279
        #
280
        # def test_extract_path(self):
281
        #     """
282
        #     Tests extracting the APRS path from a KISS-encoded frame
283
        #     using `aprs.util.extract_path()`.
284
        #     """
285
        #     extracted_path = apex.aprs.util.extract_path(3, self.test_frame)
286
        #     self.assertEqual('WIDE1-1', extracted_path[0])
287
        #
288
        # def test_format_path(self):
289
        #     """
290
        #     Tests formatting an APRS path from a KISS-encoded frame
291
        #     using `aprs.util.format_path()`.
292
        #     """
293
        #     extracted_path = apex.aprs.util.format_path(3, self.test_frame)
294
        #     self.assertEqual('WIDE1-1', extracted_path)
295
        #
296
        # def test_encode_frame(self):
297
        #     """
298
        #     Tests KISS-encoding an APRS frame using
299
        #     `aprs.util.encode_frame()`.
300
        #     """
301
        #     frame = {
302
        #         'source': 'W2GMD-1',
303
        #         'destination': 'OMG',
304
        #         'path': 'WIDE1-1',
305
        #         'text': 'test_encode_frame'
306
        #     }
307
        #     encoded_frame = apex.aprs.util.encode_frame(frame)
308
        #     legit = ('\x9e\x9a\x8e@@@`\xaed\x8e\x9a\x88@b'
309
        #              '\xae\x92\x88\x8ab@c\x03\xf0test_encode_frame')
310
        #     self.assertEqual(legit, encoded_frame)
311
        #
312
        # def test_decode_frame_recorded(self):
313
        #     """
314
        #     Tests decoding a KISS-encoded APRS frame using
315
        #     `aprs.util.decode_frame()`.
316
        #     """
317
        #     frame = {
318
        #         'path': 'WIDE1-1',
319
        #         'destination': 'APRX24',
320
        #         'source': 'W2GMD-6',
321
        #         'text': ('!3745.75NI12228.05W#W2GMD-6 Inner Sunset, '
322
        #                  'SF iGate/Digipeater http://w2gmd.org')
323
        #     }
324
        #     self.assertEqual(frame, apex.aprs.util.decode_frame(self.test_frame))
325
        #
326
        # def test_decode_frame(self):
327
        #     """
328
        #     Tests decoding a KISS-encoded APRS frame using
329
        #     `aprs.util.decode_frame()`.
330
        #     """
331
        #     frame = {
332
        #         'source': 'W2GMD-1',
333
        #         'destination': 'OMG',
334
        #         'path': 'WIDE1-1,WIDE2-2',
335
        #         'text': 'test_encode_frame'
336
        #     }
337
        #     encoded_frame = apex.aprs.util.encode_frame(frame)
338
        #     decoded_frame = apex.aprs.util.decode_frame(encoded_frame)
339
        #     self.assertEqual(frame, decoded_frame)
340
        #
341
        # def test_create_callsign(self):
342
        #     """
343
        #     Tests creating a callsign string from a callsign dict using
344
        #     `aprs.util.create_callsign()`.
345
        #     """
346
        #     full_callsign = 'W2GMD-1'
347
        #     callsign = apex.aprs.util.create_callsign(full_callsign)
348
        #     self.assertEqual({'callsign': 'W2GMD', 'ssid': 1}, callsign)
349
        #
350
        # def test_full_callsign(self):
351
        #     """
352
        #     Tests converting a callsign dict to a callsing string
353
        #     (callsign-ssid) using `aprs.util.full_callsign()`.
354
        #     """
355
        #     callsign = {'callsign': 'W2GMD', 'ssid': 1}
356
        #     full_callsign = apex.aprs.util.full_callsign(callsign)
357
        #     self.assertEqual('W2GMD-1', full_callsign)
358
        #
359
        # def test_encode_callsign_digipeated(self):
360
        #     """
361
        #     Tests encoding a digipeated callsign with
362
        #     `aprs.util.encode_callsign()`.
363
        #     """
364
        #     callsign = {'callsign': 'W2GMD*', 'ssid': 1}
365
        #     encoded_callsign = apex.aprs.util.encode_callsign(callsign)
366
        #     self.assertEqual('\xaed\x8e\x9a\x88@\xe2', encoded_callsign)
367
        #
368
        # def test_encode_callsign(self):
369
        #     """
370
        #     Tests encoding a non-digipeated callsign with
371
        #     `aprs.util.encode_callsign()`.
372
        #     """
373
        #     callsign = {'callsign': 'W2GMD', 'ssid': 1}
374
        #     encoded_callsign = apex.aprs.util.encode_callsign(callsign)
375
        #     self.assertEqual('\xaed\x8e\x9a\x88@b', encoded_callsign)
376
377
378
if __name__ == '__main__':
379
    unittest.main()
380