diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/basic/models.py | 11 | ||||
| -rw-r--r-- | tests/modeltests/model_forms/models.py | 43 | ||||
| -rw-r--r-- | tests/modeltests/mutually_referential/models.py | 8 | ||||
| -rw-r--r-- | tests/modeltests/ordering/models.py | 4 | ||||
| -rw-r--r-- | tests/regressiontests/datastructures/tests.py | 8 | ||||
| -rw-r--r-- | tests/regressiontests/datatypes/models.py | 26 | ||||
| -rw-r--r-- | tests/regressiontests/decorators/__init__.py | 0 | ||||
| -rw-r--r-- | tests/regressiontests/decorators/models.py | 2 | ||||
| -rw-r--r-- | tests/regressiontests/decorators/tests.py | 56 | ||||
| -rw-r--r-- | tests/regressiontests/fixtures_regress/fixtures/absolute.json | 9 | ||||
| -rw-r--r-- | tests/regressiontests/fixtures_regress/models.py | 22 | ||||
| -rw-r--r-- | tests/regressiontests/i18n/misc.py | 11 | ||||
| -rw-r--r-- | tests/regressiontests/string_lookup/models.py | 8 |
13 files changed, 194 insertions, 14 deletions
diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py index 2f4b932fe0..557331a36e 100644 --- a/tests/modeltests/basic/models.py +++ b/tests/modeltests/basic/models.py @@ -5,6 +5,11 @@ This is a basic model with only two non-primary-key fields. """ +try: + set +except NameError: + from sets import Set as set + from django.db import models class Article(models.Model): @@ -389,4 +394,10 @@ year, including Jan. 1 and Dec. 31. >>> a.save() >>> Article.objects.get(pk=a.id).headline u'\u6797\u539f \u3081\u3050\u307f' + +# Model instances have a hash function, so they can be used in sets or as +# dictionary keys. Two models compare as equal if their primary keys are equal. +>>> s = set([a10, a11, a12]) +>>> Article.objects.get(headline='Article 11') in s +True """ diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index f1fed8f1e1..c480899f84 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -64,11 +64,11 @@ class TextFile(models.Model): def __unicode__(self): return self.description - + class ImageFile(models.Model): description = models.CharField(max_length=20) image = models.FileField(upload_to=tempfile.gettempdir()) - + def __unicode__(self): return self.description @@ -155,29 +155,52 @@ familiar with the mechanics. ... class Meta: ... model = Category ->>> class BadForm(CategoryForm): +>>> class OddForm(CategoryForm): ... class Meta: ... model = Article -Traceback (most recent call last): -... -ImproperlyConfigured: BadForm defines a different model than its parent. + +OddForm is now an Article-related thing, because BadForm.Meta overrides +CategoryForm.Meta. +>>> OddForm.base_fields.keys() +['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] >>> class ArticleForm(ModelForm): ... class Meta: ... model = Article +First class with a Meta class wins. + >>> class BadForm(ArticleForm, CategoryForm): ... pass -Traceback (most recent call last): -... -ImproperlyConfigured: BadForm's base classes define more than one model. +>>> OddForm.base_fields.keys() +['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] -This one is OK since the subclass specifies the same model as the parent. +Subclassing without specifying a Meta on the class will use the parent's Meta +(or the first parent in the MRO if there are multiple parent classes). +>>> class CategoryForm(ModelForm): +... class Meta: +... model = Category >>> class SubCategoryForm(CategoryForm): +... pass +>>> SubCategoryForm.base_fields.keys() +['name', 'slug', 'url'] + +We can also subclass the Meta inner class to change the fields list. + +>>> class CategoryForm(ModelForm): +... checkbox = forms.BooleanField() +... ... class Meta: ... model = Category +>>> class SubCategoryForm(CategoryForm): +... class Meta(CategoryForm.Meta): +... exclude = ['url'] +>>> print SubCategoryForm() +<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr> +<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr> +<tr><th><label for="id_checkbox">Checkbox:</label></th><td><input type="checkbox" name="checkbox" id="id_checkbox" /></td></tr> # Old form_for_x tests ####################################################### diff --git a/tests/modeltests/mutually_referential/models.py b/tests/modeltests/mutually_referential/models.py index 7cf7bf8bb2..5176721f3d 100644 --- a/tests/modeltests/mutually_referential/models.py +++ b/tests/modeltests/mutually_referential/models.py @@ -1,18 +1,22 @@ """ 24. Mutually referential many-to-one relationships -To define a many-to-one relationship, use ``ForeignKey()`` . +Strings can be used instead of model literals to set up "lazy" relations. """ from django.db.models import * class Parent(Model): name = CharField(max_length=100, core=True) + + # Use a simple string for forward declarations. bestchild = ForeignKey("Child", null=True, related_name="favoured_by") class Child(Model): name = CharField(max_length=100) - parent = ForeignKey(Parent) + + # You can also explicitally specify the related app. + parent = ForeignKey("mutually_referential.Parent") __test__ = {'API_TESTS':""" # Create a Parent diff --git a/tests/modeltests/ordering/models.py b/tests/modeltests/ordering/models.py index 3e651d4ee7..9b342a9265 100644 --- a/tests/modeltests/ordering/models.py +++ b/tests/modeltests/ordering/models.py @@ -2,8 +2,8 @@ 6. Specifying ordering Specify default ordering for a model using the ``ordering`` attribute, which -should be a list or tuple of field names. This tells Django how to order the -results of ``get_list()`` and other similar functions. +should be a list or tuple of field names. This tells Django how to order +queryset results. If a field name in ``ordering`` starts with a hyphen, that field will be ordered in descending order. Otherwise, it'll be ordered in ascending order. diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py index b5dc5d171b..b51b4b1233 100644 --- a/tests/regressiontests/datastructures/tests.py +++ b/tests/regressiontests/datastructures/tests.py @@ -77,6 +77,8 @@ MultiValueDictKeyError: "Key 'lastname' not found in <MultiValueDict: {'position 'not one' >>> d.keys() == d.copy().keys() True +>>> d2 = d.copy() +>>> d2['four'] = 'four' >>> print repr(d) {'one': 'not one', 'two': 'two', 'three': 'three'} >>> d.pop('one', 'missing') @@ -99,6 +101,12 @@ Init from sequence of tuples >>> print repr(d) {1: 'one', 0: 'zero', 2: 'two'} +>>> d.clear() +>>> d +{} +>>> d.keyOrder +[] + ### DotExpandedDict ############################################################ >>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']}) diff --git a/tests/regressiontests/datatypes/models.py b/tests/regressiontests/datatypes/models.py index ff9666bc0c..9ebb6402e2 100644 --- a/tests/regressiontests/datatypes/models.py +++ b/tests/regressiontests/datatypes/models.py @@ -56,4 +56,30 @@ datetime.date(1938, 6, 4) datetime.time(5, 30) >>> d3.consumed_at datetime.datetime(2007, 4, 20, 16, 19, 59) + +# Year boundary tests (ticket #3689) + +>>> d = Donut(name='Date Test 2007', baked_date=datetime.datetime(year=2007, month=12, day=31), consumed_at=datetime.datetime(year=2007, month=12, day=31, hour=23, minute=59, second=59)) +>>> d.save() +>>> d1 = Donut(name='Date Test 2006', baked_date=datetime.datetime(year=2006, month=1, day=1), consumed_at=datetime.datetime(year=2006, month=1, day=1)) +>>> d1.save() + +>>> Donut.objects.filter(baked_date__year=2007) +[<Donut: Date Test 2007>] + +>>> Donut.objects.filter(baked_date__year=2006) +[<Donut: Date Test 2006>] + +>>> Donut.objects.filter(consumed_at__year=2007).order_by('name') +[<Donut: Apple Fritter>, <Donut: Date Test 2007>] + +>>> Donut.objects.filter(consumed_at__year=2006) +[<Donut: Date Test 2006>] + +>>> Donut.objects.filter(consumed_at__year=2005) +[] + +>>> Donut.objects.filter(consumed_at__year=2008) +[] + """} diff --git a/tests/regressiontests/decorators/__init__.py b/tests/regressiontests/decorators/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/decorators/__init__.py diff --git a/tests/regressiontests/decorators/models.py b/tests/regressiontests/decorators/models.py new file mode 100644 index 0000000000..e5a795067b --- /dev/null +++ b/tests/regressiontests/decorators/models.py @@ -0,0 +1,2 @@ +# A models.py so that tests run. + diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py new file mode 100644 index 0000000000..0c434772f8 --- /dev/null +++ b/tests/regressiontests/decorators/tests.py @@ -0,0 +1,56 @@ +from unittest import TestCase +from sys import version_info + +from django.http import HttpResponse +from django.utils.functional import allow_lazy, lazy, memoize +from django.views.decorators.http import require_http_methods, require_GET, require_POST +from django.views.decorators.vary import vary_on_headers, vary_on_cookie +from django.views.decorators.cache import cache_page, never_cache, cache_control +from django.contrib.auth.decorators import login_required, permission_required, user_passes_test +from django.contrib.admin.views.decorators import staff_member_required + +def fully_decorated(request): + """Expected __doc__""" + return HttpResponse('<html><body>dummy</body></html>') +fully_decorated.anything = "Expected __dict__" + +# django.views.decorators.http +fully_decorated = require_http_methods(["GET"])(fully_decorated) +fully_decorated = require_GET(fully_decorated) +fully_decorated = require_POST(fully_decorated) + +# django.views.decorators.vary +fully_decorated = vary_on_headers('Accept-language')(fully_decorated) +fully_decorated = vary_on_cookie(fully_decorated) + +# django.views.decorators.cache +fully_decorated = cache_page(60*15)(fully_decorated) +fully_decorated = cache_control(private=True)(fully_decorated) +fully_decorated = never_cache(fully_decorated) + +# django.contrib.auth.decorators +fully_decorated = user_passes_test(lambda u:True)(fully_decorated) +fully_decorated = login_required(fully_decorated) +fully_decorated = permission_required('change_world')(fully_decorated) + +# django.contrib.admin.views.decorators +fully_decorated = staff_member_required(fully_decorated) + +# django.utils.functional +fully_decorated = memoize(fully_decorated, {}, 1) +fully_decorated = allow_lazy(fully_decorated) +fully_decorated = lazy(fully_decorated) + +class DecoratorsTest(TestCase): + + def test_attributes(self): + """ + Tests that django decorators set certain attributes of the wrapped + function. + """ + # Only check __name__ on Python 2.4 or later since __name__ can't be + # assigned to in earlier Python versions. + if version_info[0] >= 2 and version_info[1] >= 4: + self.assertEquals(fully_decorated.__name__, 'fully_decorated') + self.assertEquals(fully_decorated.__doc__, 'Expected __doc__') + self.assertEquals(fully_decorated.__dict__['anything'], 'Expected __dict__') diff --git a/tests/regressiontests/fixtures_regress/fixtures/absolute.json b/tests/regressiontests/fixtures_regress/fixtures/absolute.json new file mode 100644 index 0000000000..37ed3f6886 --- /dev/null +++ b/tests/regressiontests/fixtures_regress/fixtures/absolute.json @@ -0,0 +1,9 @@ +[ + { + "pk": "1", + "model": "fixtures_regress.absolute", + "fields": { + "name": "Load Absolute Path Test" + } + } +]
\ No newline at end of file diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index a62925eb37..144debe05a 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth.models import User from django.conf import settings +import os class Animal(models.Model): name = models.CharField(max_length=150) @@ -28,6 +29,16 @@ class Stuff(models.Model): name = None return unicode(name) + u' is owned by ' + unicode(self.owner) +class Absolute(models.Model): + name = models.CharField(max_length=40) + + load_count = 0 + + def __init__(self, *args, **kwargs): + super(Absolute, self).__init__(*args, **kwargs) + Absolute.load_count += 1 + + __test__ = {'API_TESTS':""" >>> from django.core import management @@ -49,4 +60,15 @@ __test__ = {'API_TESTS':""" >>> Stuff.objects.all() [<Stuff: None is owned by None>] +############################################### +# Regression test for ticket #6436 -- +# os.path.join will throw away the initial parts of a path if it encounters +# an absolute path. This means that if a fixture is specified as an absolute path, +# we need to make sure we don't discover the absolute path in every fixture directory. + +>>> load_absolute_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'absolute.json') +>>> management.call_command('loaddata', load_absolute_path, verbosity=0) +>>> Absolute.load_count +1 + """} diff --git a/tests/regressiontests/i18n/misc.py b/tests/regressiontests/i18n/misc.py index eb64263799..6ed8afaee3 100644 --- a/tests/regressiontests/i18n/misc.py +++ b/tests/regressiontests/i18n/misc.py @@ -1,3 +1,5 @@ +import sys + tests = """ >>> from django.utils.translation.trans_real import parse_accept_lang_header >>> p = parse_accept_lang_header @@ -83,7 +85,14 @@ source tree. >>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'} >>> g(r) 'es-ar' +""" +# Python 2.3 returns slightly different results for completely bogus locales, +# so we omit this test for that anything below 2.4. It's relatively harmless in +# any cases (GIGO). This also means this won't be executed on Jython currently, +# but life's like that sometimes. +if sys.version_info >= (2, 4): + tests += """ This test assumes there won't be a Django translation to a US variation of the Spanish language, a safe assumption. When the user sets it as the preferred language, the main 'es' translation should be selected @@ -91,7 +100,9 @@ instead. >>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'} >>> g(r) 'es' +""" +tests += """ This tests the following scenario: there isn't a main language (zh) translation of Django but there is a translation to variation (zh_CN) the user sets zh-cn as the preferred language, it should be selected by diff --git a/tests/regressiontests/string_lookup/models.py b/tests/regressiontests/string_lookup/models.py index 9deeb18763..1bdb2d4452 100644 --- a/tests/regressiontests/string_lookup/models.py +++ b/tests/regressiontests/string_lookup/models.py @@ -39,6 +39,7 @@ class Base(models.Model): class Article(models.Model): name = models.CharField(max_length=50) text = models.TextField() + submitted_from = models.IPAddressField(blank=True, null=True) def __str__(self): return "Article %s" % self.name @@ -98,4 +99,11 @@ __test__ = {'API_TESTS': ur""" >>> Article.objects.get(text__contains='quick brown fox') <Article: Article Test> + +# Regression test for #708: "like" queries on IP address fields require casting +# to text (on PostgreSQL). +>>> Article(name='IP test', text='The body', submitted_from='192.0.2.100').save() +>>> Article.objects.filter(submitted_from__contains='192.0.2') +[<Article: Article IP test>] + """} |
