mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +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:
parent
3754b13bec
commit
a2c4f2f61e
@ -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_suite_names = ['test_gdal_driver',
|
||||||
'test_gdal_ds',
|
'test_gdal_ds',
|
||||||
'test_gdal_geom',
|
'test_gdal_geom',
|
||||||
@ -9,16 +14,78 @@ test_suite_names = ['test_gdal_driver',
|
|||||||
'test_spatialrefsys',
|
'test_spatialrefsys',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
test_models = ['geoapp']
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
|
"Builds a test suite for the GIS package."
|
||||||
s = TestSuite()
|
s = TestSuite()
|
||||||
for test_suite in test_suite_names:
|
for test_suite in test_suite_names:
|
||||||
suite = getattr(__import__('django.contrib.gis.tests', fromlist=[test_suite]),test_suite)
|
tsuite = getattr(__import__('django.contrib.gis.tests', fromlist=[test_suite]),test_suite)
|
||||||
s.addTest(suite.suite())
|
s.addTest(tsuite.suite())
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def run(verbosity=1):
|
def run(verbosity=1):
|
||||||
|
"Runs the tests that do not require geographic (GEOS, GDAL, etc.) models."
|
||||||
TextTestRunner(verbosity=verbosity).run(suite())
|
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__':
|
if __name__ == '__main__':
|
||||||
run()
|
run()
|
||||||
|
0
django/contrib/gis/tests/geoapp/__init__.py
Normal file
0
django/contrib/gis/tests/geoapp/__init__.py
Normal file
11
django/contrib/gis/tests/geoapp/models.py
Normal file
11
django/contrib/gis/tests/geoapp/models.py
Normal 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()
|
5
django/contrib/gis/tests/geoapp/sql/city.sql
Normal file
5
django/contrib/gis/tests/geoapp/sql/city.sql
Normal 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)');
|
2
django/contrib/gis/tests/geoapp/sql/country.sql
Normal file
2
django/contrib/gis/tests/geoapp/sql/country.sql
Normal file
File diff suppressed because one or more lines are too long
73
django/contrib/gis/tests/geoapp/tests.py
Normal file
73
django/contrib/gis/tests/geoapp/tests.py
Normal 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
|
Loading…
x
Reference in New Issue
Block a user