|
1 """ |
|
2 Distance and Area objects to allow for sensible and convienient calculation |
|
3 and conversions. Here are some tests. |
|
4 """ |
|
5 |
|
6 import unittest |
|
7 from django.contrib.gis.measure import Distance, Area, D, A |
|
8 |
|
9 class DistanceTest(unittest.TestCase): |
|
10 "Testing the Distance object" |
|
11 |
|
12 def testInit(self): |
|
13 "Testing initialisation from valid units" |
|
14 d = Distance(m=100) |
|
15 self.assertEqual(d.m, 100) |
|
16 |
|
17 d1, d2, d3 = D(m=100), D(meter=100), D(metre=100) |
|
18 for d in (d1, d2, d3): |
|
19 self.assertEqual(d.m, 100) |
|
20 |
|
21 d = D(nm=100) |
|
22 self.assertEqual(d.m, 185200) |
|
23 |
|
24 y1, y2, y3 = D(yd=100), D(yard=100), D(Yard=100) |
|
25 for d in (y1, y2, y3): |
|
26 self.assertEqual(d.yd, 100) |
|
27 |
|
28 mm1, mm2 = D(millimeter=1000), D(MiLLiMeTeR=1000) |
|
29 for d in (mm1, mm2): |
|
30 self.assertEqual(d.m, 1.0) |
|
31 self.assertEqual(d.mm, 1000.0) |
|
32 |
|
33 |
|
34 def testInitInvalid(self): |
|
35 "Testing initialisation from invalid units" |
|
36 self.assertRaises(AttributeError, D, banana=100) |
|
37 |
|
38 def testAccess(self): |
|
39 "Testing access in different units" |
|
40 d = D(m=100) |
|
41 self.assertEqual(d.km, 0.1) |
|
42 self.assertAlmostEqual(d.ft, 328.084, 3) |
|
43 |
|
44 def testAccessInvalid(self): |
|
45 "Testing access in invalid units" |
|
46 d = D(m=100) |
|
47 self.failIf(hasattr(d, 'banana')) |
|
48 |
|
49 def testAddition(self): |
|
50 "Test addition & subtraction" |
|
51 d1 = D(m=100) |
|
52 d2 = D(m=200) |
|
53 |
|
54 d3 = d1 + d2 |
|
55 self.assertEqual(d3.m, 300) |
|
56 d3 += d1 |
|
57 self.assertEqual(d3.m, 400) |
|
58 |
|
59 d4 = d1 - d2 |
|
60 self.assertEqual(d4.m, -100) |
|
61 d4 -= d1 |
|
62 self.assertEqual(d4.m, -200) |
|
63 |
|
64 try: |
|
65 d5 = d1 + 1 |
|
66 except TypeError, e: |
|
67 pass |
|
68 else: |
|
69 self.fail('Distance + number should raise TypeError') |
|
70 |
|
71 try: |
|
72 d5 = d1 - 1 |
|
73 except TypeError, e: |
|
74 pass |
|
75 else: |
|
76 self.fail('Distance - number should raise TypeError') |
|
77 |
|
78 try: |
|
79 d1 += 1 |
|
80 except TypeError, e: |
|
81 pass |
|
82 else: |
|
83 self.fail('Distance += number should raise TypeError') |
|
84 |
|
85 try: |
|
86 d1 -= 1 |
|
87 except TypeError, e: |
|
88 pass |
|
89 else: |
|
90 self.fail('Distance -= number should raise TypeError') |
|
91 |
|
92 def testMultiplication(self): |
|
93 "Test multiplication & division" |
|
94 d1 = D(m=100) |
|
95 |
|
96 d3 = d1 * 2 |
|
97 self.assertEqual(d3.m, 200) |
|
98 d3 = 2 * d1 |
|
99 self.assertEqual(d3.m, 200) |
|
100 d3 *= 5 |
|
101 self.assertEqual(d3.m, 1000) |
|
102 |
|
103 d4 = d1 / 2 |
|
104 self.assertEqual(d4.m, 50) |
|
105 d4 /= 5 |
|
106 self.assertEqual(d4.m, 10) |
|
107 |
|
108 a5 = d1 * D(m=10) |
|
109 self.assert_(isinstance(a5, Area)) |
|
110 self.assertEqual(a5.sq_m, 100*10) |
|
111 |
|
112 try: |
|
113 d1 *= D(m=1) |
|
114 except TypeError, e: |
|
115 pass |
|
116 else: |
|
117 self.fail('Distance *= Distance should raise TypeError') |
|
118 |
|
119 try: |
|
120 d5 = d1 / D(m=1) |
|
121 except TypeError, e: |
|
122 pass |
|
123 else: |
|
124 self.fail('Distance / Distance should raise TypeError') |
|
125 |
|
126 try: |
|
127 d1 /= D(m=1) |
|
128 except TypeError, e: |
|
129 pass |
|
130 else: |
|
131 self.fail('Distance /= Distance should raise TypeError') |
|
132 |
|
133 def testUnitConversions(self): |
|
134 "Testing default units during maths" |
|
135 d1 = D(m=100) |
|
136 d2 = D(km=1) |
|
137 |
|
138 d3 = d1 + d2 |
|
139 self.assertEqual(d3._default_unit, 'm') |
|
140 d4 = d2 + d1 |
|
141 self.assertEqual(d4._default_unit, 'km') |
|
142 d5 = d1 * 2 |
|
143 self.assertEqual(d5._default_unit, 'm') |
|
144 d6 = d1 / 2 |
|
145 self.assertEqual(d6._default_unit, 'm') |
|
146 |
|
147 def testComparisons(self): |
|
148 "Testing comparisons" |
|
149 d1 = D(m=100) |
|
150 d2 = D(km=1) |
|
151 d3 = D(km=0) |
|
152 |
|
153 self.assert_(d2 > d1) |
|
154 self.assert_(d1 == d1) |
|
155 self.assert_(d1 < d2) |
|
156 self.failIf(d3) |
|
157 |
|
158 def testUnitsStr(self): |
|
159 "Testing conversion to strings" |
|
160 d1 = D(m=100) |
|
161 d2 = D(km=3.5) |
|
162 |
|
163 self.assertEqual(str(d1), '100.0 m') |
|
164 self.assertEqual(str(d2), '3.5 km') |
|
165 self.assertEqual(repr(d1), 'Distance(m=100.0)') |
|
166 self.assertEqual(repr(d2), 'Distance(km=3.5)') |
|
167 |
|
168 def testUnitAttName(self): |
|
169 "Testing the `unit_attname` class method" |
|
170 unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'), |
|
171 ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')] |
|
172 for nm, att in unit_tuple: |
|
173 self.assertEqual(att, D.unit_attname(nm)) |
|
174 |
|
175 class AreaTest(unittest.TestCase): |
|
176 "Testing the Area object" |
|
177 |
|
178 def testInit(self): |
|
179 "Testing initialisation from valid units" |
|
180 a = Area(sq_m=100) |
|
181 self.assertEqual(a.sq_m, 100) |
|
182 |
|
183 a = A(sq_m=100) |
|
184 self.assertEqual(a.sq_m, 100) |
|
185 |
|
186 a = A(sq_mi=100) |
|
187 self.assertEqual(a.sq_m, 258998811.0336) |
|
188 |
|
189 def testInitInvaliA(self): |
|
190 "Testing initialisation from invalid units" |
|
191 self.assertRaises(AttributeError, A, banana=100) |
|
192 |
|
193 def testAccess(self): |
|
194 "Testing access in different units" |
|
195 a = A(sq_m=100) |
|
196 self.assertEqual(a.sq_km, 0.0001) |
|
197 self.assertAlmostEqual(a.sq_ft, 1076.391, 3) |
|
198 |
|
199 def testAccessInvaliA(self): |
|
200 "Testing access in invalid units" |
|
201 a = A(sq_m=100) |
|
202 self.failIf(hasattr(a, 'banana')) |
|
203 |
|
204 def testAddition(self): |
|
205 "Test addition & subtraction" |
|
206 a1 = A(sq_m=100) |
|
207 a2 = A(sq_m=200) |
|
208 |
|
209 a3 = a1 + a2 |
|
210 self.assertEqual(a3.sq_m, 300) |
|
211 a3 += a1 |
|
212 self.assertEqual(a3.sq_m, 400) |
|
213 |
|
214 a4 = a1 - a2 |
|
215 self.assertEqual(a4.sq_m, -100) |
|
216 a4 -= a1 |
|
217 self.assertEqual(a4.sq_m, -200) |
|
218 |
|
219 try: |
|
220 a5 = a1 + 1 |
|
221 except TypeError, e: |
|
222 pass |
|
223 else: |
|
224 self.fail('Area + number should raise TypeError') |
|
225 |
|
226 try: |
|
227 a5 = a1 - 1 |
|
228 except TypeError, e: |
|
229 pass |
|
230 else: |
|
231 self.fail('Area - number should raise TypeError') |
|
232 |
|
233 try: |
|
234 a1 += 1 |
|
235 except TypeError, e: |
|
236 pass |
|
237 else: |
|
238 self.fail('Area += number should raise TypeError') |
|
239 |
|
240 try: |
|
241 a1 -= 1 |
|
242 except TypeError, e: |
|
243 pass |
|
244 else: |
|
245 self.fail('Area -= number should raise TypeError') |
|
246 |
|
247 def testMultiplication(self): |
|
248 "Test multiplication & division" |
|
249 a1 = A(sq_m=100) |
|
250 |
|
251 a3 = a1 * 2 |
|
252 self.assertEqual(a3.sq_m, 200) |
|
253 a3 = 2 * a1 |
|
254 self.assertEqual(a3.sq_m, 200) |
|
255 a3 *= 5 |
|
256 self.assertEqual(a3.sq_m, 1000) |
|
257 |
|
258 a4 = a1 / 2 |
|
259 self.assertEqual(a4.sq_m, 50) |
|
260 a4 /= 5 |
|
261 self.assertEqual(a4.sq_m, 10) |
|
262 |
|
263 try: |
|
264 a5 = a1 * A(sq_m=1) |
|
265 except TypeError, e: |
|
266 pass |
|
267 else: |
|
268 self.fail('Area * Area should raise TypeError') |
|
269 |
|
270 try: |
|
271 a1 *= A(sq_m=1) |
|
272 except TypeError, e: |
|
273 pass |
|
274 else: |
|
275 self.fail('Area *= Area should raise TypeError') |
|
276 |
|
277 try: |
|
278 a5 = a1 / A(sq_m=1) |
|
279 except TypeError, e: |
|
280 pass |
|
281 else: |
|
282 self.fail('Area / Area should raise TypeError') |
|
283 |
|
284 try: |
|
285 a1 /= A(sq_m=1) |
|
286 except TypeError, e: |
|
287 pass |
|
288 else: |
|
289 self.fail('Area /= Area should raise TypeError') |
|
290 |
|
291 def testUnitConversions(self): |
|
292 "Testing default units during maths" |
|
293 a1 = A(sq_m=100) |
|
294 a2 = A(sq_km=1) |
|
295 |
|
296 a3 = a1 + a2 |
|
297 self.assertEqual(a3._default_unit, 'sq_m') |
|
298 a4 = a2 + a1 |
|
299 self.assertEqual(a4._default_unit, 'sq_km') |
|
300 a5 = a1 * 2 |
|
301 self.assertEqual(a5._default_unit, 'sq_m') |
|
302 a6 = a1 / 2 |
|
303 self.assertEqual(a6._default_unit, 'sq_m') |
|
304 |
|
305 def testComparisons(self): |
|
306 "Testing comparisons" |
|
307 a1 = A(sq_m=100) |
|
308 a2 = A(sq_km=1) |
|
309 a3 = A(sq_km=0) |
|
310 |
|
311 self.assert_(a2 > a1) |
|
312 self.assert_(a1 == a1) |
|
313 self.assert_(a1 < a2) |
|
314 self.failIf(a3) |
|
315 |
|
316 def testUnitsStr(self): |
|
317 "Testing conversion to strings" |
|
318 a1 = A(sq_m=100) |
|
319 a2 = A(sq_km=3.5) |
|
320 |
|
321 self.assertEqual(str(a1), '100.0 sq_m') |
|
322 self.assertEqual(str(a2), '3.5 sq_km') |
|
323 self.assertEqual(repr(a1), 'Area(sq_m=100.0)') |
|
324 self.assertEqual(repr(a2), 'Area(sq_km=3.5)') |
|
325 |
|
326 def suite(): |
|
327 s = unittest.TestSuite() |
|
328 s.addTest(unittest.makeSuite(DistanceTest)) |
|
329 s.addTest(unittest.makeSuite(AreaTest)) |
|
330 return s |
|
331 |
|
332 def run(verbosity=2): |
|
333 unittest.TextTestRunner(verbosity=verbosity).run(suite()) |
|
334 |
|
335 if __name__=="__main__": |
|
336 run() |