1 | import os |
---|
2 | from pyexpat import ExpatError |
---|
3 | from xml.dom.minidom import Element |
---|
4 | |
---|
5 | import pytest |
---|
6 | |
---|
7 | from ow.utilities import ( |
---|
8 | slugify, |
---|
9 | GPXMinidomParser, |
---|
10 | semicircles_to_degrees, |
---|
11 | degrees_to_semicircles, |
---|
12 | miles_to_kms, |
---|
13 | kms_to_miles, |
---|
14 | meters_to_kms, |
---|
15 | kms_to_meters, |
---|
16 | mps_to_kmph, |
---|
17 | kmph_to_mps, |
---|
18 | ) |
---|
19 | |
---|
20 | |
---|
21 | class TestUtilities(object): |
---|
22 | |
---|
23 | def test_slugify(self): |
---|
24 | res = slugify(u'long story SHORT ') |
---|
25 | assert res == u'long-story-short' |
---|
26 | res = slugify(u'bla \u03ba\u03b1\u03bb\u03ac \u03c0\u03b1\u03c2') |
---|
27 | assert res == u'bla-kala-pas' |
---|
28 | |
---|
29 | def test_slugify_special_chars(self): |
---|
30 | res = slugify(u'(r)-[i]\u00AE') |
---|
31 | assert res == u'r-i-r' |
---|
32 | |
---|
33 | def test_semicircles_to_degrees(self): |
---|
34 | assert semicircles_to_degrees(10) == 10 * (180 / pow(2, 31)) |
---|
35 | |
---|
36 | def test_degrees_to_semicircles(self): |
---|
37 | assert degrees_to_semicircles(10) == 10 * (pow(2, 31) / 180) |
---|
38 | |
---|
39 | def test_miles_to_kms(self): |
---|
40 | assert miles_to_kms(100) == 100 / 0.62137119 |
---|
41 | |
---|
42 | def test_kms_to_miles(self): |
---|
43 | assert kms_to_miles(100) == 100 * 0.62137119 |
---|
44 | |
---|
45 | def test_meters_to_kms(self): |
---|
46 | assert meters_to_kms(1000) == 1 |
---|
47 | |
---|
48 | def test_kms_to_meters(self): |
---|
49 | assert kms_to_meters(1) == 1000 |
---|
50 | |
---|
51 | def test_mps_to_kmph(self): |
---|
52 | assert mps_to_kmph(5) == 5 * 3.6 |
---|
53 | |
---|
54 | def test_kmph_to_mps(self): |
---|
55 | assert kmph_to_mps(30) == 30 * 0.277778 |
---|
56 | |
---|
57 | |
---|
58 | class TestGPXParseMinidom(object): |
---|
59 | |
---|
60 | def gpx_file(self, filename): |
---|
61 | """ |
---|
62 | Return the full path to the given filename from the available fixtures |
---|
63 | """ |
---|
64 | here = os.path.abspath(os.path.dirname(__file__)) |
---|
65 | path = os.path.join(here, 'fixtures', filename) |
---|
66 | return path |
---|
67 | |
---|
68 | def test_load_gpx_invalid(self): |
---|
69 | gpx_file = self.gpx_file('invalid.gpx') |
---|
70 | parser = GPXMinidomParser(gpx_file) |
---|
71 | with pytest.raises(ExpatError): |
---|
72 | parser.load_gpx() |
---|
73 | assert parser.gpx is None |
---|
74 | |
---|
75 | gpx_files = [ |
---|
76 | ('empty.gpx', Element), |
---|
77 | ('20131013.gpx', Element), # GPX 1.0 file |
---|
78 | ('20160129-with-extensions.gpx', Element), # GPX 1.1 file with ext. |
---|
79 | ] |
---|
80 | |
---|
81 | @pytest.mark.parametrize(('filename', 'expected'), gpx_files) |
---|
82 | def test_load_gpx(self, filename, expected): |
---|
83 | """ |
---|
84 | Loading valid gpx files ends in the gpx attribute of the parser |
---|
85 | being a xml.dom.minidom.Element object, not matter if the gpx file |
---|
86 | is empty or a 1.0/1.1 gpx file. |
---|
87 | """ |
---|
88 | gpx_file = self.gpx_file(filename) |
---|
89 | parser = GPXMinidomParser(gpx_file) |
---|
90 | parser.load_gpx() |
---|
91 | assert isinstance(parser.gpx, expected) |
---|
92 | |
---|
93 | def test_parse_tracks_empty_gpx(self): |
---|
94 | gpx_file = self.gpx_file('empty.gpx') |
---|
95 | parser = GPXMinidomParser(gpx_file) |
---|
96 | parser.load_gpx() |
---|
97 | parser.parse_tracks() |
---|
98 | assert parser.tracks == {} |
---|
99 | |
---|
100 | def test_parse_tracks_1_0_gpx(self): |
---|
101 | """ |
---|
102 | Parsing a GPX 1.0 file with no extensions. The points in the track |
---|
103 | contain keys for the well-known extensions (hr, cad, atemp), but their |
---|
104 | values are None |
---|
105 | """ |
---|
106 | gpx_file = self.gpx_file('20131013.gpx') |
---|
107 | parser = GPXMinidomParser(gpx_file) |
---|
108 | parser.load_gpx() |
---|
109 | parser.parse_tracks() |
---|
110 | keys = list(parser.tracks.keys()) |
---|
111 | assert keys == [u'A ride I will never forget'] |
---|
112 | point = parser.tracks[keys[0]][0] |
---|
113 | data = ['lat', 'lon', 'ele', 'time'] |
---|
114 | for d in data: |
---|
115 | assert point[d] is not None |
---|
116 | extensions = ['hr', 'cad', 'atemp'] |
---|
117 | for e in extensions: |
---|
118 | assert point[e] is None |
---|
119 | |
---|
120 | def test_parse_tracks_1_1_gpx(self): |
---|
121 | """ |
---|
122 | Parsing a GPX 1.1 file with extensions. The points in the track contain |
---|
123 | keys for the well-known extensions (hr, cad, atemp), with the values |
---|
124 | taken from the gpx file (although we test only that they are not None) |
---|
125 | """ |
---|
126 | gpx_file = self.gpx_file('20160129-with-extensions.gpx') |
---|
127 | parser = GPXMinidomParser(gpx_file) |
---|
128 | parser.load_gpx() |
---|
129 | parser.parse_tracks() |
---|
130 | keys = list(parser.tracks.keys()) |
---|
131 | assert keys == [ |
---|
132 | u'Cota counterclockwise + end bonus'] |
---|
133 | point = parser.tracks[keys[0]][0] |
---|
134 | data = ['lat', 'lon', 'ele', 'time'] |
---|
135 | for d in data: |
---|
136 | assert point[d] is not None |
---|
137 | extensions = ['hr', 'cad', 'atemp'] |
---|
138 | for e in extensions: |
---|
139 | assert point[e] is not None |
---|