1
0
mirror of https://github.com/django/django.git synced 2025-07-05 02:09:13 +00:00

[gsoc2009-testing] Merging from trunk. Favoring my index.txt with windmill howto

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/test-improvements@11146 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Kevin Kubasik 2009-07-01 22:27:37 +00:00
commit e43283d70b
18 changed files with 83 additions and 37 deletions

View File

@ -214,6 +214,22 @@ def model_detail(request, app_label, model_name):
'help_text': field.help_text, 'help_text': field.help_text,
}) })
# Gather many-to-many fields.
for field in opts.many_to_many:
data_type = related_object_name = field.rel.to.__name__
app_label = field.rel.to._meta.app_label
verbose = _("related `%(app_label)s.%(object_name)s` objects") % {'app_label': app_label, 'object_name': data_type}
fields.append({
'name': "%s.all" % field.name,
"data_type": 'List',
'verbose': utils.parse_rst(_("all %s") % verbose , 'model', _('model:') + opts.module_name),
})
fields.append({
'name' : "%s.count" % field.name,
'data_type' : 'Integer',
'verbose' : utils.parse_rst(_("number of %s") % verbose , 'model', _('model:') + opts.module_name),
})
# Gather model methods. # Gather model methods.
for func_name, func in model.__dict__.items(): for func_name, func in model.__dict__.items():
if (inspect.isfunction(func) and len(inspect.getargspec(func)[0]) == 1): if (inspect.isfunction(func) and len(inspect.getargspec(func)[0]) == 1):
@ -233,7 +249,7 @@ def model_detail(request, app_label, model_name):
}) })
# Gather related objects # Gather related objects
for rel in opts.get_all_related_objects(): for rel in opts.get_all_related_objects() + opts.get_all_related_many_to_many_objects():
verbose = _("related `%(app_label)s.%(object_name)s` objects") % {'app_label': rel.opts.app_label, 'object_name': rel.opts.object_name} verbose = _("related `%(app_label)s.%(object_name)s` objects") % {'app_label': rel.opts.app_label, 'object_name': rel.opts.object_name}
accessor = rel.get_accessor_name() accessor = rel.get_accessor_name()
fields.append({ fields.append({

View File

@ -32,7 +32,7 @@ class GeoModelAdmin(ModelAdmin):
map_height = 400 map_height = 400
map_srid = 4326 map_srid = 4326
map_template = 'gis/admin/openlayers.html' map_template = 'gis/admin/openlayers.html'
openlayers_url = 'http://openlayers.org/api/2.7/OpenLayers.js' openlayers_url = 'http://openlayers.org/api/2.8/OpenLayers.js'
point_zoom = num_zoom - 6 point_zoom = num_zoom - 6
wms_url = 'http://labs.metacarta.com/wms/vmap0' wms_url = 'http://labs.metacarta.com/wms/vmap0'
wms_layer = 'basic' wms_layer = 'basic'

View File

@ -225,7 +225,7 @@ class GeoQuery(sql.Query):
values.append(self.convert_values(value, field)) values.append(self.convert_values(value, field))
else: else:
values.extend(row[index_start:]) values.extend(row[index_start:])
return values return tuple(values)
def convert_values(self, value, field): def convert_values(self, value, field):
""" """

View File

@ -21,7 +21,7 @@ class GoogleMap(object):
def __init__(self, key=None, api_url=None, version=None, def __init__(self, key=None, api_url=None, version=None,
center=None, zoom=None, dom_id='map', center=None, zoom=None, dom_id='map',
kml_urls=[], polylines=None, polygons=None, markers=None, kml_urls=[], polylines=None, polygons=None, markers=None,
template='gis/google/google-single.js', template='gis/google/google-map.js',
js_module='geodjango', js_module='geodjango',
extra_context={}): extra_context={}):
@ -162,7 +162,7 @@ class GoogleMapSet(GoogleMap):
# This is the template used to generate the GMap load JavaScript for # This is the template used to generate the GMap load JavaScript for
# each map in the set. # each map in the set.
self.map_template = kwargs.pop('map_template', 'gis/google/google-map.js') self.map_template = kwargs.pop('map_template', 'gis/google/google-single.js')
# Running GoogleMap.__init__(), and resetting the template # Running GoogleMap.__init__(), and resetting the template
# value with default obtained above. # value with default obtained above.

View File

@ -1,7 +0,0 @@
{% block vars %}var geodjango = {};{% for icon in icons %}
var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
{% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
{% if icon.iconanchor %}{{ icon.varname }}.iconAnchor = new GPoint({{ icon.iconanchor.0 }}, {{ icon.iconanchor.1 }});{% endif %} {% if icon.iconsize %}{{ icon.varname }}.iconSize = new GSize({{ icon.iconsize.0 }}, {{ icon.iconsize.1 }});{% endif %}
{% if icon.infowindowanchor %}{{ icon.varname }}.infoWindowAnchor = new GPoint({{ icon.infowindowanchor.0 }}, {{ icon.infowindowanchor.1 }});{% endif %}{% endfor %}{% endblock %}
{% block functions %}{% endblock %}

View File

@ -1,10 +1,16 @@
{% autoescape off %} {% autoescape off %}
{% block vars %}var geodjango = {};{% for icon in icons %}
var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
{% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
{% if icon.iconanchor %}{{ icon.varname }}.iconAnchor = new GPoint({{ icon.iconanchor.0 }}, {{ icon.iconanchor.1 }});{% endif %} {% if icon.iconsize %}{{ icon.varname }}.iconSize = new GSize({{ icon.iconsize.0 }}, {{ icon.iconsize.1 }});{% endif %}
{% if icon.infowindowanchor %}{{ icon.varname }}.infoWindowAnchor = new GPoint({{ icon.infowindowanchor.0 }}, {{ icon.infowindowanchor.1 }});{% endif %}{% endfor %}
{% endblock vars %}{% block functions %}
{% block load %}{{ js_module }}.{{ dom_id }}_load = function(){ {% block load %}{{ js_module }}.{{ dom_id }}_load = function(){
if (GBrowserIsCompatible()) { if (GBrowserIsCompatible()) {
{{ js_module }}.{{ dom_id }} = new GMap2(document.getElementById("{{ dom_id }}")); {{ js_module }}.{{ dom_id }} = new GMap2(document.getElementById("{{ dom_id }}"));
{{ js_module }}.{{ dom_id }}.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }}); {{ js_module }}.{{ dom_id }}.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }});
{% block controls %}{{ js_module }}.{{ dom_id }}.addControl(new GSmallMapControl()); {% block controls %}{{ js_module }}.{{ dom_id }}.setUIToDefault();{% endblock %}
{{ js_module }}.{{ dom_id }}.addControl(new GMapTypeControl());{% endblock %}
{% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %} {% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %}
{% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}"); {% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}");
{{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }});{% endfor %} {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }});{% endfor %}
@ -26,4 +32,4 @@
alert("Sorry, the Google Maps API is not compatible with this browser."); alert("Sorry, the Google Maps API is not compatible with this browser.");
} }
} }
{% endblock %}{% endautoescape %} {% endblock load %}{% endblock functions %}{% endautoescape %}

View File

@ -1,4 +1,4 @@
{% extends "gis/google/google-base.js" %} {% extends "gis/google/google-map.js" %}
{% block functions %} {% block functions %}
{{ load_map_js }} {{ load_map_js }}
{{ js_module }}.load = function(){ {{ js_module }}.load = function(){

View File

@ -1,2 +1,2 @@
{% extends "gis/google/google-base.js" %} {% extends "gis/google/google-map.js" %}
{% block functions %}{% include "gis/google/google-map.js" %}{% endblock %} {% block vars %}{# No vars here because used within GoogleMapSet #}{% endblock %}

View File

@ -40,5 +40,5 @@ class Author(models.Model):
class Book(models.Model): class Book(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
author = models.ForeignKey(Author, related_name='books') author = models.ForeignKey(Author, related_name='books', null=True)
objects = models.GeoManager() objects = models.GeoManager()

View File

@ -257,6 +257,13 @@ class RelatedGeoModelTest(unittest.TestCase):
self.assertEqual(1, len(qs)) self.assertEqual(1, len(qs))
self.assertEqual(3, qs[0].num_books) self.assertEqual(3, qs[0].num_books)
def test13_select_related_null_fk(self):
"Testing `select_related` on a nullable ForeignKey via `GeoManager`. See #11381."
no_author = Book.objects.create(title='Without Author')
b = Book.objects.select_related('author').get(title='Without Author')
# Should be `None`, and not a 'dummy' model.
self.assertEqual(None, b.author)
# TODO: Related tests for KML, GML, and distance lookups. # TODO: Related tests for KML, GML, and distance lookups.
def suite(): def suite():

View File

@ -195,6 +195,7 @@ class RegexURLResolver(object):
return sub_match[0], sub_match[1], sub_match_dict return sub_match[0], sub_match[1], sub_match_dict
tried.append(pattern.regex.pattern) tried.append(pattern.regex.pattern)
raise Resolver404, {'tried': tried, 'path': new_path} raise Resolver404, {'tried': tried, 'path': new_path}
raise Resolver404, {'tried': [], 'path' : path}
def _get_urlconf_module(self): def _get_urlconf_module(self):
try: try:

View File

@ -20,3 +20,4 @@ API Reference
signals signals
templates/index templates/index
unicode unicode

View File

@ -14,6 +14,9 @@ class Reporter(models.Model):
last_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
email = models.EmailField() email = models.EmailField()
class Meta:
ordering = ('first_name', 'last_name')
def __unicode__(self): def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name) return u"%s %s" % (self.first_name, self.last_name)

View File

@ -13,4 +13,4 @@ class SectionTest(models.Model):
""" """
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
admin.site.register(SectionTest, save_as=True) #admin.site.register(SectionTest, save_as=True)

View File

@ -18,7 +18,7 @@ from models import Article, BarAccount, CustomArticle, EmptyModel, \
Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \ Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit
from test_models import SectionTest
try: try:
set set
@ -34,13 +34,23 @@ class AdminViewBasicTest(TestCase):
urlbit = 'admin' urlbit = 'admin'
def setUp(self): def setUp(self):
# from django.contrib import admin
# admin.register(TestSection)
from test_models import SectionTest
from django.contrib import admin from django.contrib import admin
admin.register(TestSection) admin.site.register(SectionTest)
import regressiontests.admin_views.urls
reload(regressiontests.admin_views.urls)
self.client.login(username='super', password='secret') self.client.login(username='super', password='secret')
def tearDown(self): def tearDown(self):
# from django.contrib import admin
# admin.unregister(TestSection)
from test_models import SectionTest
from django.contrib import admin from django.contrib import admin
admin.unregister(TestSection) admin.site.unregister(SectionTest)
import regressiontests.admin_views.urls
reload(regressiontests.admin_views.urls)
self.client.logout() self.client.logout()
def testTrailingSlashRequired(self): def testTrailingSlashRequired(self):
@ -308,6 +318,7 @@ class CustomModelAdminTest(AdminViewBasicTest):
""" """
response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit) response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit)
self.failUnlessEqual(response.status_code, 200) self.failUnlessEqual(response.status_code, 200)
def testAddWithGETArgsTestModel(self): def testAddWithGETArgsTestModel(self):
response = self.client.get('/test_admin/%s/admin_views/sectiontest/add/' % self.urlbit, {'name': 'My TestSection'}) response = self.client.get('/test_admin/%s/admin_views/sectiontest/add/' % self.urlbit, {'name': 'My TestSection'})
self.failUnlessEqual(response.status_code, 404) self.failUnlessEqual(response.status_code, 404)
@ -624,17 +635,6 @@ class AdminViewStringPrimaryKeyTest(TestCase):
def tearDown(self): def tearDown(self):
self.client.logout() self.client.logout()
def testBasicAddGetTest(self):
"""
A smoke test to ensure GET on the add_view works.
"""
from django.contrib import admin
admin.site.unregister(SectionTest)
import regressiontests.admin_views.urls
reload(regressiontests.admin_views.urls)
response = self.client.get('/test_admin/admin/admin_views/sectiontest/add/')
self.failUnlessEqual(response.status_code, 404)
def test_get_change_view(self): def test_get_change_view(self):
"Retrieving the object using urlencoded form of primary key should work" "Retrieving the object using urlencoded form of primary key should work"
response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk)) response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk))

View File

@ -22,6 +22,9 @@ class Comment(models.Model):
post = models.ForeignKey(Post, null=True) post = models.ForeignKey(Post, null=True)
comment_text = models.CharField(max_length=250) comment_text = models.CharField(max_length=250)
class Meta:
ordering = ('comment_text',)
def __unicode__(self): def __unicode__(self):
return self.comment_text return self.comment_text

View File

@ -103,7 +103,7 @@ def data_compare(testcase, pk, klass, data):
def generic_compare(testcase, pk, klass, data): def generic_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)
testcase.assertEqual(data[0], instance.data) testcase.assertEqual(data[0], instance.data)
testcase.assertEqual(data[1:], [t.data for t in instance.tags.all()]) testcase.assertEqual(data[1:], [t.data for t in instance.tags.order_by('id')])
def fk_compare(testcase, pk, klass, data): def fk_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)
@ -111,7 +111,7 @@ def fk_compare(testcase, pk, klass, data):
def m2m_compare(testcase, pk, klass, data): def m2m_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)
testcase.assertEqual(data, [obj.id for obj in instance.data.all()]) testcase.assertEqual(data, [obj.id for obj in instance.data.order_by('id')])
def im2m_compare(testcase, pk, klass, data): def im2m_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk) instance = klass.objects.get(id=pk)

View File

@ -14,8 +14,9 @@ Traceback (most recent call last):
ImproperlyConfigured: The included urlconf regressiontests.urlpatterns_reverse.no_urls doesn't have any patterns in it ImproperlyConfigured: The included urlconf regressiontests.urlpatterns_reverse.no_urls doesn't have any patterns in it
"""} """}
import unittest
from django.core.urlresolvers import reverse, NoReverseMatch from django.core.urlresolvers import reverse, resolve, NoReverseMatch, Resolver404
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
from django.shortcuts import redirect from django.shortcuts import redirect
from django.test import TestCase from django.test import TestCase
@ -112,6 +113,21 @@ class URLPatternReverse(TestCase):
else: else:
self.assertEquals(got, expected) self.assertEquals(got, expected)
class ResolverTests(unittest.TestCase):
def test_non_regex(self):
"""
Verifies that we raise a Resolver404 if what we are resolving doesn't
meet the basic requirements of a path to match - i.e., at the very
least, it matches the root pattern '^/'. We must never return None
from resolve, or we will get a TypeError further down the line.
Regression for #10834.
"""
self.assertRaises(Resolver404, resolve, '')
self.assertRaises(Resolver404, resolve, 'a')
self.assertRaises(Resolver404, resolve, '\\')
self.assertRaises(Resolver404, resolve, '.')
class ReverseShortcutTests(TestCase): class ReverseShortcutTests(TestCase):
urls = 'regressiontests.urlpatterns_reverse.urls' urls = 'regressiontests.urlpatterns_reverse.urls'