| """ |
| Distance and Area objects to allow for sensible and convienient calculation |
| and conversions. Here are some tests. |
| """ |
| |
| import unittest |
| from django.contrib.gis.measure import Distance, Area, D, A |
| |
| class DistanceTest(unittest.TestCase): |
| "Testing the Distance object" |
| |
| def testInit(self): |
| "Testing initialisation from valid units" |
| d = Distance(m=100) |
| self.assertEqual(d.m, 100) |
| |
| d1, d2, d3 = D(m=100), D(meter=100), D(metre=100) |
| for d in (d1, d2, d3): |
| self.assertEqual(d.m, 100) |
| |
| d = D(nm=100) |
| self.assertEqual(d.m, 185200) |
| |
| y1, y2, y3 = D(yd=100), D(yard=100), D(Yard=100) |
| for d in (y1, y2, y3): |
| self.assertEqual(d.yd, 100) |
| |
| mm1, mm2 = D(millimeter=1000), D(MiLLiMeTeR=1000) |
| for d in (mm1, mm2): |
| self.assertEqual(d.m, 1.0) |
| self.assertEqual(d.mm, 1000.0) |
| |
| |
| def testInitInvalid(self): |
| "Testing initialisation from invalid units" |
| self.assertRaises(AttributeError, D, banana=100) |
| |
| def testAccess(self): |
| "Testing access in different units" |
| d = D(m=100) |
| self.assertEqual(d.km, 0.1) |
| self.assertAlmostEqual(d.ft, 328.084, 3) |
| |
| def testAccessInvalid(self): |
| "Testing access in invalid units" |
| d = D(m=100) |
| self.failIf(hasattr(d, 'banana')) |
| |
| def testAddition(self): |
| "Test addition & subtraction" |
| d1 = D(m=100) |
| d2 = D(m=200) |
| |
| d3 = d1 + d2 |
| self.assertEqual(d3.m, 300) |
| d3 += d1 |
| self.assertEqual(d3.m, 400) |
| |
| d4 = d1 - d2 |
| self.assertEqual(d4.m, -100) |
| d4 -= d1 |
| self.assertEqual(d4.m, -200) |
| |
| try: |
| d5 = d1 + 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance + number should raise TypeError') |
| |
| try: |
| d5 = d1 - 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance - number should raise TypeError') |
| |
| try: |
| d1 += 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance += number should raise TypeError') |
| |
| try: |
| d1 -= 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance -= number should raise TypeError') |
| |
| def testMultiplication(self): |
| "Test multiplication & division" |
| d1 = D(m=100) |
| |
| d3 = d1 * 2 |
| self.assertEqual(d3.m, 200) |
| d3 *= 5 |
| self.assertEqual(d3.m, 1000) |
| |
| d4 = d1 / 2 |
| self.assertEqual(d4.m, 50) |
| d4 /= 5 |
| self.assertEqual(d4.m, 10) |
| |
| a5 = d1 * D(m=10) |
| self.assert_(isinstance(a5, Area)) |
| self.assertEqual(a5.sq_m, 100*10) |
| |
| try: |
| d1 *= D(m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance *= Distance should raise TypeError') |
| |
| try: |
| d5 = d1 / D(m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance / Distance should raise TypeError') |
| |
| try: |
| d1 /= D(m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Distance /= Distance should raise TypeError') |
| |
| def testUnitConversions(self): |
| "Testing default units during maths" |
| d1 = D(m=100) |
| d2 = D(km=1) |
| |
| d3 = d1 + d2 |
| self.assertEqual(d3._default_unit, 'm') |
| d4 = d2 + d1 |
| self.assertEqual(d4._default_unit, 'km') |
| d5 = d1 * 2 |
| self.assertEqual(d5._default_unit, 'm') |
| d6 = d1 / 2 |
| self.assertEqual(d6._default_unit, 'm') |
| |
| def testComparisons(self): |
| "Testing comparisons" |
| d1 = D(m=100) |
| d2 = D(km=1) |
| d3 = D(km=0) |
| |
| self.assert_(d2 > d1) |
| self.assert_(d1 == d1) |
| self.assert_(d1 < d2) |
| self.failIf(d3) |
| |
| def testUnitsStr(self): |
| "Testing conversion to strings" |
| d1 = D(m=100) |
| d2 = D(km=3.5) |
| |
| self.assertEqual(str(d1), '100.0 m') |
| self.assertEqual(str(d2), '3.5 km') |
| self.assertEqual(repr(d1), 'Distance(m=100.0)') |
| self.assertEqual(repr(d2), 'Distance(km=3.5)') |
| |
| def testUnitAttName(self): |
| "Testing the `unit_attname` class method" |
| unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'), |
| ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')] |
| for nm, att in unit_tuple: |
| self.assertEqual(att, D.unit_attname(nm)) |
| |
| class AreaTest(unittest.TestCase): |
| "Testing the Area object" |
| |
| def testInit(self): |
| "Testing initialisation from valid units" |
| a = Area(sq_m=100) |
| self.assertEqual(a.sq_m, 100) |
| |
| a = A(sq_m=100) |
| self.assertEqual(a.sq_m, 100) |
| |
| a = A(sq_mi=100) |
| self.assertEqual(a.sq_m, 258998811.0336) |
| |
| def testInitInvaliA(self): |
| "Testing initialisation from invalid units" |
| self.assertRaises(AttributeError, A, banana=100) |
| |
| def testAccess(self): |
| "Testing access in different units" |
| a = A(sq_m=100) |
| self.assertEqual(a.sq_km, 0.0001) |
| self.assertAlmostEqual(a.sq_ft, 1076.391, 3) |
| |
| def testAccessInvaliA(self): |
| "Testing access in invalid units" |
| a = A(sq_m=100) |
| self.failIf(hasattr(a, 'banana')) |
| |
| def testAddition(self): |
| "Test addition & subtraction" |
| a1 = A(sq_m=100) |
| a2 = A(sq_m=200) |
| |
| a3 = a1 + a2 |
| self.assertEqual(a3.sq_m, 300) |
| a3 += a1 |
| self.assertEqual(a3.sq_m, 400) |
| |
| a4 = a1 - a2 |
| self.assertEqual(a4.sq_m, -100) |
| a4 -= a1 |
| self.assertEqual(a4.sq_m, -200) |
| |
| try: |
| a5 = a1 + 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area + number should raise TypeError') |
| |
| try: |
| a5 = a1 - 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area - number should raise TypeError') |
| |
| try: |
| a1 += 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area += number should raise TypeError') |
| |
| try: |
| a1 -= 1 |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area -= number should raise TypeError') |
| |
| def testMultiplication(self): |
| "Test multiplication & division" |
| a1 = A(sq_m=100) |
| |
| a3 = a1 * 2 |
| self.assertEqual(a3.sq_m, 200) |
| a3 *= 5 |
| self.assertEqual(a3.sq_m, 1000) |
| |
| a4 = a1 / 2 |
| self.assertEqual(a4.sq_m, 50) |
| a4 /= 5 |
| self.assertEqual(a4.sq_m, 10) |
| |
| try: |
| a5 = a1 * A(sq_m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area * Area should raise TypeError') |
| |
| try: |
| a1 *= A(sq_m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area *= Area should raise TypeError') |
| |
| try: |
| a5 = a1 / A(sq_m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area / Area should raise TypeError') |
| |
| try: |
| a1 /= A(sq_m=1) |
| except TypeError, e: |
| pass |
| else: |
| self.fail('Area /= Area should raise TypeError') |
| |
| def testUnitConversions(self): |
| "Testing default units during maths" |
| a1 = A(sq_m=100) |
| a2 = A(sq_km=1) |
| |
| a3 = a1 + a2 |
| self.assertEqual(a3._default_unit, 'sq_m') |
| a4 = a2 + a1 |
| self.assertEqual(a4._default_unit, 'sq_km') |
| a5 = a1 * 2 |
| self.assertEqual(a5._default_unit, 'sq_m') |
| a6 = a1 / 2 |
| self.assertEqual(a6._default_unit, 'sq_m') |
| |
| def testComparisons(self): |
| "Testing comparisons" |
| a1 = A(sq_m=100) |
| a2 = A(sq_km=1) |
| a3 = A(sq_km=0) |
| |
| self.assert_(a2 > a1) |
| self.assert_(a1 == a1) |
| self.assert_(a1 < a2) |
| self.failIf(a3) |
| |
| def testUnitsStr(self): |
| "Testing conversion to strings" |
| a1 = A(sq_m=100) |
| a2 = A(sq_km=3.5) |
| |
| self.assertEqual(str(a1), '100.0 sq_m') |
| self.assertEqual(str(a2), '3.5 sq_km') |
| self.assertEqual(repr(a1), 'Area(sq_m=100.0)') |
| self.assertEqual(repr(a2), 'Area(sq_km=3.5)') |
| |
| |
| def suite(): |
| s = unittest.TestSuite() |
| s.addTest(unittest.makeSuite(DistanceTest)) |
| s.addTest(unittest.makeSuite(AreaTest)) |
| return s |
| |
| def run(verbosity=2): |
| unittest.TextTestRunner(verbosity=verbosity).run(suite()) |
| |
| if __name__=="__main__": |
| run() |