summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMarc Garcia <garcia.marc@gmail.com>2009-07-01 23:33:02 +0000
committerMarc Garcia <garcia.marc@gmail.com>2009-07-01 23:33:02 +0000
commitf5095f8cb367e51e18e084ac118d6900ab9ba735 (patch)
tree58baa1119dead8fbb2a0d98af8f70cca0d55ef09 /tests
parent87cd3dfa55770e5a987d43797c013d81530083db (diff)
[soc2009/i18n] merged up to trunk r11147
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/i18n-improvements@11148 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/modeltests/custom_pk/fields.py54
-rw-r--r--tests/modeltests/custom_pk/models.py30
-rw-r--r--tests/modeltests/proxy_models/fixtures/mypeople.json9
-rw-r--r--tests/modeltests/proxy_models/models.py43
-rw-r--r--tests/modeltests/transactions/models.py3
-rw-r--r--tests/regressiontests/fixtures_regress/models.py9
-rw-r--r--tests/regressiontests/m2m_regress/models.py14
-rw-r--r--tests/regressiontests/mail/tests.py46
-rw-r--r--tests/regressiontests/null_fk/models.py3
-rw-r--r--tests/regressiontests/one_to_one_regress/tests.py22
-rw-r--r--tests/regressiontests/queries/models.py3
-rw-r--r--tests/regressiontests/serializers_regress/tests.py4
-rw-r--r--tests/regressiontests/templates/tests.py7
-rw-r--r--tests/regressiontests/urlpatterns_reverse/tests.py18
14 files changed, 258 insertions, 7 deletions
diff --git a/tests/modeltests/custom_pk/fields.py b/tests/modeltests/custom_pk/fields.py
new file mode 100644
index 0000000000..319e42f974
--- /dev/null
+++ b/tests/modeltests/custom_pk/fields.py
@@ -0,0 +1,54 @@
+import random
+import string
+
+from django.db import models
+
+class MyWrapper(object):
+ def __init__(self, value):
+ self.value = value
+
+ def __repr__(self):
+ return "<%s: %s>" % (self.__class__.__name__, self.value)
+
+ def __unicode__(self):
+ return self.value
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.value == other.value
+ return self.value == other
+
+class MyAutoField(models.CharField):
+ __metaclass__ = models.SubfieldBase
+
+ def __init__(self, *args, **kwargs):
+ kwargs['max_length'] = 10
+ super(MyAutoField, self).__init__(*args, **kwargs)
+
+ def pre_save(self, instance, add):
+ value = getattr(instance, self.attname, None)
+ if not value:
+ value = MyWrapper(''.join(random.sample(string.lowercase, 10)))
+ setattr(instance, self.attname, value)
+ return value
+
+ def to_python(self, value):
+ if not value:
+ return
+ if not isinstance(value, MyWrapper):
+ value = MyWrapper(value)
+ return value
+
+ def get_db_prep_save(self, value):
+ if not value:
+ return
+ if isinstance(value, MyWrapper):
+ return unicode(value)
+ return value
+
+ def get_db_prep_value(self, value):
+ if not value:
+ return
+ if isinstance(value, MyWrapper):
+ return unicode(value)
+ return value
diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py
index 091f7f32b4..b88af16782 100644
--- a/tests/modeltests/custom_pk/models.py
+++ b/tests/modeltests/custom_pk/models.py
@@ -9,6 +9,8 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
from django.conf import settings
from django.db import models, transaction, IntegrityError
+from fields import MyAutoField
+
class Employee(models.Model):
employee_code = models.IntegerField(primary_key=True, db_column = 'code')
first_name = models.CharField(max_length=20)
@@ -28,6 +30,16 @@ class Business(models.Model):
def __unicode__(self):
return self.name
+class Bar(models.Model):
+ id = MyAutoField(primary_key=True, db_index=True)
+
+ def __unicode__(self):
+ return repr(self.pk)
+
+
+class Foo(models.Model):
+ bar = models.ForeignKey(Bar)
+
__test__ = {'API_TESTS':"""
>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
>>> dan.save()
@@ -121,6 +133,24 @@ DoesNotExist: Employee matching query does not exist.
... print "Fail with %s" % type(e)
Pass
+# Regression for #10785 -- Custom fields can be used for primary keys.
+>>> new_bar = Bar.objects.create()
+>>> new_foo = Foo.objects.create(bar=new_bar)
+
+# FIXME: This still doesn't work, but will require some changes in
+# get_db_prep_lookup to fix it.
+# >>> f = Foo.objects.get(bar=new_bar.pk)
+# >>> f == new_foo
+# True
+# >>> f.bar == new_bar
+# True
+
+>>> f = Foo.objects.get(bar=new_bar)
+>>> f == new_foo
+True
+>>> f.bar == new_bar
+True
+
"""}
# SQLite lets objects be saved with an empty primary key, even though an
diff --git a/tests/modeltests/proxy_models/fixtures/mypeople.json b/tests/modeltests/proxy_models/fixtures/mypeople.json
new file mode 100644
index 0000000000..d20c8f2a6e
--- /dev/null
+++ b/tests/modeltests/proxy_models/fixtures/mypeople.json
@@ -0,0 +1,9 @@
+[
+ {
+ "pk": 100,
+ "model": "proxy_models.myperson",
+ "fields": {
+ "name": "Elvis Presley"
+ }
+ }
+] \ No newline at end of file
diff --git a/tests/modeltests/proxy_models/models.py b/tests/modeltests/proxy_models/models.py
index 4b3f7d925d..e38266fb70 100644
--- a/tests/modeltests/proxy_models/models.py
+++ b/tests/modeltests/proxy_models/models.py
@@ -259,6 +259,40 @@ FieldError: Proxy model 'NoNewFields' contains model fields.
>>> OtherPerson._default_manager.all()
[<OtherPerson: barney>, <OtherPerson: wilma>]
+# Test save signals for proxy models
+>>> from django.db.models import signals
+>>> def make_handler(model, event):
+... def _handler(*args, **kwargs):
+... print u"%s %s save" % (model, event)
+... return _handler
+>>> h1 = make_handler('MyPerson', 'pre')
+>>> h2 = make_handler('MyPerson', 'post')
+>>> h3 = make_handler('Person', 'pre')
+>>> h4 = make_handler('Person', 'post')
+>>> signals.pre_save.connect(h1, sender=MyPerson)
+>>> signals.post_save.connect(h2, sender=MyPerson)
+>>> signals.pre_save.connect(h3, sender=Person)
+>>> signals.post_save.connect(h4, sender=Person)
+>>> dino = MyPerson.objects.create(name=u"dino")
+MyPerson pre save
+MyPerson post save
+
+# Test save signals for proxy proxy models
+>>> h5 = make_handler('MyPersonProxy', 'pre')
+>>> h6 = make_handler('MyPersonProxy', 'post')
+>>> signals.pre_save.connect(h5, sender=MyPersonProxy)
+>>> signals.post_save.connect(h6, sender=MyPersonProxy)
+>>> dino = MyPersonProxy.objects.create(name=u"pebbles")
+MyPersonProxy pre save
+MyPersonProxy post save
+
+>>> signals.pre_save.disconnect(h1, sender=MyPerson)
+>>> signals.post_save.disconnect(h2, sender=MyPerson)
+>>> signals.pre_save.disconnect(h3, sender=Person)
+>>> signals.post_save.disconnect(h4, sender=Person)
+>>> signals.pre_save.disconnect(h5, sender=MyPersonProxy)
+>>> signals.post_save.disconnect(h6, sender=MyPersonProxy)
+
# A proxy has the same content type as the model it is proxying for (at the
# storage level, it is meant to be essentially indistinguishable).
>>> ctype = ContentType.objects.get_for_model
@@ -266,7 +300,7 @@ FieldError: Proxy model 'NoNewFields' contains model fields.
True
>>> MyPersonProxy.objects.all()
-[<MyPersonProxy: barney>, <MyPersonProxy: fred>]
+[<MyPersonProxy: barney>, <MyPersonProxy: dino>, <MyPersonProxy: fred>, <MyPersonProxy: pebbles>]
>>> u = User.objects.create(name='Bruce')
>>> User.objects.all()
@@ -327,4 +361,11 @@ True
# Select related + filter on a related proxy of proxy field
>>> ProxyImprovement.objects.select_related().get(associated_bug__summary__icontains='fix')
<ProxyImprovement: ProxyImprovement:improve that>
+
+Proxy models can be loaded from fixtures (Regression for #11194)
+>>> from django.core import management
+>>> management.call_command('loaddata', 'mypeople.json', verbosity=0)
+>>> MyPerson.objects.get(pk=100)
+<MyPerson: Elvis Presley>
+
"""}
diff --git a/tests/modeltests/transactions/models.py b/tests/modeltests/transactions/models.py
index 06d21bbdd4..6763144ca5 100644
--- a/tests/modeltests/transactions/models.py
+++ b/tests/modeltests/transactions/models.py
@@ -14,6 +14,9 @@ class Reporter(models.Model):
last_name = models.CharField(max_length=30)
email = models.EmailField()
+ class Meta:
+ ordering = ('first_name', 'last_name')
+
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py
index 621c80c15f..16a9fc4fc5 100644
--- a/tests/regressiontests/fixtures_regress/models.py
+++ b/tests/regressiontests/fixtures_regress/models.py
@@ -9,6 +9,9 @@ class Animal(models.Model):
count = models.IntegerField()
weight = models.FloatField()
+ # use a non-default name for the default manager
+ specimens = models.Manager()
+
def __unicode__(self):
return self.common_name
@@ -161,4 +164,10 @@ Weight = 1.2 (<type 'float'>)
>>> models.signals.pre_save.disconnect(animal_pre_save_check)
+###############################################
+# Regression for #11286 -- Ensure that dumpdata honors the default manager
+# Dump the current contents of the database as a JSON fixture
+>>> management.call_command('dumpdata', 'fixtures_regress.animal', format='json')
+[{"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, "weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}}, {"pk": 2, "model": "fixtures_regress.animal", "fields": {"count": 2, "weight": 2.29..., "name": "Platypus", "latin_name": "Ornithorhynchus anatinus"}}, {"pk": 10, "model": "fixtures_regress.animal", "fields": {"count": 42, "weight": 1.2, "name": "Emu", "latin_name": "Dromaius novaehollandiae"}}]
+
"""}
diff --git a/tests/regressiontests/m2m_regress/models.py b/tests/regressiontests/m2m_regress/models.py
index 5484b26d17..913e719902 100644
--- a/tests/regressiontests/m2m_regress/models.py
+++ b/tests/regressiontests/m2m_regress/models.py
@@ -33,6 +33,14 @@ class SelfReferChild(SelfRefer):
class SelfReferChildSibling(SelfRefer):
pass
+# Many-to-Many relation between models, where one of the PK's isn't an Autofield
+class Line(models.Model):
+ name = models.CharField(max_length=100)
+
+class Worksheet(models.Model):
+ id = models.CharField(primary_key=True, max_length=100)
+ lines = models.ManyToManyField(Line, blank=True, null=True)
+
__test__ = {"regressions": """
# Multiple m2m references to the same model or a different model must be
# distinguished when accessing the relations through an instance attribute.
@@ -79,5 +87,11 @@ FieldError: Cannot resolve keyword 'porcupine' into field. Choices are: id, name
>>> sr_sibling.related.all()
[<SelfRefer: Hanna>]
+# Regression for #11311 - The primary key for models in a m2m relation
+# doesn't have to be an AutoField
+>>> w = Worksheet(id='abc')
+>>> w.save()
+>>> w.delete()
+
"""
}
diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py
index 40e2f7665f..f4c416c231 100644
--- a/tests/regressiontests/mail/tests.py
+++ b/tests/regressiontests/mail/tests.py
@@ -4,7 +4,7 @@ r"""
>>> from django.conf import settings
>>> from django.core import mail
->>> from django.core.mail import EmailMessage, mail_admins, mail_managers
+>>> from django.core.mail import EmailMessage, mail_admins, mail_managers, EmailMultiAlternatives
>>> from django.utils.translation import ugettext_lazy
# Test normal ascii character case:
@@ -95,4 +95,48 @@ BadHeaderError: Header values can't contain newlines (got u'Subject\nInjection T
>>> message['From']
'from@example.com'
+# Handle attachments within an multipart/alternative mail correctly (#9367)
+# (test is not as precise/clear as it could be w.r.t. email tree structure,
+# but it's good enough.)
+
+>>> headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
+>>> subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
+>>> text_content = 'This is an important message.'
+>>> html_content = '<p>This is an <strong>important</strong> message.</p>'
+>>> msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers)
+>>> msg.attach_alternative(html_content, "text/html")
+>>> msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf")
+>>> print msg.message().as_string()
+Content-Type: multipart/mixed; boundary="..."
+MIME-Version: 1.0
+Subject: hello
+From: from@example.com
+To: to@example.com
+Date: Fri, 09 Nov 2001 01:08:47 -0000
+Message-ID: foo
+...
+Content-Type: multipart/alternative; boundary="..."
+MIME-Version: 1.0
+...
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: quoted-printable
+...
+This is an important message.
+...
+Content-Type: text/html; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: quoted-printable
+...
+<p>This is an <strong>important</strong> message.</p>
+...
+...
+Content-Type: application/pdf
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="an attachment.pdf"
+...
+JVBERi0xLjQuJS4uLg==
+...
+
"""
diff --git a/tests/regressiontests/null_fk/models.py b/tests/regressiontests/null_fk/models.py
index 529dde5039..49887819ac 100644
--- a/tests/regressiontests/null_fk/models.py
+++ b/tests/regressiontests/null_fk/models.py
@@ -22,6 +22,9 @@ class Comment(models.Model):
post = models.ForeignKey(Post, null=True)
comment_text = models.CharField(max_length=250)
+ class Meta:
+ ordering = ('comment_text',)
+
def __unicode__(self):
return self.comment_text
diff --git a/tests/regressiontests/one_to_one_regress/tests.py b/tests/regressiontests/one_to_one_regress/tests.py
new file mode 100644
index 0000000000..a0a0c0584f
--- /dev/null
+++ b/tests/regressiontests/one_to_one_regress/tests.py
@@ -0,0 +1,22 @@
+from django.test import TestCase
+from regressiontests.one_to_one_regress.models import Place, UndergroundBar
+
+class OneToOneDeletionTests(TestCase):
+ def test_reverse_relationship_cache_cascade(self):
+ """
+ Regression test for #9023: accessing the reverse relationship shouldn't
+ result in a cascading delete().
+ """
+ place = Place.objects.create(name="Dempsey's", address="623 Vermont St")
+ bar = UndergroundBar.objects.create(place=place, serves_cocktails=False)
+
+ # The bug in #9023: if you access the one-to-one relation *before*
+ # setting to None and deleting, the cascade happens anyway.
+ place.undergroundbar
+ bar.place.name='foo'
+ bar.place = None
+ bar.save()
+ place.delete()
+
+ self.assertEqual(Place.objects.all().count(), 0)
+ self.assertEqual(UndergroundBar.objects.all().count(), 1)
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index 3649d27171..0d28926149 100644
--- a/tests/regressiontests/queries/models.py
+++ b/tests/regressiontests/queries/models.py
@@ -1151,6 +1151,7 @@ True
>>> qs = Author.objects.filter(pk__in=subq)
>>> list(qs)
[<Author: a1>, <Author: a2>]
+
# The subquery result cache should not be populated
>>> subq._result_cache is None
True
@@ -1159,6 +1160,7 @@ True
>>> qs = Author.objects.exclude(pk__in=subq)
>>> list(qs)
[<Author: a3>, <Author: a4>]
+
# The subquery result cache should not be populated
>>> subq._result_cache is None
True
@@ -1166,6 +1168,7 @@ True
>>> subq = Author.objects.filter(num__lt=3000)
>>> list(Author.objects.filter(Q(pk__in=subq) & Q(name='a1')))
[<Author: a1>]
+
# The subquery result cache should not be populated
>>> subq._result_cache is None
True
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index 4e52d81811..de7ddcc9f7 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -103,7 +103,7 @@ def data_compare(testcase, pk, klass, data):
def generic_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
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):
instance = klass.objects.get(id=pk)
@@ -111,7 +111,7 @@ def fk_compare(testcase, pk, klass, data):
def m2m_compare(testcase, pk, klass, data):
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):
instance = klass.objects.get(id=pk)
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 953e8faa1a..9c01b492e3 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -69,7 +69,7 @@ class SomeException(Exception):
class SomeOtherException(Exception):
pass
-
+
class ContextStackException(Exception):
pass
@@ -629,7 +629,7 @@ class Templates(unittest.TestCase):
# Logically the same as above, just written with explicit
# ifchanged for the day.
- 'ifchanged-param04': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
+ 'ifchanged-param05': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
# Test the else clause of ifchanged.
'ifchanged-else01': ('{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-first,1-other,2-first,2-other,2-other,3-first,'),
@@ -1014,6 +1014,9 @@ class Templates(unittest.TestCase):
# Regression test for #7460.
'cache16': ('{% load cache %}{% cache 1 foo bar %}{% endcache %}', {'foo': 'foo', 'bar': 'with spaces'}, ''),
+ # Regression test for #11270.
+ 'cache17': ('{% load cache %}{% cache 10 long_cache_key poem %}Some Content{% endcache %}', {'poem': 'Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont.'}, 'Some Content'),
+
### AUTOESCAPE TAG ##############################################
'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),
'autoescape-tag02': ("{% autoescape off %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"),
diff --git a/tests/regressiontests/urlpatterns_reverse/tests.py b/tests/regressiontests/urlpatterns_reverse/tests.py
index a7283d43bb..9def6b2eb2 100644
--- a/tests/regressiontests/urlpatterns_reverse/tests.py
+++ b/tests/regressiontests/urlpatterns_reverse/tests.py
@@ -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
"""}
+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.shortcuts import redirect
from django.test import TestCase
@@ -112,6 +113,21 @@ class URLPatternReverse(TestCase):
else:
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):
urls = 'regressiontests.urlpatterns_reverse.urls'