diff options
| author | Marc Garcia <garcia.marc@gmail.com> | 2009-07-01 23:33:02 +0000 |
|---|---|---|
| committer | Marc Garcia <garcia.marc@gmail.com> | 2009-07-01 23:33:02 +0000 |
| commit | f5095f8cb367e51e18e084ac118d6900ab9ba735 (patch) | |
| tree | 58baa1119dead8fbb2a0d98af8f70cca0d55ef09 /tests | |
| parent | 87cd3dfa55770e5a987d43797c013d81530083db (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.py | 54 | ||||
| -rw-r--r-- | tests/modeltests/custom_pk/models.py | 30 | ||||
| -rw-r--r-- | tests/modeltests/proxy_models/fixtures/mypeople.json | 9 | ||||
| -rw-r--r-- | tests/modeltests/proxy_models/models.py | 43 | ||||
| -rw-r--r-- | tests/modeltests/transactions/models.py | 3 | ||||
| -rw-r--r-- | tests/regressiontests/fixtures_regress/models.py | 9 | ||||
| -rw-r--r-- | tests/regressiontests/m2m_regress/models.py | 14 | ||||
| -rw-r--r-- | tests/regressiontests/mail/tests.py | 46 | ||||
| -rw-r--r-- | tests/regressiontests/null_fk/models.py | 3 | ||||
| -rw-r--r-- | tests/regressiontests/one_to_one_regress/tests.py | 22 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 3 | ||||
| -rw-r--r-- | tests/regressiontests/serializers_regress/tests.py | 4 | ||||
| -rw-r--r-- | tests/regressiontests/templates/tests.py | 7 | ||||
| -rw-r--r-- | tests/regressiontests/urlpatterns_reverse/tests.py | 18 |
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' |
