diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-07-07 13:23:57 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-07-07 13:23:57 +0000 |
| commit | 1e747f98af99a23c5aff7b460d5b845c3a9e2013 (patch) | |
| tree | 6347c27684a68cf1ef76b92808aa9309b0688797 /tests | |
| parent | 7ed1a919681b5b028c3f6eef1a862ff91b66feb2 (diff) | |
newforms-admin: Merged from trunk up to [5625]. This includes the Unicode
merge, however, not all of admin/ (and none of admindocs/) has been ported and
checked yet.
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5627 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
64 files changed, 763 insertions, 490 deletions
diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py index 9af13c0e3e..81656cf2df 100644 --- a/tests/modeltests/basic/models.py +++ b/tests/modeltests/basic/models.py @@ -1,3 +1,4 @@ +# coding: utf-8 """ 1. Bare-bones model @@ -13,7 +14,7 @@ class Article(models.Model): class Meta: ordering = ('pub_date','headline') - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS': """ @@ -351,7 +352,7 @@ __test__['API_TESTS'] += """ >>> a101.save() >>> a101 = Article.objects.get(pk=101) >>> a101.headline -'Article 101' +u'Article 101' # You can create saved objects in a single step >>> a10 = Article.objects.create(headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)) @@ -364,4 +365,10 @@ year, including Jan. 1 and Dec. 31. >>> a12 = Article.objects.create(headline='Article 12', pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999)) >>> Article.objects.filter(pub_date__year=2008) [<Article: Article 11>, <Article: Article 12>] + +# Unicode data works, too. +>>> a = Article(headline=u'\u6797\u539f \u3081\u3050\u307f', pub_date=datetime(2005, 7, 28)) +>>> a.save() +>>> Article.objects.get(pk=a.id).headline +u'\u6797\u539f \u3081\u3050\u307f' """ diff --git a/tests/modeltests/choices/models.py b/tests/modeltests/choices/models.py index 37d36fe1d8..cb1bd481cd 100644 --- a/tests/modeltests/choices/models.py +++ b/tests/modeltests/choices/models.py @@ -20,7 +20,7 @@ class Person(models.Model): name = models.CharField(maxlength=20) gender = models.CharField(maxlength=1, choices=GENDER_CHOICES) - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" @@ -33,7 +33,7 @@ __test__ = {'API_TESTS':""" >>> s.gender 'F' >>> a.get_gender_display() -'Male' +u'Male' >>> s.get_gender_display() -'Female' +u'Female' """} diff --git a/tests/modeltests/custom_columns/models.py b/tests/modeltests/custom_columns/models.py index 1283da07cf..fb2487802c 100644 --- a/tests/modeltests/custom_columns/models.py +++ b/tests/modeltests/custom_columns/models.py @@ -6,11 +6,11 @@ If your database column name is different than your model attribute, use the name, in API usage. If your database table name is different than your model name, use the -``db_table`` Meta attribute. This has no effect on the API used to +``db_table`` Meta attribute. This has no effect on the API used to query the database. -If you need to use a table name for a many-to-many relationship that differs -from the default generated name, use the ``db_table`` parameter on the +If you need to use a table name for a many-to-many relationship that differs +from the default generated name, use the ``db_table`` parameter on the ManyToMany field. This has no effect on the API for querying the database. """ @@ -21,8 +21,8 @@ class Author(models.Model): first_name = models.CharField(maxlength=30, db_column='firstname') last_name = models.CharField(maxlength=30, db_column='last') - def __str__(self): - return '%s %s' % (self.first_name, self.last_name) + def __unicode__(self): + return u'%s %s' % (self.first_name, self.last_name) class Meta: db_table = 'my_author_table' @@ -32,12 +32,12 @@ class Article(models.Model): headline = models.CharField(maxlength=100) authors = models.ManyToManyField(Author, db_table='my_m2m_table') - def __str__(self): + def __unicode__(self): return self.headline class Meta: ordering = ('headline',) - + __test__ = {'API_TESTS':""" # Create a Author. >>> a = Author(first_name='John', last_name='Smith') @@ -75,9 +75,9 @@ TypeError: Cannot resolve keyword 'firstname' into field. Choices are: article, >>> a = Author.objects.get(last_name__exact='Smith') >>> a.first_name -'John' +u'John' >>> a.last_name -'Smith' +u'Smith' >>> a.firstname Traceback (most recent call last): ... diff --git a/tests/modeltests/custom_managers/models.py b/tests/modeltests/custom_managers/models.py index 99df875275..0b9edc88b9 100644 --- a/tests/modeltests/custom_managers/models.py +++ b/tests/modeltests/custom_managers/models.py @@ -23,8 +23,8 @@ class Person(models.Model): fun = models.BooleanField() objects = PersonManager() - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) # An example of a custom manager that sets get_query_set(). @@ -39,7 +39,7 @@ class Book(models.Model): published_objects = PublishedBookManager() authors = models.ManyToManyField(Person, related_name='books') - def __str__(self): + def __unicode__(self): return self.title # An example of providing multiple custom managers. @@ -55,7 +55,7 @@ class Car(models.Model): cars = models.Manager() fast_cars = FastCarManager() - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/custom_methods/models.py b/tests/modeltests/custom_methods/models.py index e8fb751d54..5a6581805a 100644 --- a/tests/modeltests/custom_methods/models.py +++ b/tests/modeltests/custom_methods/models.py @@ -11,7 +11,7 @@ class Article(models.Model): headline = models.CharField(maxlength=100) pub_date = models.DateField() - def __str__(self): + def __unicode__(self): return self.headline def was_published_today(self): diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py index fd0901da3c..276fecc371 100644 --- a/tests/modeltests/custom_pk/models.py +++ b/tests/modeltests/custom_pk/models.py @@ -15,8 +15,8 @@ class Employee(models.Model): class Meta: ordering = ('last_name', 'first_name') - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) class Business(models.Model): name = models.CharField(maxlength=20, primary_key=True) @@ -24,7 +24,7 @@ class Business(models.Model): class Meta: verbose_name_plural = 'businesses' - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" @@ -62,7 +62,7 @@ DoesNotExist: Employee matching query does not exist. >>> Employee.objects.filter(last_name__exact='Jones') [<Employee: Dan Jones>, <Employee: Fran Jones>] >>> Employee.objects.in_bulk(['ABC123', 'XYZ456']) -{'XYZ456': <Employee: Fran Jones>, 'ABC123': <Employee: Dan Jones>} +{u'XYZ456': <Employee: Fran Jones>, u'ABC123': <Employee: Dan Jones>} >>> b = Business(name='Sears') >>> b.save() @@ -72,7 +72,7 @@ DoesNotExist: Employee matching query does not exist. >>> fran.business_set.all() [<Business: Sears>] >>> Business.objects.in_bulk(['Sears']) -{'Sears': <Business: Sears>} +{u'Sears': <Business: Sears>} >>> Business.objects.filter(name__exact='Sears') [<Business: Sears>] diff --git a/tests/modeltests/field_defaults/models.py b/tests/modeltests/field_defaults/models.py index 8e803d00d8..7eafa03798 100644 --- a/tests/modeltests/field_defaults/models.py +++ b/tests/modeltests/field_defaults/models.py @@ -16,7 +16,7 @@ class Article(models.Model): headline = models.CharField(maxlength=100, default='Default headline') pub_date = models.DateTimeField(default=datetime.now) - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/fixtures/models.py b/tests/modeltests/fixtures/models.py index c75e6723fd..c713aa723d 100644 --- a/tests/modeltests/fixtures/models.py +++ b/tests/modeltests/fixtures/models.py @@ -1,10 +1,10 @@ """ 37. Fixtures. -Fixtures are a way of loading data into the database in bulk. Fixure data -can be stored in any serializable format (including JSON and XML). Fixtures +Fixtures are a way of loading data into the database in bulk. Fixure data +can be stored in any serializable format (including JSON and XML). Fixtures are identified by name, and are stored in either a directory named 'fixtures' -in the application directory, on in one of the directories named in the +in the application directory, on in one of the directories named in the FIXTURE_DIRS setting. """ @@ -14,17 +14,17 @@ class Article(models.Model): headline = models.CharField(maxlength=100, default='Default headline') pub_date = models.DateTimeField() - def __str__(self): + def __unicode__(self): return self.headline - + class Meta: ordering = ('-pub_date', 'headline') - + __test__ = {'API_TESTS': """ >>> from django.core import management >>> from django.db.models import get_app -# Reset the database representation of this app. +# Reset the database representation of this app. # This will return the database to a clean initial state. >>> management.flush(verbosity=0, interactive=False) @@ -42,7 +42,7 @@ __test__ = {'API_TESTS': """ >>> Article.objects.all() [<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] -# Load fixture 3, XML format. +# Load fixture 3, XML format. >>> management.load_data(['fixture3.xml'], verbosity=0) >>> Article.objects.all() [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>] @@ -65,7 +65,7 @@ __test__ = {'API_TESTS': """ [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] # Try to load fixture 2 using format discovery; this will fail -# because there are two fixture2's in the fixtures directory +# because there are two fixture2's in the fixtures directory >>> management.load_data(['fixture2'], verbosity=0) # doctest: +ELLIPSIS Multiple fixtures named 'fixture2' in '...fixtures'. Aborting. @@ -81,7 +81,7 @@ from django.test import TestCase class SampleTestCase(TestCase): fixtures = ['fixture1.json', 'fixture2.json'] - + def testClassFixtures(self): "Check that test case has installed 4 fixture objects" self.assertEqual(Article.objects.count(), 4) diff --git a/tests/modeltests/generic_relations/models.py b/tests/modeltests/generic_relations/models.py index 195f67db8f..d77a2ee43d 100644 --- a/tests/modeltests/generic_relations/models.py +++ b/tests/modeltests/generic_relations/models.py @@ -24,7 +24,7 @@ class TaggedItem(models.Model): class Meta: ordering = ["tag"] - def __str__(self): + def __unicode__(self): return self.tag class Animal(models.Model): @@ -33,7 +33,7 @@ class Animal(models.Model): tags = generic.GenericRelation(TaggedItem) - def __str__(self): + def __unicode__(self): return self.common_name class Vegetable(models.Model): @@ -42,7 +42,7 @@ class Vegetable(models.Model): tags = generic.GenericRelation(TaggedItem) - def __str__(self): + def __unicode__(self): return self.name class Mineral(models.Model): @@ -51,7 +51,7 @@ class Mineral(models.Model): # note the lack of an explicit GenericRelation here... - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" @@ -111,17 +111,17 @@ __test__ = {'API_TESTS':""" # objects are deleted when the source object is deleted. # Original list of tags: >>> [(t.tag, t.content_type, t.object_id) for t in TaggedItem.objects.all()] -[('clearish', <ContentType: mineral>, 1), ('fatty', <ContentType: vegetable>, 2), ('hairy', <ContentType: animal>, 1), ('salty', <ContentType: vegetable>, 2), ('shiny', <ContentType: animal>, 2), ('yellow', <ContentType: animal>, 1)] +[(u'clearish', <ContentType: mineral>, 1), (u'fatty', <ContentType: vegetable>, 2), (u'hairy', <ContentType: animal>, 1), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2), (u'yellow', <ContentType: animal>, 1)] >>> lion.delete() >>> [(t.tag, t.content_type, t.object_id) for t in TaggedItem.objects.all()] -[('clearish', <ContentType: mineral>, 1), ('fatty', <ContentType: vegetable>, 2), ('salty', <ContentType: vegetable>, 2), ('shiny', <ContentType: animal>, 2)] +[(u'clearish', <ContentType: mineral>, 1), (u'fatty', <ContentType: vegetable>, 2), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] # If Generic Relation is not explicitly defined, any related objects # remain after deletion of the source object. >>> quartz.delete() >>> [(t.tag, t.content_type, t.object_id) for t in TaggedItem.objects.all()] -[('clearish', <ContentType: mineral>, 1), ('fatty', <ContentType: vegetable>, 2), ('salty', <ContentType: vegetable>, 2), ('shiny', <ContentType: animal>, 2)] +[(u'clearish', <ContentType: mineral>, 1), (u'fatty', <ContentType: vegetable>, 2), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] # If you delete a tag, the objects using the tag are unaffected # (other than losing a tag) @@ -130,6 +130,6 @@ __test__ = {'API_TESTS':""" >>> bacon.tags.all() [<TaggedItem: salty>] >>> [(t.tag, t.content_type, t.object_id) for t in TaggedItem.objects.all()] -[('clearish', <ContentType: mineral>, 1), ('salty', <ContentType: vegetable>, 2), ('shiny', <ContentType: animal>, 2)] +[(u'clearish', <ContentType: mineral>, 1), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] """} diff --git a/tests/modeltests/get_latest/models.py b/tests/modeltests/get_latest/models.py index 84c6273818..e54e5e32b7 100644 --- a/tests/modeltests/get_latest/models.py +++ b/tests/modeltests/get_latest/models.py @@ -17,7 +17,7 @@ class Article(models.Model): class Meta: get_latest_by = 'pub_date' - def __str__(self): + def __unicode__(self): return self.headline class Person(models.Model): @@ -26,7 +26,7 @@ class Person(models.Model): # Note that this model doesn't have "get_latest_by" set. - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/get_object_or_404/models.py b/tests/modeltests/get_object_or_404/models.py index 2ad459669f..5f449f4cfe 100644 --- a/tests/modeltests/get_object_or_404/models.py +++ b/tests/modeltests/get_object_or_404/models.py @@ -17,7 +17,7 @@ from django.shortcuts import get_object_or_404, get_list_or_404 class Author(models.Model): name = models.CharField(maxlength=50) - def __str__(self): + def __unicode__(self): return self.name class ArticleManager(models.Manager): @@ -30,7 +30,7 @@ class Article(models.Model): objects = models.Manager() by_a_sir = ArticleManager() - def __str__(self): + def __unicode__(self): return self.title __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/get_or_create/models.py b/tests/modeltests/get_or_create/models.py index f974a82dee..ed26daa852 100644 --- a/tests/modeltests/get_or_create/models.py +++ b/tests/modeltests/get_or_create/models.py @@ -12,8 +12,8 @@ class Person(models.Model): last_name = models.CharField(maxlength=100) birthday = models.DateField() - def __str__(self): - return '%s %s' % (self.first_name, self.last_name) + def __unicode__(self): + return u'%s %s' % (self.first_name, self.last_name) __test__ = {'API_TESTS':""" # Acting as a divine being, create an Person. diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py index 9d3e8ca4b4..207b27a7d9 100644 --- a/tests/modeltests/lookup/models.py +++ b/tests/modeltests/lookup/models.py @@ -13,7 +13,7 @@ class Article(models.Model): class Meta: ordering = ('-pub_date', 'headline') - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':r""" @@ -100,7 +100,7 @@ TypeError: in_bulk() got an unexpected keyword argument 'headline__startswith' # values() returns a list of dictionaries instead of object instances -- and # you can specify which fields you want to retrieve. >>> Article.objects.values('headline') -[{'headline': 'Article 5'}, {'headline': 'Article 6'}, {'headline': 'Article 4'}, {'headline': 'Article 2'}, {'headline': 'Article 3'}, {'headline': 'Article 7'}, {'headline': 'Article 1'}] +[{'headline': u'Article 5'}, {'headline': u'Article 6'}, {'headline': u'Article 4'}, {'headline': u'Article 2'}, {'headline': u'Article 3'}, {'headline': u'Article 7'}, {'headline': u'Article 1'}] >>> Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id') [{'id': 2}, {'id': 3}, {'id': 7}] >>> list(Article.objects.values('id', 'headline')) == [{'id': 5, 'headline': 'Article 5'}, {'id': 6, 'headline': 'Article 6'}, {'id': 4, 'headline': 'Article 4'}, {'id': 2, 'headline': 'Article 2'}, {'id': 3, 'headline': 'Article 3'}, {'id': 7, 'headline': 'Article 7'}, {'id': 1, 'headline': 'Article 1'}] @@ -110,13 +110,13 @@ True ... i = d.items() ... i.sort() ... i -[('headline', 'Article 5'), ('id', 5)] -[('headline', 'Article 6'), ('id', 6)] -[('headline', 'Article 4'), ('id', 4)] -[('headline', 'Article 2'), ('id', 2)] -[('headline', 'Article 3'), ('id', 3)] -[('headline', 'Article 7'), ('id', 7)] -[('headline', 'Article 1'), ('id', 1)] +[('headline', u'Article 5'), ('id', 5)] +[('headline', u'Article 6'), ('id', 6)] +[('headline', u'Article 4'), ('id', 4)] +[('headline', u'Article 2'), ('id', 2)] +[('headline', u'Article 3'), ('id', 3)] +[('headline', u'Article 7'), ('id', 7)] +[('headline', u'Article 1'), ('id', 1)] # You can use values() with iterator() for memory savings, because iterator() # uses database-level iteration. @@ -124,13 +124,13 @@ True ... i = d.items() ... i.sort() ... i -[('headline', 'Article 5'), ('id', 5)] -[('headline', 'Article 6'), ('id', 6)] -[('headline', 'Article 4'), ('id', 4)] -[('headline', 'Article 2'), ('id', 2)] -[('headline', 'Article 3'), ('id', 3)] -[('headline', 'Article 7'), ('id', 7)] -[('headline', 'Article 1'), ('id', 1)] +[('headline', u'Article 5'), ('id', 5)] +[('headline', u'Article 6'), ('id', 6)] +[('headline', u'Article 4'), ('id', 4)] +[('headline', u'Article 2'), ('id', 2)] +[('headline', u'Article 3'), ('id', 3)] +[('headline', u'Article 7'), ('id', 7)] +[('headline', u'Article 1'), ('id', 1)] # you can use values() even on extra fields diff --git a/tests/modeltests/m2m_and_m2o/models.py b/tests/modeltests/m2m_and_m2o/models.py index 09affb002f..b5adc63b9d 100644 --- a/tests/modeltests/m2m_and_m2o/models.py +++ b/tests/modeltests/m2m_and_m2o/models.py @@ -14,8 +14,8 @@ class Issue(models.Model): cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc') client = models.ForeignKey(User, related_name='test_issue_client') - def __str__(self): - return str(self.num) + def __unicode__(self): + return unicode(self.num) class Meta: ordering = ('num',) diff --git a/tests/modeltests/m2m_intermediary/models.py b/tests/modeltests/m2m_intermediary/models.py index b917db6189..5e56f44872 100644 --- a/tests/modeltests/m2m_intermediary/models.py +++ b/tests/modeltests/m2m_intermediary/models.py @@ -16,14 +16,14 @@ class Reporter(models.Model): first_name = models.CharField(maxlength=30) last_name = models.CharField(maxlength=30) - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) class Article(models.Model): headline = models.CharField(maxlength=100) pub_date = models.DateField() - def __str__(self): + def __unicode__(self): return self.headline class Writer(models.Model): @@ -31,8 +31,8 @@ class Writer(models.Model): article = models.ForeignKey(Article) position = models.CharField(maxlength=100) - def __str__(self): - return '%s (%s)' % (self.reporter, self.position) + def __unicode__(self): + return u'%s (%s)' % (self.reporter, self.position) __test__ = {'API_TESTS':""" # Create a few Reporters. diff --git a/tests/modeltests/m2m_multiple/models.py b/tests/modeltests/m2m_multiple/models.py index 5a1aa122a9..78c35aafc2 100644 --- a/tests/modeltests/m2m_multiple/models.py +++ b/tests/modeltests/m2m_multiple/models.py @@ -14,7 +14,7 @@ class Category(models.Model): class Meta: ordering = ('name',) - def __str__(self): + def __unicode__(self): return self.name class Article(models.Model): @@ -25,7 +25,7 @@ class Article(models.Model): class Meta: ordering = ('pub_date',) - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/m2m_recursive/models.py b/tests/modeltests/m2m_recursive/models.py index 15c713a759..28d98f0600 100644 --- a/tests/modeltests/m2m_recursive/models.py +++ b/tests/modeltests/m2m_recursive/models.py @@ -19,7 +19,7 @@ class Person(models.Model): friends = models.ManyToManyField('self') idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers') - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/m2o_recursive/models.py b/tests/modeltests/m2o_recursive/models.py index 0b528faf9e..7421061489 100644 --- a/tests/modeltests/m2o_recursive/models.py +++ b/tests/modeltests/m2o_recursive/models.py @@ -16,7 +16,7 @@ class Category(models.Model): name = models.CharField(maxlength=20) parent = models.ForeignKey('self', null=True, related_name='child_set') - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/m2o_recursive2/models.py b/tests/modeltests/m2o_recursive2/models.py index 5b7c5447ad..a8460d6149 100644 --- a/tests/modeltests/m2o_recursive2/models.py +++ b/tests/modeltests/m2o_recursive2/models.py @@ -14,7 +14,7 @@ class Person(models.Model): mother = models.ForeignKey('self', null=True, related_name='mothers_child_set') father = models.ForeignKey('self', null=True, related_name='fathers_child_set') - def __str__(self): + def __unicode__(self): return self.full_name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/manipulators/models.py b/tests/modeltests/manipulators/models.py index 1a44cfe7f4..7f1ff0e47b 100644 --- a/tests/modeltests/manipulators/models.py +++ b/tests/modeltests/manipulators/models.py @@ -10,15 +10,15 @@ class Musician(models.Model): first_name = models.CharField(maxlength=30) last_name = models.CharField(maxlength=30) - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) class Album(models.Model): name = models.CharField(maxlength=100) musician = models.ForeignKey(Musician) release_date = models.DateField(blank=True, null=True) - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" @@ -41,24 +41,24 @@ True # Attempt to add a Musician without a first_name. >>> man.get_validation_errors(MultiValueDict({'last_name': ['Blakey']})) -{'first_name': ['This field is required.']} +{'first_name': [u'This field is required.']} # Attempt to add a Musician without a first_name and last_name. >>> man.get_validation_errors(MultiValueDict({})) -{'first_name': ['This field is required.'], 'last_name': ['This field is required.']} +{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.']} # Attempt to create an Album without a name or musician. >>> man = Album.AddManipulator() >>> man.get_validation_errors(MultiValueDict({})) -{'musician': ['This field is required.'], 'name': ['This field is required.']} +{'musician': [u'This field is required.'], 'name': [u'This field is required.']} # Attempt to create an Album with an invalid musician. >>> man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['foo']})) -{'musician': ["Select a valid choice; 'foo' is not in ['', '1']."]} +{'musician': [u"Select a valid choice; 'foo' is not in ['', '1']."]} # Attempt to create an Album with an invalid release_date. >>> man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['1'], 'release_date': 'today'})) -{'release_date': ['Enter a valid date in YYYY-MM-DD format.']} +{'release_date': [u'Enter a valid date in YYYY-MM-DD format.']} # Create an Album without a release_date (because it's optional). >>> data = MultiValueDict({'name': ['Ella and Basie'], 'musician': ['1']}) diff --git a/tests/modeltests/many_to_many/models.py b/tests/modeltests/many_to_many/models.py index 5e46ad428d..446a39b472 100644 --- a/tests/modeltests/many_to_many/models.py +++ b/tests/modeltests/many_to_many/models.py @@ -12,7 +12,7 @@ from django.db import models class Publication(models.Model): title = models.CharField(maxlength=30) - def __str__(self): + def __unicode__(self): return self.title class Meta: @@ -22,7 +22,7 @@ class Article(models.Model): headline = models.CharField(maxlength=100) publications = models.ManyToManyField(Publication) - def __str__(self): + def __unicode__(self): return self.headline class Meta: diff --git a/tests/modeltests/many_to_one/models.py b/tests/modeltests/many_to_one/models.py index 02f7bf1066..1356b1924b 100644 --- a/tests/modeltests/many_to_one/models.py +++ b/tests/modeltests/many_to_one/models.py @@ -11,15 +11,15 @@ class Reporter(models.Model): last_name = models.CharField(maxlength=30) email = models.EmailField() - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) class Article(models.Model): headline = models.CharField(maxlength=100) pub_date = models.DateField() reporter = models.ForeignKey(Reporter) - def __str__(self): + def __unicode__(self): return self.headline class Meta: @@ -47,7 +47,7 @@ __test__ = {'API_TESTS':""" # Article objects have access to their related Reporter objects. >>> r = a.reporter >>> r.first_name, r.last_name -('John', 'Smith') +(u'John', u'Smith') # Create an Article via the Reporter object. >>> new_article = r.article_set.create(headline="John's second story", pub_date=datetime(2005, 7, 29)) @@ -154,8 +154,13 @@ False >>> Article.objects.filter(reporter__first_name__exact='John').extra(where=["many_to_one_article__reporter.last_name='Smith'"]) [<Article: John's second story>, <Article: This is a test>] +# And should work fine with the unicode that comes out of +# newforms.Form.cleaned_data +>>> Article.objects.filter(reporter__first_name__exact='John').extra(where=["many_to_one_article__reporter.last_name='%s'" % u'Smith']) +[<Article: John's second story>, <Article: This is a test>] + # Find all Articles for the Reporter whose ID is 1. -# Use direct ID check, pk check, and object comparison +# Use direct ID check, pk check, and object comparison >>> Article.objects.filter(reporter__id__exact=1) [<Article: John's second story>, <Article: This is a test>] >>> Article.objects.filter(reporter__pk=1) diff --git a/tests/modeltests/many_to_one_null/models.py b/tests/modeltests/many_to_one_null/models.py index fb0f6ac3b7..1469dbb5ca 100644 --- a/tests/modeltests/many_to_one_null/models.py +++ b/tests/modeltests/many_to_one_null/models.py @@ -10,7 +10,7 @@ from django.db import models class Reporter(models.Model): name = models.CharField(maxlength=30) - def __str__(self): + def __unicode__(self): return self.name class Article(models.Model): @@ -20,7 +20,7 @@ class Article(models.Model): class Meta: ordering = ('headline',) - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 6ffd4d1bce..a21bef02ce 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -34,13 +34,13 @@ class Category(models.Model): name = models.CharField(maxlength=20) url = models.CharField('The URL', maxlength=40) - def __str__(self): + def __unicode__(self): return self.name class Writer(models.Model): name = models.CharField(maxlength=50, help_text='Use both first and last names.') - def __str__(self): + def __unicode__(self): return self.name class Article(models.Model): @@ -58,14 +58,14 @@ class Article(models.Model): self.created = datetime.date.today() return super(Article, self).save() - def __str__(self): + def __unicode__(self): return self.headline class PhoneNumber(models.Model): phone = models.PhoneNumberField() description = models.CharField(maxlength=20) - def __str__(self): + def __unicode__(self): return self.phone __test__ = {'API_TESTS': """ @@ -244,10 +244,10 @@ True 1 >>> test_art = Article.objects.get(id=1) >>> test_art.headline -'Test headline' +u'Test headline' -You can create a form over a subset of the available fields -by specifying a 'fields' argument to form_for_instance. +You can create a form over a subset of the available fields +by specifying a 'fields' argument to form_for_instance. >>> PartialArticleForm = form_for_instance(art, fields=('headline','pub_date')) >>> f = PartialArticleForm({'headline': u'New headline', 'pub_date': u'1988-01-04'}, auto_id=False) >>> print f.as_ul() @@ -260,7 +260,7 @@ True 1 >>> new_art = Article.objects.get(id=1) >>> new_art.headline -'New headline' +u'New headline' Add some categories and test the many-to-many form output. >>> new_art.categories.all() diff --git a/tests/modeltests/model_inheritance/models.py b/tests/modeltests/model_inheritance/models.py index babef73e0a..8fbd518928 100644 --- a/tests/modeltests/model_inheritance/models.py +++ b/tests/modeltests/model_inheritance/models.py @@ -10,21 +10,21 @@ class Place(models.Model): name = models.CharField(maxlength=50) address = models.CharField(maxlength=80) - def __str__(self): - return "%s the place" % self.name + def __unicode__(self): + return u"%s the place" % self.name class Restaurant(Place): serves_hot_dogs = models.BooleanField() serves_pizza = models.BooleanField() - def __str__(self): - return "%s the restaurant" % self.name + def __unicode__(self): + return u"%s the restaurant" % self.name class ItalianRestaurant(Restaurant): serves_gnocchi = models.BooleanField() - def __str__(self): - return "%s the italian restaurant" % self.name + def __unicode__(self): + return u"%s the italian restaurant" % self.name __test__ = {'API_TESTS':""" # Make sure Restaurant has the right fields in the right order. diff --git a/tests/modeltests/one_to_one/models.py b/tests/modeltests/one_to_one/models.py index 7488204ff1..99228d21a8 100644 --- a/tests/modeltests/one_to_one/models.py +++ b/tests/modeltests/one_to_one/models.py @@ -12,23 +12,23 @@ class Place(models.Model): name = models.CharField(maxlength=50) address = models.CharField(maxlength=80) - def __str__(self): - return "%s the place" % self.name + def __unicode__(self): + return u"%s the place" % self.name class Restaurant(models.Model): place = models.OneToOneField(Place) serves_hot_dogs = models.BooleanField() serves_pizza = models.BooleanField() - def __str__(self): - return "%s the restaurant" % self.place.name + def __unicode__(self): + return u"%s the restaurant" % self.place.name class Waiter(models.Model): restaurant = models.ForeignKey(Restaurant) name = models.CharField(maxlength=50) - def __str__(self): - return "%s the waiter at %s" % (self.name, self.restaurant) + def __unicode__(self): + return u"%s the waiter at %s" % (self.name, self.restaurant) class ManualPrimaryKey(models.Model): primary_key = models.CharField(maxlength=10, primary_key=True) diff --git a/tests/modeltests/or_lookups/models.py b/tests/modeltests/or_lookups/models.py index 9f926a7373..142df16081 100644 --- a/tests/modeltests/or_lookups/models.py +++ b/tests/modeltests/or_lookups/models.py @@ -20,7 +20,7 @@ class Article(models.Model): class Meta: ordering = ('pub_date',) - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" @@ -100,7 +100,7 @@ __test__ = {'API_TESTS':""" 3 >>> list(Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')).values()) -[{'headline': 'Hello and goodbye', 'pub_date': datetime.datetime(2005, 11, 29, 0, 0), 'id': 3}] +[{'headline': u'Hello and goodbye', 'pub_date': datetime.datetime(2005, 11, 29, 0, 0), 'id': 3}] >>> Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([1,2]) {1: <Article: Hello>} diff --git a/tests/modeltests/ordering/models.py b/tests/modeltests/ordering/models.py index 110ae3d7fc..1c4e08c11c 100644 --- a/tests/modeltests/ordering/models.py +++ b/tests/modeltests/ordering/models.py @@ -21,7 +21,7 @@ class Article(models.Model): class Meta: ordering = ('-pub_date', 'headline') - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/pagination/models.py b/tests/modeltests/pagination/models.py index 94deb885f5..2834d293e4 100644 --- a/tests/modeltests/pagination/models.py +++ b/tests/modeltests/pagination/models.py @@ -12,7 +12,7 @@ class Article(models.Model): headline = models.CharField(maxlength=100, default='Default headline') pub_date = models.DateTimeField() - def __str__(self): + def __unicode__(self): return self.headline __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/reserved_names/models.py b/tests/modeltests/reserved_names/models.py index affe3f649d..acec978d86 100644 --- a/tests/modeltests/reserved_names/models.py +++ b/tests/modeltests/reserved_names/models.py @@ -21,7 +21,7 @@ class Thing(models.Model): class Meta: db_table = 'select' - def __str__(self): + def __unicode__(self): return self.when __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/reverse_lookup/models.py b/tests/modeltests/reverse_lookup/models.py index 4d6591551a..957c1dfb96 100644 --- a/tests/modeltests/reverse_lookup/models.py +++ b/tests/modeltests/reverse_lookup/models.py @@ -9,14 +9,14 @@ from django.db import models class User(models.Model): name = models.CharField(maxlength=200) - def __str__(self): + def __unicode__(self): return self.name class Poll(models.Model): question = models.CharField(maxlength=200) creator = models.ForeignKey(User) - def __str__(self): + def __unicode__(self): return self.question class Choice(models.Model): @@ -24,7 +24,7 @@ class Choice(models.Model): poll = models.ForeignKey(Poll, related_name="poll_choice") related_poll = models.ForeignKey(Poll, related_name="related_choice") - def __str(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" diff --git a/tests/modeltests/save_delete_hooks/models.py b/tests/modeltests/save_delete_hooks/models.py index 6e24c308ba..292cfd8e9e 100644 --- a/tests/modeltests/save_delete_hooks/models.py +++ b/tests/modeltests/save_delete_hooks/models.py @@ -11,8 +11,8 @@ class Person(models.Model): first_name = models.CharField(maxlength=20) last_name = models.CharField(maxlength=20) - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) def save(self): print "Before save" diff --git a/tests/modeltests/select_related/models.py b/tests/modeltests/select_related/models.py index cd34bd1d84..235712ef27 100644 --- a/tests/modeltests/select_related/models.py +++ b/tests/modeltests/select_related/models.py @@ -13,49 +13,49 @@ from django.db import models class Domain(models.Model): name = models.CharField(maxlength=50) - def __str__(self): + def __unicode__(self): return self.name class Kingdom(models.Model): name = models.CharField(maxlength=50) domain = models.ForeignKey(Domain) - def __str__(self): + def __unicode__(self): return self.name class Phylum(models.Model): name = models.CharField(maxlength=50) kingdom = models.ForeignKey(Kingdom) - def __str__(self): + def __unicode__(self): return self.name class Klass(models.Model): name = models.CharField(maxlength=50) phylum = models.ForeignKey(Phylum) - def __str__(self): + def __unicode__(self): return self.name class Order(models.Model): name = models.CharField(maxlength=50) klass = models.ForeignKey(Klass) - def __str__(self): + def __unicode__(self): return self.name class Family(models.Model): name = models.CharField(maxlength=50) order = models.ForeignKey(Order) - def __str__(self): + def __unicode__(self): return self.name class Genus(models.Model): name = models.CharField(maxlength=50) family = models.ForeignKey(Family) - def __str__(self): + def __unicode__(self): return self.name class Species(models.Model): name = models.CharField(maxlength=50) genus = models.ForeignKey(Genus) - def __str__(self): + def __unicode__(self): return self.name def create_tree(stringtree): diff --git a/tests/modeltests/serializers/models.py b/tests/modeltests/serializers/models.py index 8d44d5eae7..b7543f9348 100644 --- a/tests/modeltests/serializers/models.py +++ b/tests/modeltests/serializers/models.py @@ -13,7 +13,7 @@ class Category(models.Model): class Meta: ordering = ('name',) - def __str__(self): + def __unicode__(self): return self.name class Author(models.Model): @@ -22,7 +22,7 @@ class Author(models.Model): class Meta: ordering = ('name',) - def __str__(self): + def __unicode__(self): return self.name class Article(models.Model): @@ -34,15 +34,15 @@ class Article(models.Model): class Meta: ordering = ('pub_date',) - def __str__(self): + def __unicode__(self): return self.headline class AuthorProfile(models.Model): author = models.OneToOneField(Author) date_of_birth = models.DateField() - def __str__(self): - return "Profile of %s" % self.author + def __unicode__(self): + return u"Profile of %s" % self.author __test__ = {'API_TESTS':""" # Create some data: diff --git a/tests/modeltests/str/models.py b/tests/modeltests/str/models.py index 81230d538c..b4d3adcd6d 100644 --- a/tests/modeltests/str/models.py +++ b/tests/modeltests/str/models.py @@ -1,23 +1,39 @@ +# -*- coding: utf-8 -*- """ -2. Adding __str__() to models +2. Adding __str__() or __unicode__() to models -Although it's not a strict requirement, each model should have a ``__str__()`` -method to return a "human-readable" representation of the object. Do this not -only for your own sanity when dealing with the interactive prompt, but also -because objects' representations are used throughout Django's -automatically-generated admin. +Although it's not a strict requirement, each model should have a +``_str__()`` or ``__unicode__()`` method to return a "human-readable" +representation of the object. Do this not only for your own sanity when dealing +with the interactive prompt, but also because objects' representations are used +throughout Django's automatically-generated admin. + +Normally, you should write ``__unicode__``() method, since this will work for +all field types (and Django will automatically provide an appropriate +``__str__()`` method). However, you can write a ``__str__()`` method directly, +if you prefer. You must be careful to encode the results correctly, though. """ from django.db import models +from django.utils.encoding import smart_str class Article(models.Model): headline = models.CharField(maxlength=100) pub_date = models.DateTimeField() def __str__(self): + # Caution: this is only safe if you are certain that headline will be + # in ASCII. + return self.headline + +class InternationalArticle(models.Model): + headline = models.CharField(maxlength=100) + pub_date = models.DateTimeField() + + def __unicode__(self): return self.headline -__test__ = {'API_TESTS':""" +__test__ = {'API_TESTS':ur""" # Create an Article. >>> from datetime import datetime >>> a = Article(headline='Area man programs in Python', pub_date=datetime(2005, 7, 28)) @@ -28,4 +44,10 @@ __test__ = {'API_TESTS':""" >>> a <Article: Area man programs in Python> + +>>> a1 = InternationalArticle(headline=u'Girl wins €12.500 in lottery', pub_date=datetime(2005, 7, 28)) + +# The default str() output will be the UTF-8 encoded output of __unicode__(). +>>> str(a1) +'Girl wins \xe2\x82\xac12.500 in lottery' """} diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index 5ebf29678c..06e574590f 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -1,3 +1,4 @@ +# coding: utf-8 """ 38. Testing using the Test Client @@ -27,11 +28,14 @@ class ClientTest(TestCase): def test_get_view(self): "GET a view" - response = self.client.get('/test_client/get_view/') + # The data is ignored, but let's check it doesn't crash the system + # anyway. + data = {'var': u'\xf2'} + response = self.client.get('/test_client/get_view/', data) # Check some response details self.assertContains(response, 'This is a test') - self.assertEqual(response.context['var'], 42) + self.assertEqual(response.context['var'], u'\xf2') self.assertEqual(response.template.name, 'GET Template') def test_get_post_view(self): @@ -281,4 +285,4 @@ class ClientTest(TestCase): self.assertEqual(mail.outbox[1].from_email, 'from@example.com') self.assertEqual(mail.outbox[1].to[0], 'second@example.com') self.assertEqual(mail.outbox[1].to[1], 'third@example.com') -
\ No newline at end of file + diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py index 9bdf213b35..21f577d758 100644 --- a/tests/modeltests/test_client/views.py +++ b/tests/modeltests/test_client/views.py @@ -10,7 +10,7 @@ from django.shortcuts import render_to_response def get_view(request): "A simple view that expects a GET request, and returns a rendered template" t = Template('This is a test. {{ var }} is the value.', name='GET Template') - c = Context({'var': 42}) + c = Context({'var': request.GET.get('var', 42)}) return HttpResponse(t.render(c)) diff --git a/tests/modeltests/transactions/models.py b/tests/modeltests/transactions/models.py index e1fad8063e..d7eba6e4d3 100644 --- a/tests/modeltests/transactions/models.py +++ b/tests/modeltests/transactions/models.py @@ -14,8 +14,8 @@ class Reporter(models.Model): last_name = models.CharField(maxlength=30) email = models.EmailField() - def __str__(self): - return "%s %s" % (self.first_name, self.last_name) + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) __test__ = {'API_TESTS':""" >>> from django.db import connection, transaction @@ -96,4 +96,4 @@ Exception: I meant to do that Traceback (most recent call last): ... TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK -"""
\ No newline at end of file +""" diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py index b31f981aac..5be2f867a4 100644 --- a/tests/modeltests/validation/models.py +++ b/tests/modeltests/validation/models.py @@ -17,7 +17,7 @@ class Person(models.Model): favorite_moment = models.DateTimeField() email = models.EmailField() - def __str__(self): + def __unicode__(self): return self.name __test__ = {'API_TESTS':""" @@ -42,7 +42,7 @@ __test__ = {'API_TESTS':""" >>> p = Person(**dict(valid_params, id='foo')) >>> p.validate() -{'id': ['This value must be an integer.']} +{'id': [u'This value must be an integer.']} >>> p = Person(**dict(valid_params, id=None)) >>> p.validate() @@ -76,7 +76,7 @@ False >>> p = Person(**dict(valid_params, is_child='foo')) >>> p.validate() -{'is_child': ['This value must be either True or False.']} +{'is_child': [u'This value must be either True or False.']} >>> p = Person(**dict(valid_params, name=u'Jose')) >>> p.validate() @@ -88,7 +88,7 @@ u'Jose' >>> p.validate() {} >>> p.name -'227' +u'227' >>> p = Person(**dict(valid_params, birthdate=datetime.date(2000, 5, 3))) >>> p.validate() @@ -116,7 +116,7 @@ datetime.date(2000, 5, 3) >>> p = Person(**dict(valid_params, birthdate='foo')) >>> p.validate() -{'birthdate': ['Enter a valid date in YYYY-MM-DD format.']} +{'birthdate': [u'Enter a valid date in YYYY-MM-DD format.']} >>> p = Person(**dict(valid_params, favorite_moment=datetime.datetime(2002, 4, 3, 13, 23))) >>> p.validate() @@ -144,10 +144,10 @@ u'john@example.com' >>> p = Person(**dict(valid_params, email=22)) >>> p.validate() -{'email': ['Enter a valid e-mail address.']} +{'email': [u'Enter a valid e-mail address.']} # Make sure that Date and DateTime return validation errors and don't raise Python errors. >>> Person(name='John Doe', is_child=True, email='abc@def.com').validate() -{'favorite_moment': ['This field is required.'], 'birthdate': ['This field is required.']} +{'favorite_moment': [u'This field is required.'], 'birthdate': [u'This field is required.']} """} diff --git a/tests/regressiontests/dateformat/tests.py b/tests/regressiontests/dateformat/tests.py index f9f84145c5..30c9a4e6dd 100644 --- a/tests/regressiontests/dateformat/tests.py +++ b/tests/regressiontests/dateformat/tests.py @@ -1,54 +1,54 @@ r""" >>> format(my_birthday, '') -'' +u'' >>> format(my_birthday, 'a') -'p.m.' +u'p.m.' >>> format(my_birthday, 'A') -'PM' +u'PM' >>> format(my_birthday, 'd') -'08' +u'08' >>> format(my_birthday, 'j') -'8' +u'8' >>> format(my_birthday, 'l') -'Sunday' +u'Sunday' >>> format(my_birthday, 'L') -'False' +u'False' >>> format(my_birthday, 'm') -'07' +u'07' >>> format(my_birthday, 'M') -'Jul' +u'Jul' >>> format(my_birthday, 'b') -'jul' +u'jul' >>> format(my_birthday, 'n') -'7' +u'7' >>> format(my_birthday, 'N') -'July' +u'July' >>> no_tz or format(my_birthday, 'O') == '+0100' True >>> format(my_birthday, 'P') -'10 p.m.' +u'10 p.m.' >>> no_tz or format(my_birthday, 'r') == 'Sun, 8 Jul 1979 22:00:00 +0100' True >>> format(my_birthday, 's') -'00' +u'00' >>> format(my_birthday, 'S') -'th' +u'th' >>> format(my_birthday, 't') -'31' +u'31' >>> no_tz or format(my_birthday, 'T') == 'CET' True >>> no_tz or format(my_birthday, 'U') == '300531600' True >>> format(my_birthday, 'w') -'0' +u'0' >>> format(my_birthday, 'W') -'27' +u'27' >>> format(my_birthday, 'y') -'79' +u'79' >>> format(my_birthday, 'Y') -'1979' +u'1979' >>> format(my_birthday, 'z') -'189' +u'189' >>> no_tz or format(my_birthday, 'Z') == '3600' True @@ -62,10 +62,10 @@ True True >>> format(my_birthday, r'Y z \C\E\T') -'1979 189 CET' +u'1979 189 CET' >>> format(my_birthday, r'jS o\f F') -'8th of July' +u'8th of July' """ from django.utils import dateformat, translation diff --git a/tests/regressiontests/defaultfilters/tests.py b/tests/regressiontests/defaultfilters/tests.py index b35636aba6..a1efae66f6 100644 --- a/tests/regressiontests/defaultfilters/tests.py +++ b/tests/regressiontests/defaultfilters/tests.py @@ -2,197 +2,211 @@ r""" >>> floatformat(7.7) -'7.7' +u'7.7' >>> floatformat(7.0) -'7' +u'7' >>> floatformat(0.7) -'0.7' +u'0.7' >>> floatformat(0.07) -'0.1' +u'0.1' >>> floatformat(0.007) -'0.0' +u'0.0' >>> floatformat(0.0) -'0' +u'0' >>> floatformat(7.7,3) -'7.700' +u'7.700' >>> floatformat(6.000000,3) -'6.000' +u'6.000' >>> floatformat(13.1031,-3) -'13.103' +u'13.103' >>> floatformat(11.1197, -2) -'11.12' +u'11.12' >>> floatformat(11.0000, -2) -'11' +u'11' >>> floatformat(11.000001, -2) -'11.00' +u'11.00' >>> floatformat(8.2798, 3) -'8.280' ->>> floatformat('foo') -'' ->>> floatformat(13.1031, 'bar') -'13.1031' ->>> floatformat('foo', 'bar') -'' +u'8.280' +>>> floatformat(u'foo') +u'' +>>> floatformat(13.1031, u'bar') +u'13.1031' +>>> floatformat(u'foo', u'bar') +u'' ->>> addslashes('"double quotes" and \'single quotes\'') -'\\"double quotes\\" and \\\'single quotes\\\'' +>>> addslashes(u'"double quotes" and \'single quotes\'') +u'\\"double quotes\\" and \\\'single quotes\\\'' ->>> addslashes(r'\ : backslashes, too') -'\\\\ : backslashes, too' +>>> addslashes(ur'\ : backslashes, too') +u'\\\\ : backslashes, too' ->>> capfirst('hello world') -'Hello world' +>>> capfirst(u'hello world') +u'Hello world' ->>> fix_ampersands('Jack & Jill & Jeroboam') -'Jack & Jill & Jeroboam' +>>> fix_ampersands(u'Jack & Jill & Jeroboam') +u'Jack & Jill & Jeroboam' ->>> linenumbers('line 1\nline 2') -'1. line 1\n2. line 2' +>>> linenumbers(u'line 1\nline 2') +u'1. line 1\n2. line 2' ->>> linenumbers('\n'.join(['x'] * 10)) -'01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. x\n08. x\n09. x\n10. x' +>>> linenumbers(u'\n'.join([u'x'] * 10)) +u'01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. x\n08. x\n09. x\n10. x' >>> lower('TEST') -'test' +u'test' >>> lower(u'\xcb') # uppercase E umlaut u'\xeb' >>> make_list('abc') -['a', 'b', 'c'] +[u'a', u'b', u'c'] >>> make_list(1234) -['1', '2', '3', '4'] +[u'1', u'2', u'3', u'4'] >>> slugify(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/') -'jack-jill-like-numbers-123-and-4-and-silly-characters' +u'jack-jill-like-numbers-123-and-4-and-silly-characters' ->>> stringformat(1, '03d') -'001' +>>> slugify(u"Un \xe9l\xe9phant \xe0 l'or\xe9e du bois") +u'un-elephant-a-loree-du-bois' ->>> stringformat(1, 'z') -'' +>>> stringformat(1, u'03d') +u'001' + +>>> stringformat(1, u'z') +u'' >>> title('a nice title, isn\'t it?') -"A Nice Title, Isn't It?" +u"A Nice Title, Isn't It?" + +>>> title(u'discoth\xe8que') +u'Discoth\xe8que' +>>> truncatewords(u'A sentence with a few words in it', 1) +u'A ...' ->>> truncatewords('A sentence with a few words in it', 1) -'A ...' +>>> truncatewords(u'A sentence with a few words in it', 5) +u'A sentence with a few ...' ->>> truncatewords('A sentence with a few words in it', 5) -'A sentence with a few ...' +>>> truncatewords(u'A sentence with a few words in it', 100) +u'A sentence with a few words in it' ->>> truncatewords('A sentence with a few words in it', 100) -'A sentence with a few words in it' +>>> truncatewords(u'A sentence with a few words in it', 'not a number') +u'A sentence with a few words in it' ->>> truncatewords('A sentence with a few words in it', 'not a number') -'A sentence with a few words in it' +>>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 0) +u'' ->>> truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 0) -'' +>>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 2) +u'<p>one <a href="#">two ...</a></p>' ->>> truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 2) -'<p>one <a href="#">two ...</a></p>' +>>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 4) +u'<p>one <a href="#">two - three <br>four ...</a></p>' ->>> truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 4) -'<p>one <a href="#">two - three <br>four ...</a></p>' +>>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 5) +u'<p>one <a href="#">two - three <br>four</a> five</p>' ->>> truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 5) -'<p>one <a href="#">two - three <br>four</a> five</p>' +>>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 100) +u'<p>one <a href="#">two - three <br>four</a> five</p>' ->>> truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 100) -'<p>one <a href="#">two - three <br>four</a> five</p>' +>>> truncatewords_html(u'\xc5ngstr\xf6m was here', 1) +u'\xc5ngstr\xf6m ...' ->>> upper('Mixed case input') -'MIXED CASE INPUT' +>>> upper(u'Mixed case input') +u'MIXED CASE INPUT' >>> upper(u'\xeb') # lowercase e umlaut u'\xcb' ->>> urlencode('jack & jill') -'jack%20%26%20jill' +>>> urlencode(u'fran\xe7ois & jill') +u'fran%C3%A7ois%20%26%20jill' >>> urlencode(1) -'1' +u'1' +>>> iriencode(u'S\xf8r-Tr\xf8ndelag') +u'S%C3%B8r-Tr%C3%B8ndelag' +>>> iriencode(urlencode(u'fran\xe7ois & jill')) +u'fran%C3%A7ois%20%26%20jill' +>>> urlizetrunc(u'http://short.com/', 20) +u'<a href="http://short.com/" rel="nofollow">http://short.com/</a>' ->>> urlizetrunc('http://short.com/', 20) -'<a href="http://short.com/" rel="nofollow">http://short.com/</a>' +>>> urlizetrunc(u'http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20) +u'<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=" rel="nofollow">http://www.google....</a>' >>> urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20) -'<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=" rel="nofollow">http://www.google...</a>' +u'<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=" rel="nofollow">http://www.google...</a>' # Check truncating of URIs which are the exact length >>> uri = 'http://31characteruri.com/test/' >>> len(uri) 31 >>> urlizetrunc(uri, 31) -'<a href="http://31characteruri.com/test/" rel="nofollow">http://31characteruri.com/test/</a>' +u'<a href="http://31characteruri.com/test/" rel="nofollow">http://31characteruri.com/test/</a>' >>> urlizetrunc(uri, 30) -'<a href="http://31characteruri.com/test/" rel="nofollow">http://31characteruri.com/t...</a>' +u'<a href="http://31characteruri.com/test/" rel="nofollow">http://31characteruri.com/t...</a>' >>> urlizetrunc(uri, 2) -'<a href="http://31characteruri.com/test/" rel="nofollow">...</a>' +u'<a href="http://31characteruri.com/test/" rel="nofollow">...</a>' >>> wordcount('') 0 ->>> wordcount('oneword') +>>> wordcount(u'oneword') 1 ->>> wordcount('lots of words') +>>> wordcount(u'lots of words') 3 ->>> wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14) -"this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid" +>>> wordwrap(u'this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14) +u"this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid" ->>> wordwrap('this is a short paragraph of text.\n But this line should be indented',14) -'this is a\nshort\nparagraph of\ntext.\n But this\nline should be\nindented' +>>> wordwrap(u'this is a short paragraph of text.\n But this line should be indented',14) +u'this is a\nshort\nparagraph of\ntext.\n But this\nline should be\nindented' ->>> wordwrap('this is a short paragraph of text.\n But this line should be indented',15) -'this is a short\nparagraph of\ntext.\n But this line\nshould be\nindented' +>>> wordwrap(u'this is a short paragraph of text.\n But this line should be indented',15) +u'this is a short\nparagraph of\ntext.\n But this line\nshould be\nindented' ->>> ljust('test', 10) -'test ' +>>> ljust(u'test', 10) +u'test ' ->>> ljust('test', 3) -'test' +>>> ljust(u'test', 3) +u'test' ->>> rjust('test', 10) -' test' +>>> rjust(u'test', 10) +u' test' ->>> rjust('test', 3) -'test' +>>> rjust(u'test', 3) +u'test' ->>> center('test', 6) -' test ' +>>> center(u'test', 6) +u' test ' ->>> cut('a string to be mangled', 'a') -' string to be mngled' +>>> cut(u'a string to be mangled', 'a') +u' string to be mngled' ->>> cut('a string to be mangled', 'ng') -'a stri to be maled' +>>> cut(u'a string to be mangled', 'ng') +u'a stri to be maled' ->>> cut('a string to be mangled', 'strings') -'a string to be mangled' +>>> cut(u'a string to be mangled', 'strings') +u'a string to be mangled' ->>> escape('<some html & special characters > here') -'<some html & special characters > here' +>>> escape(u'<some html & special characters > here') +u'<some html & special characters > here' >>> escape(u'<some html & special characters > here ĐÅ€£') u'<some html & special characters > here \xc4\x90\xc3\x85\xe2\x82\xac\xc2\xa3' ->>> linebreaks('line 1') -'<p>line 1</p>' +>>> linebreaks(u'line 1') +u'<p>line 1</p>' ->>> linebreaks('line 1\nline 2') -'<p>line 1<br />line 2</p>' +>>> linebreaks(u'line 1\nline 2') +u'<p>line 1<br />line 2</p>' ->>> removetags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img') -'some <b>html</b> with alert("You smell") disallowed tags' +>>> removetags(u'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img') +u'some <b>html</b> with alert("You smell") disallowed tags' ->>> striptags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags') -'some html with alert("You smell") disallowed tags' +>>> striptags(u'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags') +u'some html with alert("You smell") disallowed tags' >>> dictsort([{'age': 23, 'name': 'Barbara-Ann'}, ... {'age': 63, 'name': 'Ra Ra Rasputin'}, @@ -207,16 +221,16 @@ u'<some html & special characters > here \xc4\x90\xc3\x85\xe2\x82\xac\ >>> first([0,1,2]) 0 ->>> first('') -'' +>>> first(u'') +u'' ->>> first('test') -'t' +>>> first(u'test') +u't' ->>> join([0,1,2], 'glue') -'0glue1glue2' +>>> join([0,1,2], u'glue') +u'0glue1glue2' ->>> length('1234') +>>> length(u'1234') 4 >>> length([1,2,3,4]) @@ -231,37 +245,37 @@ False >>> length_is('a', 1) True ->>> length_is('a', 10) +>>> length_is(u'a', 10) False ->>> slice_('abcdefg', '0') -'' +>>> slice_(u'abcdefg', u'0') +u'' ->>> slice_('abcdefg', '1') -'a' +>>> slice_(u'abcdefg', u'1') +u'a' ->>> slice_('abcdefg', '-1') -'abcdef' +>>> slice_(u'abcdefg', u'-1') +u'abcdef' ->>> slice_('abcdefg', '1:2') -'b' +>>> slice_(u'abcdefg', u'1:2') +u'b' ->>> slice_('abcdefg', '1:3') -'bc' +>>> slice_(u'abcdefg', u'1:3') +u'bc' ->>> slice_('abcdefg', '0::2') -'aceg' +>>> slice_(u'abcdefg', u'0::2') +u'aceg' ->>> unordered_list(['item 1', []]) -'\t<li>item 1</li>' +>>> unordered_list([u'item 1', []]) +u'\t<li>item 1</li>' ->>> unordered_list(['item 1', [['item 1.1', []]]]) -'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>' +>>> unordered_list([u'item 1', [[u'item 1.1', []]]]) +u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>' ->>> unordered_list(['item 1', [['item 1.1', []], ['item 1.2', []]]]) -'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>' +>>> unordered_list([u'item 1', [[u'item 1.1', []], [u'item 1.2', []]]]) +u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>' ->>> add('1', '2') +>>> add(u'1', u'2') 3 >>> get_digit(123, 1) @@ -279,43 +293,43 @@ False >>> get_digit(123, 0) 123 ->>> get_digit('xyz', 0) -'xyz' +>>> get_digit(u'xyz', 0) +u'xyz' # real testing of date() is in dateformat.py ->>> date(datetime.datetime(2005, 12, 29), "d F Y") -'29 December 2005' ->>> date(datetime.datetime(2005, 12, 29), r'jS o\f F') -'29th of December' +>>> date(datetime.datetime(2005, 12, 29), u"d F Y") +u'29 December 2005' +>>> date(datetime.datetime(2005, 12, 29), ur'jS o\f F') +u'29th of December' # real testing of time() is done in dateformat.py ->>> time(datetime.time(13), "h") -'01' +>>> time(datetime.time(13), u"h") +u'01' ->>> time(datetime.time(0), "h") -'12' +>>> time(datetime.time(0), u"h") +u'12' # real testing is done in timesince.py, where we can provide our own 'now' >>> timesince(datetime.datetime.now() - datetime.timedelta(1)) -'1 day' +u'1 day' ->>> default("val", "default") -'val' +>>> default(u"val", u"default") +u'val' ->>> default(None, "default") -'default' +>>> default(None, u"default") +u'default' ->>> default('', "default") -'default' +>>> default(u'', u"default") +u'default' ->>> default_if_none("val", "default") -'val' +>>> default_if_none(u"val", u"default") +u'val' ->>> default_if_none(None, "default") -'default' +>>> default_if_none(None, u"default") +u'default' ->>> default_if_none('', "default") -'' +>>> default_if_none(u'', u"default") +u'' >>> divisibleby(4, 2) True @@ -324,139 +338,139 @@ True False >>> yesno(True) -'yes' +u'yes' >>> yesno(False) -'no' +u'no' >>> yesno(None) -'maybe' +u'maybe' ->>> yesno(True, 'certainly,get out of town,perhaps') -'certainly' +>>> yesno(True, u'certainly,get out of town,perhaps') +u'certainly' ->>> yesno(False, 'certainly,get out of town,perhaps') -'get out of town' +>>> yesno(False, u'certainly,get out of town,perhaps') +u'get out of town' ->>> yesno(None, 'certainly,get out of town,perhaps') -'perhaps' +>>> yesno(None, u'certainly,get out of town,perhaps') +u'perhaps' ->>> yesno(None, 'certainly,get out of town') -'get out of town' +>>> yesno(None, u'certainly,get out of town') +u'get out of town' >>> filesizeformat(1023) -'1023 bytes' +u'1023 bytes' >>> filesizeformat(1024) -'1.0 KB' +u'1.0 KB' >>> filesizeformat(10*1024) -'10.0 KB' +u'10.0 KB' >>> filesizeformat(1024*1024-1) -'1024.0 KB' +u'1024.0 KB' >>> filesizeformat(1024*1024) -'1.0 MB' +u'1.0 MB' >>> filesizeformat(1024*1024*50) -'50.0 MB' +u'50.0 MB' >>> filesizeformat(1024*1024*1024-1) -'1024.0 MB' +u'1024.0 MB' >>> filesizeformat(1024*1024*1024) -'1.0 GB' +u'1.0 GB' >>> pluralize(1) -'' +u'' >>> pluralize(0) -'s' +u's' >>> pluralize(2) -'s' +u's' >>> pluralize([1]) -'' +u'' >>> pluralize([]) -'s' +u's' >>> pluralize([1,2,3]) -'s' +u's' ->>> pluralize(1,'es') -'' +>>> pluralize(1,u'es') +u'' ->>> pluralize(0,'es') -'es' +>>> pluralize(0,u'es') +u'es' ->>> pluralize(2,'es') -'es' +>>> pluralize(2,u'es') +u'es' ->>> pluralize(1,'y,ies') -'y' +>>> pluralize(1,u'y,ies') +u'y' ->>> pluralize(0,'y,ies') -'ies' +>>> pluralize(0,u'y,ies') +u'ies' ->>> pluralize(2,'y,ies') -'ies' +>>> pluralize(2,u'y,ies') +u'ies' ->>> pluralize(0,'y,ies,error') -'' +>>> pluralize(0,u'y,ies,error') +u'' ->>> phone2numeric('0800 flowers') -'0800 3569377' +>>> phone2numeric(u'0800 flowers') +u'0800 3569377' # Filters shouldn't break if passed non-strings >>> addslashes(123) -'123' +u'123' >>> linenumbers(123) -'1. 123' +u'1. 123' >>> lower(123) -'123' +u'123' >>> make_list(123) -['1', '2', '3'] +[u'1', u'2', u'3'] >>> slugify(123) -'123' +u'123' >>> title(123) -'123' +u'123' >>> truncatewords(123, 2) -'123' +u'123' >>> upper(123) -'123' +u'123' >>> urlencode(123) -'123' +u'123' >>> urlize(123) -'123' +u'123' >>> urlizetrunc(123, 1) -'123' +u'123' >>> wordcount(123) 1 >>> wordwrap(123, 2) -'123' +u'123' >>> ljust('123', 4) -'123 ' +u'123 ' >>> rjust('123', 4) -' 123' +u' 123' >>> center('123', 5) -' 123 ' +u' 123 ' >>> center('123', 6) -' 123 ' +u' 123 ' >>> cut(123, '2') -'13' +u'13' >>> escape(123) -'123' +u'123' >>> linebreaks(123) -'<p>123</p>' +u'<p>123</p>' >>> linebreaksbr(123) -'123' +u'123' >>> removetags(123, 'a') -'123' +u'123' >>> striptags(123) -'123' +u'123' """ diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index dd407df353..31528238e9 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -4,8 +4,8 @@ class Animal(models.Model): name = models.CharField(maxlength=150) latin_name = models.CharField(maxlength=150) - def __str__(self): - return self.common_name + def __unicode__(self): + return self.common_name class Plant(models.Model): name = models.CharField(maxlength=150) @@ -26,4 +26,4 @@ __test__ = {'API_TESTS':""" >>> animal = Animal(name='Platypus', latin_name='Ornithorhynchus anatinus') >>> animal.save() -"""}
\ No newline at end of file +"""} diff --git a/tests/regressiontests/forms/localflavor.py b/tests/regressiontests/forms/localflavor.py index ede89de2a0..252aa10b34 100644 --- a/tests/regressiontests/forms/localflavor.py +++ b/tests/regressiontests/forms/localflavor.py @@ -1303,9 +1303,9 @@ strict. >>> rut = CLRutField() >>> rut.clean('11-6') -'11-6' +u'11-6' >>> rut.clean('116') -'11-6' +u'11-6' # valid format, bad verifier. >>> rut.clean('11.111.111-0') @@ -1318,13 +1318,13 @@ Traceback (most recent call last): ValidationError: [u'The Chilean RUT is not valid.'] >>> rut.clean('767484100') -'76.748.410-0' +u'76.748.410-0' >>> rut.clean('78.412.790-7') -'78.412.790-7' +u'78.412.790-7' >>> rut.clean('8.334.6043') -'8.334.604-3' +u'8.334.604-3' >>> rut.clean('76793310-K') -'76.793.310-K' +u'76.793.310-K' Strict RUT usage (does not allow imposible values) >>> rut = CLRutField(strict=True) @@ -1346,7 +1346,7 @@ Traceback (most recent call last): ... ValidationError: [u'Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'] >>> rut.clean('78.412.790-7') -'78.412.790-7' +u'78.412.790-7' >>> rut.clean('8.334.6043') Traceback (most recent call last): ... diff --git a/tests/regressiontests/forms/regressions.py b/tests/regressiontests/forms/regressions.py index 5fe057b5d8..784ef49902 100644 --- a/tests/regressiontests/forms/regressions.py +++ b/tests/regressiontests/forms/regressions.py @@ -16,24 +16,63 @@ u'<p>F1: <input type="text" class="special" name="f1" maxlength="10" /></p>\n<p> ####################### There were some problems with form translations in #3600 ->>> from django.utils.translation import gettext_lazy, activate, deactivate +>>> from django.utils.translation import ugettext_lazy, activate, deactivate >>> class SomeForm(Form): -... username = CharField(max_length=10, label=gettext_lazy('Username')) +... username = CharField(max_length=10, label=ugettext_lazy('Username')) >>> f = SomeForm() >>> print f.as_p() <p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p> + +Translations are done at rendering time, so multi-lingual apps can define forms +early and still send back the right translation. + +# XFAIL >>> activate('de') >>> print f.as_p() <p><label for="id_username">Benutzername:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p> +>>> activate('pl') +>>> f.as_p() +u'<p><label for="id_username">Nazwa u\u017cytkownika:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p>' >>> deactivate() Unicode decoding problems... ->>> GENDERS = (('0', u'En tied\xe4'), ('1', u'Mies'), ('2', u'Nainen')) +>>> GENDERS = ((u'\xc5', u'En tied\xe4'), (u'\xf8', u'Mies'), (u'\xdf', u'Nainen')) >>> class SomeForm(Form): -... somechoice = ChoiceField(choices=GENDERS, widget=RadioSelect()) +... somechoice = ChoiceField(choices=GENDERS, widget=RadioSelect(), label=u'\xc5\xf8\xdf') >>> f = SomeForm() >>> f.as_p() -u'<p><label for="id_somechoice_0">Somechoice:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="0" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="1" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="2" name="somechoice" /> Nainen</label></li>\n</ul></p>' +u'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>' + +Testing choice validation with UTF-8 bytestrings as input (these are the +Russian abbreviations "мес." and "шт.". + +>>> UNITS = (('\xd0\xbc\xd0\xb5\xd1\x81.', '\xd0\xbc\xd0\xb5\xd1\x81.'), ('\xd1\x88\xd1\x82.', '\xd1\x88\xd1\x82.')) +>>> f = ChoiceField(choices=UNITS) +>>> f.clean(u'\u0448\u0442.') +u'\u0448\u0442.' +>>> f.clean('\xd1\x88\xd1\x82.') +u'\u0448\u0442.' + +Translated error messages used to be buggy. +>>> activate('ru') +>>> f = SomeForm({}) +>>> f.as_p() +u'<ul class="errorlist"><li>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>' +>>> deactivate() + +####################### +# Miscellaneous Tests # +####################### + +There once was a problem with Form fields called "data". Let's make sure that +doesn't come back. +>>> class DataForm(Form): +... data = CharField(max_length=10) +>>> f = DataForm({'data': 'xyzzy'}) +>>> f.is_valid() +True +>>> f.cleaned_data +{'data': u'xyzzy'} ####################### # Miscellaneous Tests # diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 892498c3ae..d862e96441 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3375,7 +3375,7 @@ does not have help text, nothing will be output. <input type="submit" /> </form> >>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)})) -'' +u'' The label_tag() method takes an optional attrs argument: a dictionary of HTML attributes to add to the <label> tag. diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py index e7245104e9..9d5ca2006a 100644 --- a/tests/regressiontests/httpwrappers/tests.py +++ b/tests/regressiontests/httpwrappers/tests.py @@ -94,7 +94,7 @@ MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>" >>> q['name'] = 'john' >>> q['name'] -'john' +u'john' >>> del q['name'] >>> 'name' in q @@ -106,10 +106,10 @@ False 'default' >>> q.get('name', 'default') -'john' +u'john' >>> q.getlist('name') -['john'] +[u'john'] >>> q.getlist('foo') [] @@ -117,18 +117,18 @@ False >>> q.setlist('foo', ['bar', 'baz']) >>> q.get('foo', 'default') -'baz' +u'baz' >>> q.getlist('foo') -['bar', 'baz'] +[u'bar', u'baz'] >>> q.appendlist('foo', 'another') >>> q.getlist('foo') -['bar', 'baz', 'another'] +[u'bar', u'baz', u'another'] >>> q['foo'] -'another' +u'another' >>> q.has_key('foo') True @@ -137,16 +137,16 @@ True True >>> q.items() -[('foo', 'another'), ('name', 'john')] +[(u'foo', u'another'), (u'name', u'john')] >>> q.lists() -[('foo', ['bar', 'baz', 'another']), ('name', ['john'])] +[(u'foo', [u'bar', u'baz', u'another']), (u'name', [u'john'])] >>> q.keys() -['foo', 'name'] +[u'foo', u'name'] >>> q.values() -['another', 'john'] +[u'another', u'john'] >>> len(q) 2 @@ -155,16 +155,16 @@ True # Displays last value >>> q['foo'] -'hello' +u'hello' >>> q.get('foo', 'not available') -'hello' +u'hello' >>> q.getlist('foo') -['bar', 'baz', 'another', 'hello'] +[u'bar', u'baz', u'another', u'hello'] >>> q.pop('foo') -['bar', 'baz', 'another', 'hello'] +[u'bar', u'baz', u'another', u'hello'] >>> q.pop('foo', 'not there') 'not there' @@ -173,13 +173,13 @@ True 'not there' >>> q.setdefault('foo', 'bar') -'bar' +u'bar' >>> q['foo'] -'bar' +u'bar' >>> q.getlist('foo') -['bar'] +[u'bar'] >>> q.urlencode() 'foo=bar&name=john' @@ -196,12 +196,12 @@ True >>> q = QueryDict('foo=bar') >>> q['foo'] -'bar' +u'bar' >>> q['bar'] Traceback (most recent call last): ... -MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {'foo': ['bar']}>" +MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {u'foo': [u'bar']}>" >>> q['something'] = 'bar' Traceback (most recent call last): @@ -209,13 +209,13 @@ Traceback (most recent call last): AttributeError: This QueryDict instance is immutable >>> q.get('foo', 'default') -'bar' +u'bar' >>> q.get('bar', 'default') 'default' >>> q.getlist('foo') -['bar'] +[u'bar'] >>> q.getlist('bar') [] @@ -243,16 +243,16 @@ False False >>> q.items() -[('foo', 'bar')] +[(u'foo', u'bar')] >>> q.lists() -[('foo', ['bar'])] +[(u'foo', [u'bar'])] >>> q.keys() -['foo'] +[u'foo'] >>> q.values() -['bar'] +[u'bar'] >>> len(q) 1 @@ -292,7 +292,7 @@ AttributeError: This QueryDict instance is immutable >>> q = QueryDict('vote=yes&vote=no') >>> q['vote'] -'no' +u'no' >>> q['something'] = 'bar' Traceback (most recent call last): @@ -300,13 +300,13 @@ Traceback (most recent call last): AttributeError: This QueryDict instance is immutable >>> q.get('vote', 'default') -'no' +u'no' >>> q.get('foo', 'default') 'default' >>> q.getlist('vote') -['yes', 'no'] +[u'yes', u'no'] >>> q.getlist('foo') [] @@ -334,16 +334,16 @@ False False >>> q.items() -[('vote', 'no')] +[(u'vote', u'no')] >>> q.lists() -[('vote', ['yes', 'no'])] +[(u'vote', [u'yes', u'no'])] >>> q.keys() -['vote'] +[u'vote'] >>> q.values() -['no'] +[u'no'] >>> len(q) 1 @@ -381,6 +381,16 @@ Traceback (most recent call last): ... AttributeError: This QueryDict instance is immutable +# QueryDicts must be able to handle invalid input encoding (in this case, bad +# UTF-8 encoding). +>>> q = QueryDict('foo=bar&foo=\xff') + +>>> q['foo'] +u'\ufffd' + +>>> q.getlist('foo') +[u'bar', u'\ufffd'] + """ from django.http import QueryDict diff --git a/tests/regressiontests/humanize/tests.py b/tests/regressiontests/humanize/tests.py index eca65f7575..f94d642973 100644 --- a/tests/regressiontests/humanize/tests.py +++ b/tests/regressiontests/humanize/tests.py @@ -15,7 +15,7 @@ class HumanizeTests(unittest.TestCase): self.assertEqual(rendered, result_list[index], msg="""%s test failed, produced %s, should've produced %s""" % (method, rendered, result_list[index])) - + def test_ordinal(self): test_list = ('1','2','3','4','11','12', '13','101','102','103','111', @@ -43,12 +43,12 @@ should've produced %s""" % (method, rendered, result_list[index])) self.humanize_tester(test_list, result_list, 'intword') def test_apnumber(self): - test_list = [str(x) for x in xrange(1,11)] - result_list = ('one', 'two', 'three', 'four', 'five', 'six', - 'seven', 'eight', 'nine', '10') + test_list = [str(x) for x in range(1, 11)] + result_list = (u'one', u'two', u'three', u'four', u'five', u'six', + u'seven', u'eight', u'nine', u'10') self.humanize_tester(test_list, result_list, 'apnumber') if __name__ == '__main__': unittest.main() - + diff --git a/tests/regressiontests/i18n/__init__.py b/tests/regressiontests/i18n/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/__init__.py diff --git a/tests/regressiontests/i18n/models.py b/tests/regressiontests/i18n/models.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/models.py diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py new file mode 100644 index 0000000000..8a7d2bee3e --- /dev/null +++ b/tests/regressiontests/i18n/tests.py @@ -0,0 +1,33 @@ +# coding: utf-8 + +ur""" +Format string interpolation should work with *_lazy objects. + +>>> from django.utils.translation import ugettext_lazy, activate, deactivate, gettext_lazy +>>> s = ugettext_lazy('Add %(name)s') +>>> d = {'name': 'Ringo'} +>>> s % d +u'Add Ringo' +>>> activate('de') +>>> s % d +u'Ringo hinzuf\xfcgen' +>>> activate('pl') +>>> s % d +u'Dodaj Ringo' +>>> deactivate() + +It should be possible to compare *_lazy objects. + +>>> s1 = ugettext_lazy('Add %(name)s') +>>> s == s1 +True +>>> s2 = gettext_lazy('Add %(name)s') +>>> s3 = gettext_lazy('Add %(name)s') +>>> s2 == s3 +True +>>> s == s2 +True +>>> s4 = ugettext_lazy('Some other string') +>>> s == s4 +False +""" diff --git a/tests/regressiontests/model_regress/__init__.py b/tests/regressiontests/model_regress/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/model_regress/__init__.py diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py new file mode 100644 index 0000000000..b4d432d8fa --- /dev/null +++ b/tests/regressiontests/model_regress/models.py @@ -0,0 +1,34 @@ +# coding: utf-8 +from django.db import models + +CHOICES = ( + (1, 'first'), + (2, 'second'), +) + +class Article(models.Model): + headline = models.CharField(maxlength=100, default='Default headline') + pub_date = models.DateTimeField() + status = models.IntegerField(blank=True, null=True, choices=CHOICES) + + class Meta: + ordering = ('pub_date','headline') + # A utf-8 verbose name (Ångström's Articles) to test they are valid. + verbose_name = "\xc3\x85ngstr\xc3\xb6m's Articles" + + def __unicode__(self): + return self.headline + +__test__ = {'API_TESTS': """ +(NOTE: Part of the regression test here is merely parsing the model +declaration. The verbose_name, in particular, did not always work.) + +An empty choice field should return None for the display name. + +>>> from datetime import datetime +>>> a = Article(headline="Look at me!", pub_date=datetime.now()) +>>> a.save() +>>> a.get_status_display() is None +True +""" +} diff --git a/tests/regressiontests/null_queries/models.py b/tests/regressiontests/null_queries/models.py index 21944d9e7a..2e903876bf 100644 --- a/tests/regressiontests/null_queries/models.py +++ b/tests/regressiontests/null_queries/models.py @@ -3,15 +3,15 @@ from django.db import models class Poll(models.Model): question = models.CharField(maxlength=200) - def __str__(self): - return "Q: %s " % self.question + def __unicode__(self): + return u"Q: %s " % self.question class Choice(models.Model): poll = models.ForeignKey(Poll) choice = models.CharField(maxlength=200) - def __str__(self): - return "Choice: %s in poll %s" % (self.choice, self.poll) + def __unicode__(self): + return u"Choice: %s in poll %s" % (self.choice, self.poll) __test__ = {'API_TESTS':""" # Regression test for the use of None as a query value. None is interpreted as diff --git a/tests/regressiontests/one_to_one_regress/models.py b/tests/regressiontests/one_to_one_regress/models.py index b81f4266e1..be48c842ed 100644 --- a/tests/regressiontests/one_to_one_regress/models.py +++ b/tests/regressiontests/one_to_one_regress/models.py @@ -4,23 +4,23 @@ class Place(models.Model): name = models.CharField(maxlength=50) address = models.CharField(maxlength=80) - def __str__(self): - return "%s the place" % self.name + def __unicode__(self): + return u"%s the place" % self.name class Restaurant(models.Model): place = models.OneToOneField(Place) serves_hot_dogs = models.BooleanField() serves_pizza = models.BooleanField() - def __str__(self): - return "%s the restaurant" % self.place.name + def __unicode__(self): + return u"%s the restaurant" % self.place.name class Favorites(models.Model): name = models.CharField(maxlength = 50) restaurants = models.ManyToManyField(Restaurant) - def __str__(self): - return "Favorites for %s" % self.name + def __unicode__(self): + return u"Favorites for %s" % self.name __test__ = {'API_TESTS':""" # Regression test for #1064 and #1506: Check that we create models via the m2m diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index febcfa822e..7c6da9d356 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -111,6 +111,9 @@ test_data = [ (data_obj, 13, CharData, "null"), (data_obj, 14, CharData, "NULL"), (data_obj, 15, CharData, None), + # (We use something that will fit into a latin1 database encoding here, + # because that is still the default used on many system setups.) + (data_obj, 16, CharData, u'\xa5'), (data_obj, 20, DateData, datetime.date(2006,6,16)), (data_obj, 21, DateData, None), (data_obj, 30, DateTimeData, datetime.datetime(2006,6,16,10,42,37)), diff --git a/tests/regressiontests/string_lookup/models.py b/tests/regressiontests/string_lookup/models.py index 441bb3f8a3..66651ce680 100644 --- a/tests/regressiontests/string_lookup/models.py +++ b/tests/regressiontests/string_lookup/models.py @@ -1,9 +1,11 @@ +# -*- coding: utf-8 -*- from django.db import models class Foo(models.Model): name = models.CharField(maxlength=50) + friend = models.CharField(maxlength=50, blank=True) - def __str__(self): + def __unicode__(self): return "Foo %s" % self.name class Bar(models.Model): @@ -12,35 +14,35 @@ class Bar(models.Model): fwd = models.ForeignKey("Whiz") back = models.ForeignKey("Foo") - def __str__(self): + def __unicode__(self): return "Bar %s" % self.place.name class Whiz(models.Model): name = models.CharField(maxlength = 50) - def __str__(self): + def __unicode__(self): return "Whiz %s" % self.name class Child(models.Model): parent = models.OneToOneField('Base') name = models.CharField(maxlength = 50) - def __str__(self): + def __unicode__(self): return "Child %s" % self.name - + class Base(models.Model): name = models.CharField(maxlength = 50) - def __str__(self): + def __unicode__(self): return "Base %s" % self.name -__test__ = {'API_TESTS':""" -# Regression test for #1661 and #1662: Check that string form referencing of models works, -# both as pre and post reference, on all RelatedField types. +__test__ = {'API_TESTS': ur""" +# Regression test for #1661 and #1662: Check that string form referencing of +# models works, both as pre and post reference, on all RelatedField types. >>> f1 = Foo(name="Foo1") >>> f1.save() ->>> f2 = Foo(name="Foo1") +>>> f2 = Foo(name="Foo2") >>> f2.save() >>> w1 = Whiz(name="Whiz1") @@ -56,7 +58,7 @@ __test__ = {'API_TESTS':""" <Whiz: Whiz Whiz1> >>> b1.back -<Foo: Foo Foo1> +<Foo: Foo Foo2> >>> base1 = Base(name="Base1") >>> base1.save() @@ -66,4 +68,18 @@ __test__ = {'API_TESTS':""" >>> child1.parent <Base: Base Base1> + +# Regression tests for #3937: make sure we can use unicode characters in +# queries. +# BUG: These tests fail on MySQL, but it's a problem with the test setup. A +# properly configured UTF-8 database can handle this. + +>>> fx = Foo(name='Bjorn', friend=u'François') +>>> fx.save() +>>> Foo.objects.get(friend__contains=u'\xe7') +<Foo: Foo Bjorn> + +# We can also do the above query using UTF-8 strings. +>>> Foo.objects.get(friend__contains='\xc3\xa7') +<Foo: Foo Bjorn> """} diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 8801100bcc..5b4ff10bdb 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -8,11 +8,17 @@ if __name__ == '__main__': from django import template from django.template import loader -from django.utils.translation import activate, deactivate, install +from django.utils.translation import activate, deactivate, install, ugettext as _ from django.utils.tzinfo import LocalTimezone from datetime import datetime, timedelta +from unicode import unicode_tests import unittest +# Some other tests we would like to run +__test__ = { + 'unicode': unicode_tests, +} + ################################# # Custom template tag for tests # ################################# @@ -63,10 +69,10 @@ class OtherClass: def method(self): return "OtherClass.method" -class UnicodeInStrClass: - "Class whose __str__ returns a Unicode object." +class UTF8Class: + "Class whose __str__ returns non-ASCII data" def __str__(self): - return u'ŠĐĆŽćžšđ' + return u'ŠĐĆŽćžšđ'.encode('utf-8') class Templates(unittest.TestCase): def test_templates(self): @@ -215,9 +221,9 @@ class Templates(unittest.TestCase): # Empty strings can be passed as arguments to filters 'filter-syntax17': (r'{{ var|join:"" }}', {'var': ['a', 'b', 'c']}, 'abc'), - # If a variable has a __str__() that returns a Unicode object, the - # value will be converted to a bytestring. - 'filter-syntax18': (r'{{ var }}', {'var': UnicodeInStrClass()}, '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91'), + # Make sure that any unicode strings are converted to bytestrings + # in the final output. + 'filter-syntax18': (r'{{ var }}', {'var': UTF8Class()}, u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'), # Numbers as filter arguments should work 'filter-syntax19': ('{{ var|truncatewords:1 }}', {"var": "hello world"}, "hello ..."), @@ -729,6 +735,7 @@ class Templates(unittest.TestCase): 'url02' : ('{% url regressiontests.templates.views.client_action client.id, action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'), 'url04' : ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'), + 'url05' : (u'{% url метка_оператора 1 %}', {}, '/url_tag/unicode/1/'), # Failures 'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError), diff --git a/tests/regressiontests/templates/unicode.py b/tests/regressiontests/templates/unicode.py new file mode 100644 index 0000000000..efda11c2da --- /dev/null +++ b/tests/regressiontests/templates/unicode.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +unicode_tests = ur""" +Templates can be created from unicode strings. +>>> from django.template import * +>>> t1 = Template(u'ŠĐĆŽćžšđ {{ var }}') + +Templates can also be created from bytestrings. These are assumed by encoded +using UTF-8. + +>>> s = '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91 {{ var }}' +>>> t2 = Template(s) +>>> s = '\x80\xc5\xc0' +>>> Template(s) +Traceback (most recent call last): + ... +TemplateEncodingError: Templates can only be constructed from unicode or UTF-8 strings. + +Contexts can be constructed from unicode or UTF-8 bytestrings. + +>>> c1 = Context({'var': 'foo'}) +>>> c2 = Context({u'var': 'foo'}) +>>> c3 = Context({'var': u'Đđ'}) +>>> c4 = Context({u'var': '\xc4\x90\xc4\x91'}) + +Since both templates and all four contexts represent the same thing, they all +render the same (and are returned as unicode objects). + +>>> t1.render(c3) == t2.render(c3) +True +>>> type(t1.render(c3)) +<type 'unicode'> +""" diff --git a/tests/regressiontests/templates/urls.py b/tests/regressiontests/templates/urls.py index 5fbade5c58..4ac9eb29f7 100644 --- a/tests/regressiontests/templates/urls.py +++ b/tests/regressiontests/templates/urls.py @@ -1,3 +1,4 @@ +# coding: utf-8 from django.conf.urls.defaults import * from regressiontests.templates import views @@ -8,4 +9,5 @@ urlpatterns = patterns('', (r'^client/(\d+)/$', views.client), (r'^client/(\d+)/(?P<action>[^/]+)/$', views.client_action), url(r'^named-client/(\d+)/$', views.client, name="named.client"), + url(r'^unicode/(\d+)/$', views.client, name=u"метка_оператора"), ) diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 40d022a47a..f03615e961 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -4,6 +4,7 @@ Regression tests for the Test Client, especially the customized assertions. """ from django.test import Client, TestCase from django.core import mail +import os class AssertTemplateUsedTests(TestCase): fixtures = ['testdata.json'] @@ -59,7 +60,7 @@ class AssertTemplateUsedTests(TestCase): try: self.assertTemplateUsed(response, "Valid POST Template") except AssertionError, e: - self.assertEquals(str(e), "Template 'Valid POST Template' was not one of the templates used to render the response. Templates used: ['form_view.html', 'base.html']") + self.assertEquals(str(e), "Template 'Valid POST Template' was not one of the templates used to render the response. Templates used: form_view.html, base.html") class AssertRedirectsTests(TestCase): def test_redirect_page(self): @@ -69,7 +70,7 @@ class AssertRedirectsTests(TestCase): try: self.assertRedirects(response, '/test_client/get_view/') except AssertionError, e: - self.assertEquals(str(e), "Response didn't redirect as expected: Reponse code was 301 (expected 302)") + self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)") def test_incorrect_target(self): "An assertion is raised if the response redirects to another target" @@ -78,10 +79,10 @@ class AssertRedirectsTests(TestCase): # Should redirect to get_view self.assertRedirects(response, '/test_client/some_view/') except AssertionError, e: - self.assertEquals(str(e), "Response didn't redirect as expected: Reponse code was 301 (expected 302)") + self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)") def test_target_page(self): - "An assertion is raised if the reponse redirect target cannot be retrieved as expected" + "An assertion is raised if the response redirect target cannot be retrieved as expected" response = self.client.get('/test_client/double_redirect_view/') try: # The redirect target responds with a 301 code, not 200 @@ -162,3 +163,12 @@ class AssertFormErrorTests(TestCase): except AssertionError, e: self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])") +class AssertFileUploadTests(TestCase): + def test_simple_upload(self): + fd = open(os.path.join(os.path.dirname(__file__), "views.py")) + post_data = { + 'name': 'Ringo', + 'file_field': fd, + } + response = self.client.post('/test_client_regress/file_upload/', post_data) + self.assertEqual(response.status_code, 200) diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py index e9cd0aea15..160f9f992d 100644 --- a/tests/regressiontests/test_client_regress/urls.py +++ b/tests/regressiontests/test_client_regress/urls.py @@ -1,7 +1,7 @@ from django.conf.urls.defaults import * -from django.views.generic.simple import redirect_to import views urlpatterns = patterns('', (r'^no_template_view/$', views.no_template_view), + (r'^file_upload/$', views.file_upload_view), ) diff --git a/tests/regressiontests/test_client_regress/views.py b/tests/regressiontests/test_client_regress/views.py index d8dd2b349c..8728ab0d7d 100644 --- a/tests/regressiontests/test_client_regress/views.py +++ b/tests/regressiontests/test_client_regress/views.py @@ -1,8 +1,20 @@ from django.core.mail import EmailMessage, SMTPConnection -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseServerError from django.shortcuts import render_to_response def no_template_view(request): "A simple view that expects a GET request, and returns a rendered template" return HttpResponse("No template used") +def file_upload_view(request): + """ + Check that a file upload can be updated into the POST dictionary without + going pear-shaped. + """ + form_data = request.POST.copy() + form_data.update(request.FILES) + if isinstance(form_data['file_field'], dict) and isinstance(form_data['name'], unicode): + return HttpResponse('') + else: + return HttpResponseServerError() + diff --git a/tests/regressiontests/text/tests.py b/tests/regressiontests/text/tests.py index f758ecaf90..0fd22b58b0 100644 --- a/tests/regressiontests/text/tests.py +++ b/tests/regressiontests/text/tests.py @@ -1,17 +1,38 @@ -""" -# Tests for stuff in django.utils.text. +# coding: utf-8 +r""" +# Tests for stuff in django.utils.text and other text munging util functions. >>> from django.utils.text import * ### smart_split ########################################################### >>> list(smart_split(r'''This is "a person" test.''')) -['This', 'is', '"a person"', 'test.'] +[u'This', u'is', u'"a person"', u'test.'] >>> print list(smart_split(r'''This is "a person's" test.'''))[2] "a person's" ->>> print list(smart_split(r'''This is "a person\\"s" test.'''))[2] +>>> print list(smart_split(r'''This is "a person\"s" test.'''))[2] "a person"s" >>> list(smart_split('''"a 'one''')) -['"a', "'one"] +[u'"a', u"'one"] >>> print list(smart_split(r'''all friends' tests'''))[1] friends' + +### urlquote ############################################################# +>>> from django.utils.http import urlquote, urlquote_plus +>>> urlquote(u'Paris & Orl\xe9ans') +u'Paris%20%26%20Orl%C3%A9ans' +>>> urlquote_plus(u'Paris & Orl\xe9ans') +u'Paris+%26+Orl%C3%A9ans' + +### iri_to_uri ########################################################### +>>> from django.utils.encoding import iri_to_uri +>>> iri_to_uri(u'red%09ros\xe9#red') +'red%09ros%C3%A9#red' +>>> iri_to_uri(u'/blog/for/J\xfcrgen M\xfcnster/') +'/blog/for/J%C3%BCrgen%20M%C3%BCnster/' +>>> iri_to_uri(u'locations/%s' % urlquote_plus(u'Paris & Orl\xe9ans')) +'locations/Paris+%26+Orl%C3%A9ans' + +iri_to_uri() is idempotent: +>>> iri_to_uri(iri_to_uri(u'red%09ros\xe9#red')) +'red%09ros%C3%A9#red' """ diff --git a/tests/runtests.py b/tests/runtests.py index 7d1ee1e29c..5a76cf5a18 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -126,6 +126,7 @@ def django_tests(verbosity, tests_to_run): for model_dir, model_name in get_invalid_models(): model_label = '.'.join([model_dir, model_name]) if not tests_to_run or model_name in tests_to_run: + print >> sys.stderr,'****', model_label extra_tests.append(InvalidModelTestCase(model_label)) # Run the test suite, including the extra validation tests. |
