app/django/contrib/gis/tests/test_measure.py
changeset 323 ff1a9aa48cfd
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
       
     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 *= 5
       
    99         self.assertEqual(d3.m, 1000)
       
   100         
       
   101         d4 = d1 / 2
       
   102         self.assertEqual(d4.m, 50)
       
   103         d4 /= 5
       
   104         self.assertEqual(d4.m, 10)
       
   105         
       
   106         a5 = d1 * D(m=10)
       
   107         self.assert_(isinstance(a5, Area))
       
   108         self.assertEqual(a5.sq_m, 100*10)
       
   109 
       
   110         try:
       
   111             d1 *= D(m=1)
       
   112         except TypeError, e:
       
   113             pass
       
   114         else:
       
   115             self.fail('Distance *= Distance should raise TypeError')
       
   116             
       
   117         try:
       
   118             d5 = d1 / D(m=1)
       
   119         except TypeError, e:
       
   120             pass
       
   121         else:
       
   122             self.fail('Distance / Distance should raise TypeError')
       
   123 
       
   124         try:
       
   125             d1 /= D(m=1)
       
   126         except TypeError, e:
       
   127             pass
       
   128         else:
       
   129             self.fail('Distance /= Distance should raise TypeError')
       
   130 
       
   131     def testUnitConversions(self):
       
   132         "Testing default units during maths"
       
   133         d1 = D(m=100)
       
   134         d2 = D(km=1)
       
   135 
       
   136         d3 = d1 + d2
       
   137         self.assertEqual(d3._default_unit, 'm')
       
   138         d4 = d2 + d1
       
   139         self.assertEqual(d4._default_unit, 'km')
       
   140         d5 = d1 * 2
       
   141         self.assertEqual(d5._default_unit, 'm')
       
   142         d6 = d1 / 2
       
   143         self.assertEqual(d6._default_unit, 'm')
       
   144     
       
   145     def testComparisons(self):
       
   146         "Testing comparisons"
       
   147         d1 = D(m=100)
       
   148         d2 = D(km=1)
       
   149         d3 = D(km=0)
       
   150         
       
   151         self.assert_(d2 > d1)
       
   152         self.assert_(d1 == d1)
       
   153         self.assert_(d1 < d2)
       
   154         self.failIf(d3)
       
   155         
       
   156     def testUnitsStr(self):
       
   157         "Testing conversion to strings"
       
   158         d1 = D(m=100)
       
   159         d2 = D(km=3.5)
       
   160         
       
   161         self.assertEqual(str(d1), '100.0 m')
       
   162         self.assertEqual(str(d2), '3.5 km')
       
   163         self.assertEqual(repr(d1), 'Distance(m=100.0)')
       
   164         self.assertEqual(repr(d2), 'Distance(km=3.5)')
       
   165 
       
   166     def testUnitAttName(self):
       
   167         "Testing the `unit_attname` class method"
       
   168         unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'),
       
   169                       ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')]
       
   170         for nm, att in unit_tuple:
       
   171             self.assertEqual(att, D.unit_attname(nm))
       
   172 
       
   173 class AreaTest(unittest.TestCase):
       
   174     "Testing the Area object"
       
   175 
       
   176     def testInit(self):
       
   177         "Testing initialisation from valid units"
       
   178         a = Area(sq_m=100)
       
   179         self.assertEqual(a.sq_m, 100)
       
   180 
       
   181         a = A(sq_m=100)
       
   182         self.assertEqual(a.sq_m, 100)
       
   183 
       
   184         a = A(sq_mi=100)
       
   185         self.assertEqual(a.sq_m, 258998811.0336)
       
   186     
       
   187     def testInitInvaliA(self):
       
   188         "Testing initialisation from invalid units"
       
   189         self.assertRaises(AttributeError, A, banana=100)
       
   190 
       
   191     def testAccess(self):
       
   192         "Testing access in different units"
       
   193         a = A(sq_m=100)
       
   194         self.assertEqual(a.sq_km, 0.0001)
       
   195         self.assertAlmostEqual(a.sq_ft, 1076.391, 3)
       
   196     
       
   197     def testAccessInvaliA(self):
       
   198         "Testing access in invalid units"
       
   199         a = A(sq_m=100)
       
   200         self.failIf(hasattr(a, 'banana'))
       
   201 
       
   202     def testAddition(self):
       
   203         "Test addition & subtraction"
       
   204         a1 = A(sq_m=100)
       
   205         a2 = A(sq_m=200)
       
   206 
       
   207         a3 = a1 + a2
       
   208         self.assertEqual(a3.sq_m, 300)
       
   209         a3 += a1
       
   210         self.assertEqual(a3.sq_m, 400)
       
   211         
       
   212         a4 = a1 - a2
       
   213         self.assertEqual(a4.sq_m, -100)
       
   214         a4 -= a1
       
   215         self.assertEqual(a4.sq_m, -200)
       
   216         
       
   217         try:
       
   218             a5 = a1 + 1
       
   219         except TypeError, e:
       
   220             pass
       
   221         else:
       
   222             self.fail('Area + number should raise TypeError')
       
   223 
       
   224         try:
       
   225             a5 = a1 - 1
       
   226         except TypeError, e:
       
   227             pass
       
   228         else:
       
   229             self.fail('Area - number should raise TypeError')
       
   230 
       
   231         try:
       
   232             a1 += 1
       
   233         except TypeError, e:
       
   234             pass
       
   235         else:
       
   236             self.fail('Area += number should raise TypeError')
       
   237 
       
   238         try:
       
   239             a1 -= 1
       
   240         except TypeError, e:
       
   241             pass
       
   242         else:
       
   243             self.fail('Area -= number should raise TypeError')
       
   244             
       
   245     def testMultiplication(self):
       
   246         "Test multiplication & division"
       
   247         a1 = A(sq_m=100)
       
   248 
       
   249         a3 = a1 * 2
       
   250         self.assertEqual(a3.sq_m, 200)
       
   251         a3 *= 5
       
   252         self.assertEqual(a3.sq_m, 1000)
       
   253         
       
   254         a4 = a1 / 2
       
   255         self.assertEqual(a4.sq_m, 50)
       
   256         a4 /= 5
       
   257         self.assertEqual(a4.sq_m, 10)
       
   258         
       
   259         try:
       
   260             a5 = a1 * A(sq_m=1)
       
   261         except TypeError, e:
       
   262             pass
       
   263         else:
       
   264             self.fail('Area * Area should raise TypeError')
       
   265 
       
   266         try:
       
   267             a1 *= A(sq_m=1)
       
   268         except TypeError, e:
       
   269             pass
       
   270         else:
       
   271             self.fail('Area *= Area should raise TypeError')
       
   272             
       
   273         try:
       
   274             a5 = a1 / A(sq_m=1)
       
   275         except TypeError, e:
       
   276             pass
       
   277         else:
       
   278             self.fail('Area / Area should raise TypeError')
       
   279 
       
   280         try:
       
   281             a1 /= A(sq_m=1)
       
   282         except TypeError, e:
       
   283             pass
       
   284         else:
       
   285             self.fail('Area /= Area should raise TypeError')
       
   286 
       
   287     def testUnitConversions(self):
       
   288         "Testing default units during maths"
       
   289         a1 = A(sq_m=100)
       
   290         a2 = A(sq_km=1)
       
   291 
       
   292         a3 = a1 + a2
       
   293         self.assertEqual(a3._default_unit, 'sq_m')
       
   294         a4 = a2 + a1
       
   295         self.assertEqual(a4._default_unit, 'sq_km')
       
   296         a5 = a1 * 2
       
   297         self.assertEqual(a5._default_unit, 'sq_m')
       
   298         a6 = a1 / 2
       
   299         self.assertEqual(a6._default_unit, 'sq_m')
       
   300     
       
   301     def testComparisons(self):
       
   302         "Testing comparisons"
       
   303         a1 = A(sq_m=100)
       
   304         a2 = A(sq_km=1)
       
   305         a3 = A(sq_km=0)
       
   306         
       
   307         self.assert_(a2 > a1)
       
   308         self.assert_(a1 == a1)
       
   309         self.assert_(a1 < a2)
       
   310         self.failIf(a3)
       
   311         
       
   312     def testUnitsStr(self):
       
   313         "Testing conversion to strings"
       
   314         a1 = A(sq_m=100)
       
   315         a2 = A(sq_km=3.5)
       
   316         
       
   317         self.assertEqual(str(a1), '100.0 sq_m')
       
   318         self.assertEqual(str(a2), '3.5 sq_km')
       
   319         self.assertEqual(repr(a1), 'Area(sq_m=100.0)')
       
   320         self.assertEqual(repr(a2), 'Area(sq_km=3.5)')
       
   321 
       
   322         
       
   323 def suite():
       
   324     s = unittest.TestSuite()
       
   325     s.addTest(unittest.makeSuite(DistanceTest))
       
   326     s.addTest(unittest.makeSuite(AreaTest))
       
   327     return s
       
   328 
       
   329 def run(verbosity=2):
       
   330     unittest.TextTestRunner(verbosity=verbosity).run(suite())
       
   331 
       
   332 if __name__=="__main__":
       
   333     run()