[1.2.X] GeoDjango test suite housekeeping. Moved data into fixtures for `relatedapp` and `distapp` tests, and made both use Django's `TestCase`; moved functionality out of `GeoDjangoTestSuiteRunner` to allow future re-use in `runtests.py` (refs #10420); compressed test app fixtures and cleaned up imports.

Backport of r14776 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14812 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2010-12-04 13:11:54 +00:00
parent 65b26b30a7
commit d54d7a52a9
14 changed files with 168 additions and 344 deletions

View File

@ -1,14 +1,14 @@
import sys
import unittest
from django.conf import settings
from django.db.models import get_app
from django.test.simple import build_suite, DjangoTestSuiteRunner
def run_tests(*args, **kwargs):
from django.test.simple import run_tests as base_run_tests
return base_run_tests(*args, **kwargs)
def run_gis_tests(test_labels, verbosity=1, interactive=True, failfast=False, extra_tests=None):
import warnings
warnings.warn(
@ -18,94 +18,121 @@ def run_gis_tests(test_labels, verbosity=1, interactive=True, failfast=False, ex
test_runner = GeoDjangoTestSuiteRunner(verbosity=verbosity, interactive=interactive, failfast=failfast)
return test_runner.run_tests(test_labels, extra_tests=extra_tests)
def geo_apps(namespace=True):
"""
Returns a list of GeoDjango test applications that reside in
`django.contrib.gis.tests` that can be used with the current
database and the spatial libraries that are installed.
"""
from django.db import connection
from django.contrib.gis.geos import GEOS_PREPARE
from django.contrib.gis.gdal import HAS_GDAL
apps = ['geoapp', 'relatedapp']
# No distance queries on MySQL.
if not connection.ops.mysql:
apps.append('distapp')
# Test geography support with PostGIS 1.5+.
if connection.ops.postgis and connection.ops.geography:
apps.append('geogapp')
# The following GeoDjango test apps depend on GDAL support.
if HAS_GDAL:
# 3D apps use LayerMapping, which uses GDAL.
if connection.ops.postgis and GEOS_PREPARE:
apps.append('geo3d')
apps.append('layermap')
if namespace:
return ['django.contrib.gis.tests.%s' % app
for app in apps]
else:
return apps
def geodjango_suite():
"""
Returns a TestSuite consisting only of GeoDjango tests that can be run.
"""
import sys
from django.db.models import get_app
suite = unittest.TestSuite()
# Adding the GEOS tests.
from django.contrib.gis.geos import tests as geos_tests
suite.addTest(geos_tests.suite())
# Adding the measurment tests.
from django.contrib.gis.tests import test_measure
suite.addTest(test_measure.suite())
# Adding GDAL tests, and any test suite that depends on GDAL, to the
# suite if GDAL is available.
from django.contrib.gis.gdal import HAS_GDAL
if HAS_GDAL:
from django.contrib.gis.gdal import tests as gdal_tests
suite.addTest(gdal_tests.suite())
from django.contrib.gis.tests import test_spatialrefsys, test_geoforms
suite.addTest(test_spatialrefsys.suite())
suite.addTest(test_geoforms.suite())
else:
sys.stderr.write('GDAL not available - no tests requiring GDAL will be run.\n')
# Add GeoIP tests to the suite, if the library and data is available.
from django.contrib.gis.utils import HAS_GEOIP
if HAS_GEOIP and hasattr(settings, 'GEOIP_PATH'):
from django.contrib.gis.tests import test_geoip
suite.addTest(test_geoip.suite())
# Finally, adding the suites for each of the GeoDjango test apps.
for app_name in geo_apps(namespace=False):
suite.addTest(build_suite(get_app(app_name)))
return suite
class GeoDjangoTestSuiteRunner(DjangoTestSuiteRunner):
def setup_test_environment(self, **kwargs):
super(GeoDjangoTestSuiteRunner, self).setup_test_environment(**kwargs)
from django.db import connection
from django.contrib.gis.geos import GEOS_PREPARE
from django.contrib.gis.gdal import HAS_GDAL
# Getting and storing the original values of INSTALLED_APPS and
# the ROOT_URLCONF.
# Saving original values of INSTALLED_APPS, ROOT_URLCONF, and SITE_ID.
self.old_installed = getattr(settings, 'INSTALLED_APPS', None)
self.old_root_urlconf = getattr(settings, 'ROOT_URLCONF', None)
self.old_root_urlconf = getattr(settings, 'ROOT_URLCONF', '')
self.old_site_id = getattr(settings, 'SITE_ID', None)
# Tests that require use of a spatial database (e.g., creation of models)
self.geo_apps = ['geoapp', 'relatedapp']
if connection.ops.postgis and connection.ops.geography:
# Test geography support with PostGIS 1.5+.
self.geo_apps.append('geogapp')
if HAS_GDAL:
# The following GeoDjango test apps depend on GDAL support.
if not connection.ops.mysql:
self.geo_apps.append('distapp')
# 3D apps use LayerMapping, which uses GDAL.
if connection.ops.postgis and GEOS_PREPARE:
self.geo_apps.append('geo3d')
self.geo_apps.append('layermap')
# Constructing the new INSTALLED_APPS, and including applications
# within the GeoDjango test namespace (`self.geo_apps`).
# within the GeoDjango test namespace.
new_installed = ['django.contrib.sites',
'django.contrib.sitemaps',
'django.contrib.gis',
]
new_installed.extend(['django.contrib.gis.tests.%s' % app
for app in self.geo_apps])
# Calling out to `geo_apps` to get GeoDjango applications supported
# for testing.
new_installed.extend(geo_apps())
settings.INSTALLED_APPS = new_installed
# Setting the URLs.
settings.ROOT_URLCONF = 'django.contrib.gis.tests.urls'
# SITE_ID needs to be set
settings.SITE_ID = 1
# ROOT_URLCONF needs to be set, else `AttributeErrors` are raised
# when TestCases are torn down that have `urls` defined.
settings.ROOT_URLCONF = ''
def teardown_test_environment(self, **kwargs):
super(GeoDjangoTestSuiteRunner, self).teardown_test_environment(**kwargs)
settings.INSTALLED_APPS = self.old_installed
settings.ROOT_URLCONF = self.old_root_urlconf
settings.SITE_ID = self.old_site_id
def build_suite(self, test_labels, extra_tests=None, **kwargs):
"""
This method is overridden to construct a suite consisting only of tests
for GeoDjango.
"""
suite = unittest.TestSuite()
# Adding the GEOS tests.
from django.contrib.gis.geos import tests as geos_tests
suite.addTest(geos_tests.suite())
# Adding the measurment tests.
from django.contrib.gis.tests import test_measure
suite.addTest(test_measure.suite())
# Adding GDAL tests, and any test suite that depends on GDAL, to the
# suite if GDAL is available.
from django.contrib.gis.gdal import HAS_GDAL
if HAS_GDAL:
from django.contrib.gis.gdal import tests as gdal_tests
suite.addTest(gdal_tests.suite())
from django.contrib.gis.tests import test_spatialrefsys, test_geoforms
suite.addTest(test_spatialrefsys.suite())
suite.addTest(test_geoforms.suite())
else:
sys.stderr.write('GDAL not available - no tests requiring GDAL will be run.\n')
# Add GeoIP tests to the suite, if the library and data is available.
from django.contrib.gis.utils import HAS_GEOIP
if HAS_GEOIP and hasattr(settings, 'GEOIP_PATH'):
from django.contrib.gis.tests import test_geoip
suite.addTest(test_geoip.suite())
# Finally, adding the suites for each of the GeoDjango test apps.
for app_name in self.geo_apps:
suite.addTest(build_suite(get_app(app_name)))
return suite
return geodjango_suite()

View File

@ -1,36 +0,0 @@
au_cities = (('Wollongong', 150.902, -34.4245),
('Shellharbour', 150.87, -34.5789),
('Thirroul', 150.924, -34.3147),
('Mittagong', 150.449, -34.4509),
('Batemans Bay', 150.175, -35.7082),
('Canberra', 144.963, -37.8143),
('Melbourne', 145.963, -37.8143),
('Sydney', 151.26071, -33.887034),
('Hobart', 147.33, -42.8827),
('Adelaide', 138.6, -34.9258),
('Hillsdale', 151.231341, -33.952685),
)
stx_cities = (('Downtown Houston', -95.363151, 29.763374),
('West University Place', -95.448601, 29.713803),
('Southside Place', -95.436920, 29.705777),
('Bellaire', -95.458732, 29.705614),
('Pearland', -95.287303, 29.563568),
('Galveston', -94.797489, 29.301336),
('Sealy', -96.156952, 29.780918),
('San Antonio', -98.493183, 29.424170),
('Saint Hedwig', -98.199820, 29.414197),
)
# Data from U.S. Census ZCTA cartographic boundary file for Texas (`zt48_d00.shp`).
stx_zips = (('77002', 'POLYGON ((-95.365015 29.772327, -95.362415 29.772327, -95.360915 29.771827, -95.354615 29.771827, -95.351515 29.772527, -95.350915 29.765327, -95.351015 29.762436, -95.350115 29.760328, -95.347515 29.758528, -95.352315 29.753928, -95.356415 29.756328, -95.358215 29.754028, -95.360215 29.756328, -95.363415 29.757128, -95.364014 29.75638, -95.363415 29.753928, -95.360015 29.751828, -95.361815 29.749528, -95.362715 29.750028, -95.367516 29.744128, -95.369316 29.745128, -95.373916 29.744128, -95.380116 29.738028, -95.387916 29.727929, -95.388516 29.729629, -95.387916 29.732129, -95.382916 29.737428, -95.376616 29.742228, -95.372616 29.747228, -95.378601 29.750846, -95.378616 29.752028, -95.378616 29.754428, -95.376016 29.754528, -95.374616 29.759828, -95.373616 29.761128, -95.371916 29.763928, -95.372316 29.768727, -95.365884 29.76791, -95.366015 29.767127, -95.358715 29.765327, -95.358615 29.766327, -95.359115 29.767227, -95.360215 29.767027, -95.362783 29.768267, -95.365315 29.770527, -95.365015 29.772327))'),
('77005', 'POLYGON ((-95.447918 29.727275, -95.428017 29.728729, -95.421117 29.729029, -95.418617 29.727629, -95.418517 29.726429, -95.402117 29.726629, -95.402117 29.725729, -95.395316 29.725729, -95.391916 29.726229, -95.389716 29.725829, -95.396517 29.715429, -95.397517 29.715929, -95.400917 29.711429, -95.411417 29.715029, -95.418417 29.714729, -95.418317 29.70623, -95.440818 29.70593, -95.445018 29.70683, -95.446618 29.70763, -95.447418 29.71003, -95.447918 29.727275))'),
('77025', 'POLYGON ((-95.418317 29.70623, -95.414717 29.706129, -95.414617 29.70533, -95.418217 29.70533, -95.419817 29.69533, -95.419484 29.694196, -95.417166 29.690901, -95.414517 29.69433, -95.413317 29.69263, -95.412617 29.68973, -95.412817 29.68753, -95.414087 29.685055, -95.419165 29.685428, -95.421617 29.68513, -95.425717 29.67983, -95.425017 29.67923, -95.424517 29.67763, -95.427418 29.67763, -95.438018 29.664631, -95.436713 29.664411, -95.440118 29.662231, -95.439218 29.661031, -95.437718 29.660131, -95.435718 29.659731, -95.431818 29.660331, -95.441418 29.656631, -95.441318 29.656331, -95.441818 29.656131, -95.441718 29.659031, -95.441118 29.661031, -95.446718 29.656431, -95.446518 29.673431, -95.446918 29.69013, -95.447418 29.71003, -95.446618 29.70763, -95.445018 29.70683, -95.440818 29.70593, -95.418317 29.70623))'),
('77401', 'POLYGON ((-95.447918 29.727275, -95.447418 29.71003, -95.446918 29.69013, -95.454318 29.68893, -95.475819 29.68903, -95.475819 29.69113, -95.484419 29.69103, -95.484519 29.69903, -95.480419 29.70133, -95.480419 29.69833, -95.474119 29.69833, -95.474119 29.70453, -95.472719 29.71283, -95.468019 29.71293, -95.468219 29.720229, -95.464018 29.720229, -95.464118 29.724529, -95.463018 29.725929, -95.459818 29.726129, -95.459918 29.720329, -95.451418 29.720429, -95.451775 29.726303, -95.451318 29.727029, -95.447918 29.727275))'),
)
interstates = (('I-25', 'LINESTRING(-104.4780170766108 36.66698791870694, -104.4468522338495 36.79925409393386, -104.46212692626 36.9372149776075, -104.5126119783768 37.08163268820887, -104.5247764602161 37.29300499892048, -104.7084397427668 37.49150259925398, -104.8126599016282 37.69514285621863, -104.8452887035466 37.87613395659479, -104.7160169341003 38.05951763337799, -104.6165437927668 38.30432045855106, -104.6437227858174 38.53979986564737, -104.7596170387259 38.7322907594295, -104.8380078676822 38.89998460604341, -104.8501253693506 39.09980189213358, -104.8791648316464 39.24368776457503, -104.8635041274215 39.3785278162751, -104.8894471170052 39.5929228239605, -104.9721242843344 39.69528482419685, -105.0112104500356 39.7273080432394, -105.0010368577104 39.76677607811571, -104.981835619 39.81466504121967, -104.9858891550477 39.88806911250832, -104.9873548059578 39.98117234571016, -104.9766220487419 40.09796423450692, -104.9818565932953 40.36056530662884, -104.9912746373997 40.74904484447656)'),
)
stx_interstates = (('I-10', 'LINESTRING(924952.5 4220931.6,925065.3 4220931.6,929568.4 4221057.8)'),
)

View File

@ -1,18 +1,17 @@
import os, unittest
import os
from decimal import Decimal
from django.db import connection
from django.db.models import Q
from django.contrib.gis.gdal import DataSource
from django.contrib.gis.geos import GEOSGeometry, Point, LineString
from django.contrib.gis.measure import D # alias for Distance
from django.contrib.gis.tests.utils import oracle, postgis, spatialite, no_oracle, no_spatialite
from django.test import TestCase
from models import AustraliaCity, Interstate, SouthTexasInterstate, \
SouthTexasCity, SouthTexasCityFt, CensusZipcode, SouthTexasZipcode
from data import au_cities, interstates, stx_interstates, stx_cities, stx_zips
class DistanceTest(unittest.TestCase):
class DistanceTest(TestCase):
# A point we are testing distances with -- using a WGS84
# coordinate that'll be implicitly transormed to that to
@ -28,37 +27,12 @@ class DistanceTest(unittest.TestCase):
return cities
def test01_init(self):
"Initialization of distance models."
# Loading up the cities.
def load_cities(city_model, data_tup):
for name, x, y in data_tup:
city_model(name=name, point=Point(x, y, srid=4326)).save()
def load_interstates(imodel, data_tup):
for name, wkt in data_tup:
imodel(name=name, path=wkt).save()
load_cities(SouthTexasCity, stx_cities)
load_cities(SouthTexasCityFt, stx_cities)
load_cities(AustraliaCity, au_cities)
"Test initialization of distance models."
self.assertEqual(9, SouthTexasCity.objects.count())
self.assertEqual(9, SouthTexasCityFt.objects.count())
self.assertEqual(11, AustraliaCity.objects.count())
# Loading up the South Texas Zip Codes.
for name, wkt in stx_zips:
poly = GEOSGeometry(wkt, srid=4269)
SouthTexasZipcode(name=name, poly=poly).save()
CensusZipcode(name=name, poly=poly).save()
self.assertEqual(4, SouthTexasZipcode.objects.count())
self.assertEqual(4, CensusZipcode.objects.count())
# Loading up the Interstates.
load_interstates(Interstate, interstates)
load_interstates(SouthTexasInterstate, stx_interstates)
self.assertEqual(1, Interstate.objects.count())
self.assertEqual(1, SouthTexasInterstate.objects.count())
@ -382,8 +356,3 @@ class DistanceTest(unittest.TestCase):
z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212')
self.assertEqual(None, z.distance)
self.assertEqual(None, z.area)
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(DistanceTest))
return s

View File

@ -1,4 +1,6 @@
import os, re, unittest
import os
import re
from django.utils.unittest import TestCase
from django.contrib.gis.db.models import Union, Extent3D
from django.contrib.gis.geos import GEOSGeometry, Point, Polygon
from django.contrib.gis.utils import LayerMapping, LayerMapError
@ -49,7 +51,7 @@ def gen_bbox():
bbox_3d = Polygon(tuple((x, y, z) for (x, y), z in zip(bbox_2d[0].coords, bbox_z)), srid=32140)
return bbox_2d, bbox_3d
class Geo3DTest(unittest.TestCase):
class Geo3DTest(TestCase):
"""
Only a subset of the PostGIS routines are 3D-enabled, and this TestCase
tries to test the features that can handle 3D and that are also
@ -227,8 +229,3 @@ class Geo3DTest(unittest.TestCase):
for ztrans in ztranslations:
for city in City3D.objects.translate(0, 0, ztrans):
self.assertEqual(city_dict[city.name][2] + ztrans, city.translate.z)
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(Geo3DTest))
return s

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,12 @@
import unittest
from xml.dom import minidom
from django.test import TestCase
from django.test import Client
from models import City
class GeoFeedTest(unittest.TestCase):
client = Client()
class GeoFeedTest(TestCase):
urls = 'django.contrib.gis.tests.geoapp.urls'
def assertChildNodes(self, elem, expected):
"Taken from regressiontests/syndication/tests.py."
@ -16,9 +17,9 @@ class GeoFeedTest(unittest.TestCase):
def test_geofeed_rss(self):
"Tests geographic feeds using GeoRSS over RSSv2."
# Uses `GEOSGeometry` in `item_geometry`
doc1 = minidom.parseString(self.client.get('/geoapp/feeds/rss1/').content)
doc1 = minidom.parseString(self.client.get('/feeds/rss1/').content)
# Uses a 2-tuple in `item_geometry`
doc2 = minidom.parseString(self.client.get('/geoapp/feeds/rss2/').content)
doc2 = minidom.parseString(self.client.get('/feeds/rss2/').content)
feed1, feed2 = doc1.firstChild, doc2.firstChild
# Making sure the box got added to the second GeoRSS feed.
@ -41,8 +42,8 @@ class GeoFeedTest(unittest.TestCase):
def test_geofeed_atom(self):
"Testing geographic feeds using GeoRSS over Atom."
doc1 = minidom.parseString(self.client.get('/geoapp/feeds/atom1/').content)
doc2 = minidom.parseString(self.client.get('/geoapp/feeds/atom2/').content)
doc1 = minidom.parseString(self.client.get('/feeds/atom1/').content)
doc2 = minidom.parseString(self.client.get('/feeds/atom2/').content)
feed1, feed2 = doc1.firstChild, doc2.firstChild
# Making sure the box got added to the second GeoRSS feed.
@ -60,7 +61,7 @@ class GeoFeedTest(unittest.TestCase):
def test_geofeed_w3c(self):
"Testing geographic feeds using W3C Geo."
doc = minidom.parseString(self.client.get('/geoapp/feeds/w3cgeo1/').content)
doc = minidom.parseString(self.client.get('/feeds/w3cgeo1/').content)
feed = doc.firstChild
# Ensuring the geo namespace was added to the <feed> element.
self.assertEqual(feed.getAttribute(u'xmlns:geo'), u'http://www.w3.org/2003/01/geo/wgs84_pos#')
@ -73,5 +74,5 @@ class GeoFeedTest(unittest.TestCase):
self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'geo:lat', 'geo:lon'])
# Boxes and Polygons aren't allowed in W3C Geo feeds.
self.assertRaises(ValueError, self.client.get, '/geoapp/feeds/w3cgeo2/') # Box in <channel>
self.assertRaises(ValueError, self.client.get, '/geoapp/feeds/w3cgeo3/') # Polygons in <entry>
self.assertRaises(ValueError, self.client.get, '/feeds/w3cgeo2/') # Box in <channel>
self.assertRaises(ValueError, self.client.get, '/feeds/w3cgeo3/') # Polygons in <entry>

View File

@ -1,11 +1,14 @@
import unittest, zipfile, cStringIO
import cStringIO
from xml.dom import minidom
import zipfile
from django.test import TestCase
from django.test import Client
from models import City, Country
class GeoSitemapTest(unittest.TestCase):
client = Client()
class GeoSitemapTest(TestCase):
urls = 'django.contrib.gis.tests.geoapp.urls'
def assertChildNodes(self, elem, expected):
"Taken from regressiontests/syndication/tests.py."
@ -16,7 +19,7 @@ class GeoSitemapTest(unittest.TestCase):
def test_geositemap_index(self):
"Tests geographic sitemap index."
# Getting the geo index.
doc = minidom.parseString(self.client.get('/geoapp/sitemap.xml').content)
doc = minidom.parseString(self.client.get('/sitemap.xml').content)
index = doc.firstChild
self.assertEqual(index.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9')
self.assertEqual(3, len(index.getElementsByTagName('sitemap')))
@ -24,13 +27,13 @@ class GeoSitemapTest(unittest.TestCase):
def test_geositemap_kml(self):
"Tests KML/KMZ geographic sitemaps."
for kml_type in ('kml', 'kmz'):
doc = minidom.parseString(self.client.get('/geoapp/sitemaps/%s.xml' % kml_type).content)
doc = minidom.parseString(self.client.get('/sitemaps/%s.xml' % kml_type).content)
# Ensuring the right sitemaps namespaces are present.
urlset = doc.firstChild
self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9')
self.assertEqual(urlset.getAttribute(u'xmlns:geo'), u'http://www.google.com/geo/schemas/sitemap/1.0')
urls = urlset.getElementsByTagName('url')
self.assertEqual(2, len(urls)) # Should only be 2 sitemaps.
for url in urls:
@ -42,7 +45,7 @@ class GeoSitemapTest(unittest.TestCase):
# Getting the relative URL since we don't have a real site.
kml_url = url.getElementsByTagName('loc')[0].childNodes[0].data.split('http://example.com')[1]
if kml_type == 'kml':
kml_doc = minidom.parseString(self.client.get(kml_url).content)
elif kml_type == 'kmz':
@ -52,7 +55,7 @@ class GeoSitemapTest(unittest.TestCase):
self.assertEqual(1, len(zf.filelist))
self.assertEqual('doc.kml', zf.filelist[0].filename)
kml_doc = minidom.parseString(zf.read('doc.kml'))
# Ensuring the correct number of placemarks are in the KML doc.
if 'city' in kml_url:
model = City
@ -64,8 +67,8 @@ class GeoSitemapTest(unittest.TestCase):
"Tests GeoRSS geographic sitemaps."
from feeds import feed_dict
doc = minidom.parseString(self.client.get('/geoapp/sitemaps/georss.xml').content)
doc = minidom.parseString(self.client.get('/sitemaps/georss.xml').content)
# Ensuring the right sitemaps namespaces are present.
urlset = doc.firstChild
self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9')

View File

@ -1,10 +1,11 @@
import re, os, unittest
import re
from django.db import connection
from django.contrib.gis import gdal
from django.contrib.gis.geos import *
from django.contrib.gis.geos import fromstr, GEOSGeometry, \
Point, LineString, LinearRing, Polygon, GeometryCollection
from django.contrib.gis.measure import Distance
from django.contrib.gis.tests.utils import \
no_mysql, no_oracle, no_postgis, no_spatialite, \
no_mysql, no_oracle, no_spatialite, \
mysql, oracle, postgis, spatialite
from django.test import TestCase
@ -732,11 +733,3 @@ class GeoModelTest(TestCase):
from test_feeds import GeoFeedTest
from test_regress import GeoRegressionTests
from test_sitemaps import GeoSitemapTest
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(GeoModelTest))
s.addTest(unittest.makeSuite(GeoFeedTest))
s.addTest(unittest.makeSuite(GeoSitemapTest))
s.addTest(unittest.makeSuite(GeoRegressionTests))
return s

View File

@ -10,7 +10,7 @@ from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, I
from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping
shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data'))
shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data'))
city_shp = os.path.join(shp_path, 'cities', 'cities.shp')
co_shp = os.path.join(shp_path, 'counties', 'counties.shp')
inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp')
@ -265,8 +265,4 @@ class LayerMapTest(unittest.TestCase):
self.assertEqual(6, ICity1.objects.count())
self.assertEqual(3, ICity2.objects.count())
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(LayerMapTest))
return s

View File

@ -1,23 +1,13 @@
import os, unittest
from django.contrib.gis.geos import *
from django.test import TestCase
from django.contrib.gis.geos import GEOSGeometry, Point, MultiPoint
from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
from django.contrib.gis.geometry.backend import Geometry
from django.contrib.gis.tests.utils import mysql, oracle, postgis, spatialite, no_mysql, no_oracle, no_spatialite
from django.conf import settings
from django.contrib.gis.tests.utils import mysql, oracle, no_mysql, no_oracle, no_spatialite
from models import City, Location, DirectoryEntry, Parcel, Book, Author, Article
cities = (('Aurora', 'TX', -97.516111, 33.058333),
('Roswell', 'NM', -104.528056, 33.387222),
('Kecksburg', 'PA', -79.460734, 40.18476),
)
class RelatedGeoModelTest(unittest.TestCase):
def test01_setup(self):
"Setting up for related model tests."
for name, state, lon, lat in cities:
loc = Location.objects.create(point=Point(lon, lat))
c = City.objects.create(name=name, state=state, location=loc)
class RelatedGeoModelTest(TestCase):
def test02_select_related(self):
"Testing `select_related` on geographic models (see #7126)."
@ -25,6 +15,13 @@ class RelatedGeoModelTest(unittest.TestCase):
qs2 = City.objects.select_related()
qs3 = City.objects.select_related('location')
# Reference data for what's in the fixtures.
cities = (
('Aurora', 'TX', -97.516111, 33.058333),
('Roswell', 'NM', -104.528056, 33.387222),
('Kecksburg', 'PA', -79.460734, 40.18476),
)
for qs in (qs1, qs2, qs3):
for ref, c in zip(cities, qs):
nm, st, lon, lat = ref
@ -63,11 +60,11 @@ class RelatedGeoModelTest(unittest.TestCase):
# This combines the Extent and Union aggregates into one query
aggs = City.objects.aggregate(Extent('location__point'))
# One for all locations, one that excludes Roswell.
all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
# One for all locations, one that excludes New Mexico (Roswell).
all_extent = (-104.528056, 29.763374, -79.460734, 40.18476)
txpa_extent = (-97.516111, 29.763374, -79.460734, 40.18476)
e1 = City.objects.extent(field_name='location__point')
e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
e2 = City.objects.exclude(state='NM').extent(field_name='location__point')
e3 = aggs['location__point__extent']
# The tolerance value is to four decimal places because of differences
@ -83,10 +80,12 @@ class RelatedGeoModelTest(unittest.TestCase):
aggs = City.objects.aggregate(Union('location__point'))
# These are the points that are components of the aggregate geographic
# union that is returned.
# union that is returned. Each point # corresponds to City PK.
p1 = Point(-104.528056, 33.387222)
p2 = Point(-97.516111, 33.058333)
p3 = Point(-79.460734, 40.18476)
p4 = Point(-96.801611, 32.782057)
p5 = Point(-95.363151, 29.763374)
# Creating the reference union geometry depending on the spatial backend,
# as Oracle will have a different internal ordering of the component
@ -94,14 +93,15 @@ class RelatedGeoModelTest(unittest.TestCase):
# query that includes limiting information in the WHERE clause (in other
# words a `.filter()` precedes the call to `.unionagg()`).
if oracle:
ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
ref_u1 = MultiPoint(p4, p5, p3, p1, p2, srid=4326)
ref_u2 = MultiPoint(p3, p2, srid=4326)
else:
ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
# Looks like PostGIS points by longitude value.
ref_u1 = MultiPoint(p1, p2, p4, p5, p3, srid=4326)
ref_u2 = MultiPoint(p2, p3, srid=4326)
u1 = City.objects.unionagg(field_name='location__point')
u2 = City.objects.exclude(name='Roswell').unionagg(field_name='location__point')
u2 = City.objects.exclude(name__in=('Roswell', 'Houston', 'Dallas', 'Fort Worth')).unionagg(field_name='location__point')
u3 = aggs['location__point__union']
self.assertEqual(ref_u1, u1)
@ -187,17 +187,10 @@ class RelatedGeoModelTest(unittest.TestCase):
def test09_pk_relations(self):
"Ensuring correct primary key column is selected across relations. See #10757."
# Adding two more cities, but this time making sure that their location
# ID values do not match their City ID values.
loc1 = Location.objects.create(point='POINT (-95.363151 29.763374)')
loc2 = Location.objects.create(point='POINT (-96.801611 32.782057)')
dallas = City.objects.create(name='Dallas', state='TX', location=loc2)
houston = City.objects.create(name='Houston', state='TX', location=loc1)
# The expected ID values -- notice the last two location IDs
# are out of order. We want to make sure that the related
# location ID column is selected instead of ID column for
# the city.
# are out of order. Dallas and Houston have location IDs that differ
# from their PKs -- this is done to ensure that the related location
# ID column is selected instead of ID column for the city.
city_ids = (1, 2, 3, 4, 5)
loc_ids = (1, 2, 3, 5, 4)
ids_qs = City.objects.order_by('id').values('id', 'location__id')
@ -232,10 +225,8 @@ class RelatedGeoModelTest(unittest.TestCase):
@no_oracle
def test12a_count(self):
"Testing `Count` aggregate use with the `GeoManager` on geo-fields."
# Creating a new City, 'Fort Worth', that uses the same location
# as Dallas.
# The City, 'Fort Worth' uses the same location as Dallas.
dallas = City.objects.get(name='Dallas')
ftworth = City.objects.create(name='Fort Worth', state='TX', location=dallas.location)
# Count annotation should be 2 for the Dallas location now.
loc = Location.objects.annotate(num_cities=Count('city')).get(id=dallas.location.id)
@ -243,18 +234,9 @@ class RelatedGeoModelTest(unittest.TestCase):
def test12b_count(self):
"Testing `Count` aggregate use with the `GeoManager` on non geo-fields. See #11087."
# Creating some data for the Book/Author non-geo models that
# use GeoManager. See #11087.
tp = Author.objects.create(name='Trevor Paglen')
Book.objects.create(title='Torture Taxi', author=tp)
Book.objects.create(title='I Could Tell You But Then You Would Have to be Destroyed by Me', author=tp)
Book.objects.create(title='Blank Spots on the Map', author=tp)
wp = Author.objects.create(name='William Patry')
Book.objects.create(title='Patry on Copyright', author=wp)
# Should only be one author (Trevor Paglen) returned by this query, and
# the annotation should have 3 for the number of books. Also testing
# with a `GeoValuesQuerySet` (see #11489).
# the annotation should have 3 for the number of books, see #11087.
# Also testing with a `GeoValuesQuerySet`, see #11489.
qs = Author.objects.annotate(num_books=Count('books')).filter(num_books__gt=1)
vqs = Author.objects.values('name').annotate(num_books=Count('books')).filter(num_books__gt=1)
self.assertEqual(1, len(qs))
@ -280,7 +262,7 @@ class RelatedGeoModelTest(unittest.TestCase):
# SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN
# "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
# WHERE "relatedapp_city"."state" = 'TX';
ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
ref_geom = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
c1 = City.objects.filter(state='TX').collect(field_name='location__point')
c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
@ -298,10 +280,5 @@ class RelatedGeoModelTest(unittest.TestCase):
# keyword. The TypeError is swallowed if QuerySet is actually
# evaluated as list generation swallows TypeError in CPython.
sql = str(qs.query)
# TODO: Related tests for KML, GML, and distance lookups.
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(RelatedGeoModelTest))
return s
# TODO: Related tests for KML, GML, and distance lookups.

View File

@ -1,6 +0,0 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^geoapp/', include('django.contrib.gis.tests.geoapp.urls')),
)