1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: geographic models may now be tested; started test geographic application to test geographic queries and lookup types.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5763 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-07-26 02:27:17 +00:00
parent 3754b13bec
commit a2c4f2f61e
6 changed files with 168 additions and 10 deletions

View File

@ -1,5 +1,10 @@
from unittest import TestSuite, makeSuite, TextTestRunner
from copy import copy
from unittest import TestSuite, TextTestRunner
from django.contrib.gis.utils import create_spatial_db
from django.db import connection
from django.test.utils import destroy_test_db
# Tests that do not require setting up and tearing down a spatial database.
test_suite_names = ['test_gdal_driver',
'test_gdal_ds',
'test_gdal_geom',
@ -9,16 +14,78 @@ test_suite_names = ['test_gdal_driver',
'test_spatialrefsys',
]
test_models = ['geoapp']
def suite():
"Builds a test suite for the GIS package."
s = TestSuite()
for test_suite in test_suite_names:
suite = getattr(__import__('django.contrib.gis.tests', fromlist=[test_suite]),test_suite)
s.addTest(suite.suite())
tsuite = getattr(__import__('django.contrib.gis.tests', fromlist=[test_suite]),test_suite)
s.addTest(tsuite.suite())
return s
def run(verbosity=1):
"Runs the tests that do not require geographic (GEOS, GDAL, etc.) models."
TextTestRunner(verbosity=verbosity).run(suite())
def run_tests(module_list, verbosity=1):
"""Run the tests that require creation of a spatial database. Does not
yet work on Windows platforms.
In order to run geographic model tests the DATABASE_USER will require
superuser priviliges. To accomplish this outside the `postgres` user,
create your own PostgreSQL database as a user:
(1) Initialize database: `initdb -D /path/to/user/db`
(2) If there's already a Postgres instance on the machine, it will need
to use a different TCP port than 5432. Edit postgresql.conf (in
/path/to/user/db) to change the database port (e.g. `port = 5433`).
(3) Start this database `pg_ctl -D /path/to/user/db start`
Make sure your settings.py matches the settings of the user database. For example, set the
same port number (`DATABASE_PORT=5433`). DATABASE_NAME or TEST_DATABSE_NAME must be set,
along with DATABASE_USER.
In settings.py set TEST_RUNNER='django.contrib.gis.tests.run_tests'.
Finally, this assumes that the PostGIS SQL files (lwpostgis.sql and spatial_ref_sys.sql)
are installed in /usr/local/share. If they are not, add `POSTGIS_SQL_PATH=/path/to/sql`
in your settings.py.
The tests may be run by invoking `./manage.py test`.
"""
from django.conf import settings
# Getting initial values.
old_name = copy(settings.DATABASE_NAME)
old_installed = copy(settings.INSTALLED_APPS)
# Creating the test suite, adding the test models to INSTALLED_APPS, and
# adding the model test suites to our suite package.
test_suite = suite()
for test_model in test_models:
module_name = 'django.contrib.gis.tests.%s' % test_model
settings.INSTALLED_APPS.append(module_name)
tsuite = getattr(__import__('django.contrib.gis.tests.%s' % test_model, fromlist=['tests']), 'tests')
test_suite.addTest(tsuite.suite())
# Resetting the loaded flag to take into account what we appended to the INSTALLED_APPS
# (since this routine is invoked through django/core/management, it caches the apps,
# this ensures that syncdb will see our appended models)
from django.db.models import loading
loading._loaded = False
# Creating the test spatial database.
create_spatial_db(test=True, verbosity=verbosity)
# Executing the tests (including the model tests)
result = TextTestRunner(verbosity=verbosity).run(test_suite)
# Cleaning up, destroying the test spatial database and resetting the INSTALLED_APPS.
destroy_test_db(old_name, verbosity)
settings.INSTALLED_APPS = old_installed
# Returning the total failures and errors
return len(result.failures) + len(result.errors)
if __name__ == '__main__':
run()

View File

@ -0,0 +1,11 @@
from django.contrib.gis.db import models
class Country(models.Model, models.GeoMixin):
name = models.CharField(maxlength=30)
mpoly = models.MultiPolygonField() # SRID, by default, is 4326
objects = models.GeoManager()
class City(models.Model, models.GeoMixin):
name = models.CharField(maxlength=30)
point = models.PointField()
objects = models.GeoManager()

View File

@ -0,0 +1,5 @@
INSERT INTO geoapp_city ("name", "point") VALUES ('Houston', 'SRID=4326;POINT (-95.363151 29.763374)');
INSERT INTO geoapp_city ("name", "point") VALUES ('Dallas', 'SRID=4326;POINT (-96.801611 32.782057)');
INSERT INTO geoapp_city ("name", "point") VALUES ('Oklahoma City', 'SRID=4326;POINT (-97.521157 34.464642)');
INSERT INTO geoapp_city ("name", "point") VALUES ('Wellington', 'SRID=4326;POINT (174.783117 -41.315268)');
INSERT INTO geoapp_city ("name", "point") VALUES ('Pueblo', 'SRID=4326;POINT (-104.609252 38.255001)');

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,73 @@
import unittest
from models import Country, City
from django.contrib.gis.geos import fromstr, Point
class GeoModelTest(unittest.TestCase):
def test001_initial_sql(self):
"Testing geographic initial SQL."
# Ensuring that data was loaded from initial SQL.
self.assertEqual(2, Country.objects.count())
self.assertEqual(5, City.objects.count())
def test002_contains_contained(self):
"Testing the 'contained' and 'contains' lookup types."
# Getting Texas, yes we were a country -- once ;)
texas = Country.objects.get(name='Texas')
# Seeing what cities are in Texas, should get Houston and Dallas,
# and Oklahoma City because 'contained' only checks on the
# _bounding box_ of the Geometries.
qs = City.objects.filter(point__contained=texas.mpoly)
self.assertEqual(3, qs.count())
city_names = [c.name for c in qs]
self.assertEqual(True, 'Houston' in city_names)
self.assertEqual(True, 'Dallas' in city_names)
self.assertEqual(True, 'Oklahoma City' in city_names)
# Pulling out some cities.
houston = City.objects.get(name='Houston')
wellington = City.objects.get(name='Wellington')
pueblo = City.objects.get(name='Pueblo')
okcity = City.objects.get(name='Oklahoma City')
# Now testing contains on the countries using the points for
# Houston and Wellington.
tx = Country.objects.get(mpoly__contains=houston.point) # Query w/GEOSGeometry
nz = Country.objects.get(mpoly__contains=wellington.point.hex) # Query w/EWKBHEX
self.assertEqual('Texas', tx.name)
self.assertEqual('New Zealand', nz.name)
# Pueblo and Oklahoma City (even though OK City is within the bounding box of Texas)
# are not contained in Texas or New Zealand.
self.assertEqual(0, len(Country.objects.filter(mpoly__contains=pueblo.point))) # Query w/GEOSGeometry object
self.assertEqual(0, len(Country.objects.filter(mpoly__contains=okcity.point.wkt))) # Qeury w/WKT
def test003_lookup_insert_transform(self):
"Testing automatic transform for lookups and inserts."
# San Antonio in WGS84 and NAD83(HARN) / Texas Centric Lambert Conformal
sa_4326 = 'POINT (-98.493183 29.424170)'
sa_3084 = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform
# Constructing & querying with a point from a different SRID
wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84
nad_pnt = fromstr(sa_3084, srid=3084)
tx = Country.objects.get(mpoly__intersects=nad_pnt)
self.assertEqual('Texas', tx.name)
# Creating San Antonio. Remember the Alamo.
sa = City(name='San Antonio', point=nad_pnt)
sa.save()
# Now verifying that San Antonio was transformed correctly
sa = City.objects.get(name='San Antonio')
self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6)
self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6)
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(GeoModelTest))
return s