diff options
author | Nishanth Amuluru | 2011-01-11 22:41:51 +0530 |
---|---|---|
committer | Nishanth Amuluru | 2011-01-11 22:41:51 +0530 |
commit | b03203c8cb991c16ac8a3d74c8c4078182d0bb48 (patch) | |
tree | 7cf13b2deacbfaaec99edb431b83ddd5ea734a52 /parts/django/tests | |
parent | 0c50203cd9eb94b819883c3110922e873f003138 (diff) | |
download | pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.gz pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.bz2 pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.zip |
removed all the buildout files
Diffstat (limited to 'parts/django/tests')
817 files changed, 0 insertions, 62439 deletions
diff --git a/parts/django/tests/modeltests/__init__.py b/parts/django/tests/modeltests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/aggregation/__init__.py b/parts/django/tests/modeltests/aggregation/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/aggregation/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/aggregation/fixtures/initial_data.json b/parts/django/tests/modeltests/aggregation/fixtures/initial_data.json deleted file mode 100644 index a002100..0000000 --- a/parts/django/tests/modeltests/aggregation/fixtures/initial_data.json +++ /dev/null @@ -1,243 +0,0 @@ -[ - { - "pk": 1, - "model": "aggregation.publisher", - "fields": { - "name": "Apress", - "num_awards": 3 - } - }, - { - "pk": 2, - "model": "aggregation.publisher", - "fields": { - "name": "Sams", - "num_awards": 1 - } - }, - { - "pk": 3, - "model": "aggregation.publisher", - "fields": { - "name": "Prentice Hall", - "num_awards": 7 - } - }, - { - "pk": 4, - "model": "aggregation.publisher", - "fields": { - "name": "Morgan Kaufmann", - "num_awards": 9 - } - }, - { - "pk": 5, - "model": "aggregation.publisher", - "fields": { - "name": "Jonno's House of Books", - "num_awards": 0 - } - }, - { - "pk": 1, - "model": "aggregation.book", - "fields": { - "publisher": 1, - "isbn": "159059725", - "name": "The Definitive Guide to Django: Web Development Done Right", - "price": "30.00", - "rating": 4.5, - "authors": [1, 2], - "contact": 1, - "pages": 447, - "pubdate": "2007-12-6" - } - }, - { - "pk": 2, - "model": "aggregation.book", - "fields": { - "publisher": 2, - "isbn": "067232959", - "name": "Sams Teach Yourself Django in 24 Hours", - "price": "23.09", - "rating": 3.0, - "authors": [3], - "contact": 3, - "pages": 528, - "pubdate": "2008-3-3" - } - }, - { - "pk": 3, - "model": "aggregation.book", - "fields": { - "publisher": 1, - "isbn": "159059996", - "name": "Practical Django Projects", - "price": "29.69", - "rating": 4.0, - "authors": [4], - "contact": 4, - "pages": 300, - "pubdate": "2008-6-23" - } - }, - { - "pk": 4, - "model": "aggregation.book", - "fields": { - "publisher": 3, - "isbn": "013235613", - "name": "Python Web Development with Django", - "price": "29.69", - "rating": 4.0, - "authors": [5, 6, 7], - "contact": 5, - "pages": 350, - "pubdate": "2008-11-3" - } - }, - { - "pk": 5, - "model": "aggregation.book", - "fields": { - "publisher": 3, - "isbn": "013790395", - "name": "Artificial Intelligence: A Modern Approach", - "price": "82.80", - "rating": 4.0, - "authors": [8, 9], - "contact": 8, - "pages": 1132, - "pubdate": "1995-1-15" - } - }, - { - "pk": 6, - "model": "aggregation.book", - "fields": { - "publisher": 4, - "isbn": "155860191", - "name": "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", - "price": "75.00", - "rating": 5.0, - "authors": [8], - "contact": 8, - "pages": 946, - "pubdate": "1991-10-15" - } - }, - { - "pk": 1, - "model": "aggregation.store", - "fields": { - "books": [1, 2, 3, 4, 5, 6], - "name": "Amazon.com", - "original_opening": "1994-4-23 9:17:42", - "friday_night_closing": "23:59:59" - } - }, - { - "pk": 2, - "model": "aggregation.store", - "fields": { - "books": [1, 3, 5, 6], - "name": "Books.com", - "original_opening": "2001-3-15 11:23:37", - "friday_night_closing": "23:59:59" - } - }, - { - "pk": 3, - "model": "aggregation.store", - "fields": { - "books": [3, 4, 6], - "name": "Mamma and Pappa's Books", - "original_opening": "1945-4-25 16:24:14", - "friday_night_closing": "21:30:00" - } - }, - { - "pk": 1, - "model": "aggregation.author", - "fields": { - "age": 34, - "friends": [2, 4], - "name": "Adrian Holovaty" - } - }, - { - "pk": 2, - "model": "aggregation.author", - "fields": { - "age": 35, - "friends": [1, 7], - "name": "Jacob Kaplan-Moss" - } - }, - { - "pk": 3, - "model": "aggregation.author", - "fields": { - "age": 45, - "friends": [], - "name": "Brad Dayley" - } - }, - { - "pk": 4, - "model": "aggregation.author", - "fields": { - "age": 29, - "friends": [1], - "name": "James Bennett" - } - }, - { - "pk": 5, - "model": "aggregation.author", - "fields": { - "age": 37, - "friends": [6, 7], - "name": "Jeffrey Forcier" - } - }, - { - "pk": 6, - "model": "aggregation.author", - "fields": { - "age": 29, - "friends": [5, 7], - "name": "Paul Bissex" - } - }, - { - "pk": 7, - "model": "aggregation.author", - "fields": { - "age": 25, - "friends": [2, 5, 6], - "name": "Wesley J. Chun" - } - }, - { - "pk": 8, - "model": "aggregation.author", - "fields": { - "age": 57, - "friends": [9], - "name": "Peter Norvig" - } - }, - { - "pk": 9, - "model": "aggregation.author", - "fields": { - "age": 46, - "friends": [8], - "name": "Stuart Russell" - } - } -] diff --git a/parts/django/tests/modeltests/aggregation/models.py b/parts/django/tests/modeltests/aggregation/models.py deleted file mode 100644 index ccc1289..0000000 --- a/parts/django/tests/modeltests/aggregation/models.py +++ /dev/null @@ -1,42 +0,0 @@ -# coding: utf-8 -from django.db import models - - -class Author(models.Model): - name = models.CharField(max_length=100) - age = models.IntegerField() - friends = models.ManyToManyField('self', blank=True) - - def __unicode__(self): - return self.name - -class Publisher(models.Model): - name = models.CharField(max_length=255) - num_awards = models.IntegerField() - - def __unicode__(self): - return self.name - -class Book(models.Model): - isbn = models.CharField(max_length=9) - name = models.CharField(max_length=255) - pages = models.IntegerField() - rating = models.FloatField() - price = models.DecimalField(decimal_places=2, max_digits=6) - authors = models.ManyToManyField(Author) - contact = models.ForeignKey(Author, related_name='book_contact_set') - publisher = models.ForeignKey(Publisher) - pubdate = models.DateField() - - def __unicode__(self): - return self.name - -class Store(models.Model): - name = models.CharField(max_length=255) - books = models.ManyToManyField(Book) - original_opening = models.DateTimeField() - friday_night_closing = models.TimeField() - - def __unicode__(self): - return self.name - diff --git a/parts/django/tests/modeltests/aggregation/tests.py b/parts/django/tests/modeltests/aggregation/tests.py deleted file mode 100644 index c830368..0000000 --- a/parts/django/tests/modeltests/aggregation/tests.py +++ /dev/null @@ -1,565 +0,0 @@ -import datetime -from decimal import Decimal - -from django.db.models import Avg, Sum, Count, Max, Min -from django.test import TestCase, Approximate - -from models import Author, Publisher, Book, Store - - -class BaseAggregateTestCase(TestCase): - fixtures = ["initial_data.json"] - - def test_empty_aggregate(self): - self.assertEqual(Author.objects.all().aggregate(), {}) - - def test_single_aggregate(self): - vals = Author.objects.aggregate(Avg("age")) - self.assertEqual(vals, {"age__avg": Approximate(37.4, places=1)}) - - def test_multiple_aggregates(self): - vals = Author.objects.aggregate(Sum("age"), Avg("age")) - self.assertEqual(vals, {"age__sum": 337, "age__avg": Approximate(37.4, places=1)}) - - def test_filter_aggregate(self): - vals = Author.objects.filter(age__gt=29).aggregate(Sum("age")) - self.assertEqual(len(vals), 1) - self.assertEqual(vals["age__sum"], 254) - - def test_related_aggregate(self): - vals = Author.objects.aggregate(Avg("friends__age")) - self.assertEqual(len(vals), 1) - self.assertAlmostEqual(vals["friends__age__avg"], 34.07, places=2) - - vals = Book.objects.filter(rating__lt=4.5).aggregate(Avg("authors__age")) - self.assertEqual(len(vals), 1) - self.assertAlmostEqual(vals["authors__age__avg"], 38.2857, places=2) - - vals = Author.objects.all().filter(name__contains="a").aggregate(Avg("book__rating")) - self.assertEqual(len(vals), 1) - self.assertEqual(vals["book__rating__avg"], 4.0) - - vals = Book.objects.aggregate(Sum("publisher__num_awards")) - self.assertEqual(len(vals), 1) - self.assertEquals(vals["publisher__num_awards__sum"], 30) - - vals = Publisher.objects.aggregate(Sum("book__price")) - self.assertEqual(len(vals), 1) - self.assertEqual(vals["book__price__sum"], Decimal("270.27")) - - def test_aggregate_multi_join(self): - vals = Store.objects.aggregate(Max("books__authors__age")) - self.assertEqual(len(vals), 1) - self.assertEqual(vals["books__authors__age__max"], 57) - - vals = Author.objects.aggregate(Min("book__publisher__num_awards")) - self.assertEqual(len(vals), 1) - self.assertEqual(vals["book__publisher__num_awards__min"], 1) - - def test_aggregate_alias(self): - vals = Store.objects.filter(name="Amazon.com").aggregate(amazon_mean=Avg("books__rating")) - self.assertEqual(len(vals), 1) - self.assertAlmostEqual(vals["amazon_mean"], 4.08, places=2) - - def test_annotate_basic(self): - self.assertQuerysetEqual( - Book.objects.annotate().order_by('pk'), [ - "The Definitive Guide to Django: Web Development Done Right", - "Sams Teach Yourself Django in 24 Hours", - "Practical Django Projects", - "Python Web Development with Django", - "Artificial Intelligence: A Modern Approach", - "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp" - ], - lambda b: b.name - ) - - books = Book.objects.annotate(mean_age=Avg("authors__age")) - b = books.get(pk=1) - self.assertEqual( - b.name, - u'The Definitive Guide to Django: Web Development Done Right' - ) - self.assertEqual(b.mean_age, 34.5) - - def test_annotate_m2m(self): - books = Book.objects.filter(rating__lt=4.5).annotate(Avg("authors__age")).order_by("name") - self.assertQuerysetEqual( - books, [ - (u'Artificial Intelligence: A Modern Approach', 51.5), - (u'Practical Django Projects', 29.0), - (u'Python Web Development with Django', Approximate(30.3, places=1)), - (u'Sams Teach Yourself Django in 24 Hours', 45.0) - ], - lambda b: (b.name, b.authors__age__avg), - ) - - books = Book.objects.annotate(num_authors=Count("authors")).order_by("name") - self.assertQuerysetEqual( - books, [ - (u'Artificial Intelligence: A Modern Approach', 2), - (u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 1), - (u'Practical Django Projects', 1), - (u'Python Web Development with Django', 3), - (u'Sams Teach Yourself Django in 24 Hours', 1), - (u'The Definitive Guide to Django: Web Development Done Right', 2) - ], - lambda b: (b.name, b.num_authors) - ) - - def test_backwards_m2m_annotate(self): - authors = Author.objects.filter(name__contains="a").annotate(Avg("book__rating")).order_by("name") - self.assertQuerysetEqual( - authors, [ - (u'Adrian Holovaty', 4.5), - (u'Brad Dayley', 3.0), - (u'Jacob Kaplan-Moss', 4.5), - (u'James Bennett', 4.0), - (u'Paul Bissex', 4.0), - (u'Stuart Russell', 4.0) - ], - lambda a: (a.name, a.book__rating__avg) - ) - - authors = Author.objects.annotate(num_books=Count("book")).order_by("name") - self.assertQuerysetEqual( - authors, [ - (u'Adrian Holovaty', 1), - (u'Brad Dayley', 1), - (u'Jacob Kaplan-Moss', 1), - (u'James Bennett', 1), - (u'Jeffrey Forcier', 1), - (u'Paul Bissex', 1), - (u'Peter Norvig', 2), - (u'Stuart Russell', 1), - (u'Wesley J. Chun', 1) - ], - lambda a: (a.name, a.num_books) - ) - - def test_reverse_fkey_annotate(self): - books = Book.objects.annotate(Sum("publisher__num_awards")).order_by("name") - self.assertQuerysetEqual( - books, [ - (u'Artificial Intelligence: A Modern Approach', 7), - (u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 9), - (u'Practical Django Projects', 3), - (u'Python Web Development with Django', 7), - (u'Sams Teach Yourself Django in 24 Hours', 1), - (u'The Definitive Guide to Django: Web Development Done Right', 3) - ], - lambda b: (b.name, b.publisher__num_awards__sum) - ) - - publishers = Publisher.objects.annotate(Sum("book__price")).order_by("name") - self.assertQuerysetEqual( - publishers, [ - (u'Apress', Decimal("59.69")), - (u"Jonno's House of Books", None), - (u'Morgan Kaufmann', Decimal("75.00")), - (u'Prentice Hall', Decimal("112.49")), - (u'Sams', Decimal("23.09")) - ], - lambda p: (p.name, p.book__price__sum) - ) - - def test_annotate_values(self): - books = list(Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values()) - self.assertEqual( - books, [ - { - "contact_id": 1, - "id": 1, - "isbn": "159059725", - "mean_age": 34.5, - "name": "The Definitive Guide to Django: Web Development Done Right", - "pages": 447, - "price": Approximate(Decimal("30")), - "pubdate": datetime.date(2007, 12, 6), - "publisher_id": 1, - "rating": 4.5, - } - ] - ) - - books = Book.objects.filter(pk=1).annotate(mean_age=Avg('authors__age')).values('pk', 'isbn', 'mean_age') - self.assertEqual( - list(books), [ - { - "pk": 1, - "isbn": "159059725", - "mean_age": 34.5, - } - ] - ) - - books = Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values("name") - self.assertEqual( - list(books), [ - { - "name": "The Definitive Guide to Django: Web Development Done Right" - } - ] - ) - - books = Book.objects.filter(pk=1).values().annotate(mean_age=Avg('authors__age')) - self.assertEqual( - list(books), [ - { - "contact_id": 1, - "id": 1, - "isbn": "159059725", - "mean_age": 34.5, - "name": "The Definitive Guide to Django: Web Development Done Right", - "pages": 447, - "price": Approximate(Decimal("30")), - "pubdate": datetime.date(2007, 12, 6), - "publisher_id": 1, - "rating": 4.5, - } - ] - ) - - books = Book.objects.values("rating").annotate(n_authors=Count("authors__id"), mean_age=Avg("authors__age")).order_by("rating") - self.assertEqual( - list(books), [ - { - "rating": 3.0, - "n_authors": 1, - "mean_age": 45.0, - }, - { - "rating": 4.0, - "n_authors": 6, - "mean_age": Approximate(37.16, places=1) - }, - { - "rating": 4.5, - "n_authors": 2, - "mean_age": 34.5, - }, - { - "rating": 5.0, - "n_authors": 1, - "mean_age": 57.0, - } - ] - ) - - authors = Author.objects.annotate(Avg("friends__age")).order_by("name") - self.assertEqual(len(authors), 9) - self.assertQuerysetEqual( - authors, [ - (u'Adrian Holovaty', 32.0), - (u'Brad Dayley', None), - (u'Jacob Kaplan-Moss', 29.5), - (u'James Bennett', 34.0), - (u'Jeffrey Forcier', 27.0), - (u'Paul Bissex', 31.0), - (u'Peter Norvig', 46.0), - (u'Stuart Russell', 57.0), - (u'Wesley J. Chun', Approximate(33.66, places=1)) - ], - lambda a: (a.name, a.friends__age__avg) - ) - - def test_count(self): - vals = Book.objects.aggregate(Count("rating")) - self.assertEqual(vals, {"rating__count": 6}) - - vals = Book.objects.aggregate(Count("rating", distinct=True)) - self.assertEqual(vals, {"rating__count": 4}) - - def test_fkey_aggregate(self): - explicit = list(Author.objects.annotate(Count('book__id'))) - implicit = list(Author.objects.annotate(Count('book'))) - self.assertEqual(explicit, implicit) - - def test_annotate_ordering(self): - books = Book.objects.values('rating').annotate(oldest=Max('authors__age')).order_by('oldest', 'rating') - self.assertEqual( - list(books), [ - { - "rating": 4.5, - "oldest": 35, - }, - { - "rating": 3.0, - "oldest": 45 - }, - { - "rating": 4.0, - "oldest": 57, - }, - { - "rating": 5.0, - "oldest": 57, - } - ] - ) - - books = Book.objects.values("rating").annotate(oldest=Max("authors__age")).order_by("-oldest", "-rating") - self.assertEqual( - list(books), [ - { - "rating": 5.0, - "oldest": 57, - }, - { - "rating": 4.0, - "oldest": 57, - }, - { - "rating": 3.0, - "oldest": 45, - }, - { - "rating": 4.5, - "oldest": 35, - } - ] - ) - - def test_aggregate_annotation(self): - vals = Book.objects.annotate(num_authors=Count("authors__id")).aggregate(Avg("num_authors")) - self.assertEqual(vals, {"num_authors__avg": Approximate(1.66, places=1)}) - - def test_filtering(self): - p = Publisher.objects.create(name='Expensive Publisher', num_awards=0) - Book.objects.create( - name='ExpensiveBook1', - pages=1, - isbn='111', - rating=3.5, - price=Decimal("1000"), - publisher=p, - contact_id=1, - pubdate=datetime.date(2008,12,1) - ) - Book.objects.create( - name='ExpensiveBook2', - pages=1, - isbn='222', - rating=4.0, - price=Decimal("1000"), - publisher=p, - contact_id=1, - pubdate=datetime.date(2008,12,2) - ) - Book.objects.create( - name='ExpensiveBook3', - pages=1, - isbn='333', - rating=4.5, - price=Decimal("35"), - publisher=p, - contact_id=1, - pubdate=datetime.date(2008,12,3) - ) - - publishers = Publisher.objects.annotate(num_books=Count("book__id")).filter(num_books__gt=1).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Prentice Hall", - "Expensive Publisher", - ], - lambda p: p.name, - ) - - publishers = Publisher.objects.filter(book__price__lt=Decimal("40.0")).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Apress", - "Sams", - "Prentice Hall", - "Expensive Publisher", - ], - lambda p: p.name - ) - - publishers = Publisher.objects.annotate(num_books=Count("book__id")).filter(num_books__gt=1, book__price__lt=Decimal("40.0")).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Prentice Hall", - "Expensive Publisher", - ], - lambda p: p.name, - ) - - publishers = Publisher.objects.filter(book__price__lt=Decimal("40.0")).annotate(num_books=Count("book__id")).filter(num_books__gt=1).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - ], - lambda p: p.name - ) - - publishers = Publisher.objects.annotate(num_books=Count("book")).filter(num_books__range=[1, 3]).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Sams", - "Prentice Hall", - "Morgan Kaufmann", - "Expensive Publisher", - ], - lambda p: p.name - ) - - publishers = Publisher.objects.annotate(num_books=Count("book")).filter(num_books__range=[1, 2]).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Sams", - "Prentice Hall", - "Morgan Kaufmann", - ], - lambda p: p.name - ) - - publishers = Publisher.objects.annotate(num_books=Count("book")).filter(num_books__in=[1, 3]).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Sams", - "Morgan Kaufmann", - "Expensive Publisher", - ], - lambda p: p.name, - ) - - publishers = Publisher.objects.annotate(num_books=Count("book")).filter(num_books__isnull=True) - self.assertEqual(len(publishers), 0) - - def test_annotation(self): - vals = Author.objects.filter(pk=1).aggregate(Count("friends__id")) - self.assertEqual(vals, {"friends__id__count": 2}) - - books = Book.objects.annotate(num_authors=Count("authors__name")).filter(num_authors__ge=2).order_by("pk") - self.assertQuerysetEqual( - books, [ - "The Definitive Guide to Django: Web Development Done Right", - "Artificial Intelligence: A Modern Approach", - ], - lambda b: b.name - ) - - authors = Author.objects.annotate(num_friends=Count("friends__id", distinct=True)).filter(num_friends=0).order_by("pk") - self.assertQuerysetEqual( - authors, [ - "Brad Dayley", - ], - lambda a: a.name - ) - - publishers = Publisher.objects.annotate(num_books=Count("book__id")).filter(num_books__gt=1).order_by("pk") - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Prentice Hall", - ], - lambda p: p.name - ) - - publishers = Publisher.objects.filter(book__price__lt=Decimal("40.0")).annotate(num_books=Count("book__id")).filter(num_books__gt=1) - self.assertQuerysetEqual( - publishers, [ - "Apress", - ], - lambda p: p.name - ) - - books = Book.objects.annotate(num_authors=Count("authors__id")).filter(authors__name__contains="Norvig", num_authors__gt=1) - self.assertQuerysetEqual( - books, [ - "Artificial Intelligence: A Modern Approach", - ], - lambda b: b.name - ) - - def test_more_aggregation(self): - a = Author.objects.get(name__contains='Norvig') - b = Book.objects.get(name__contains='Done Right') - b.authors.add(a) - b.save() - - vals = Book.objects.annotate(num_authors=Count("authors__id")).filter(authors__name__contains="Norvig", num_authors__gt=1).aggregate(Avg("rating")) - self.assertEqual(vals, {"rating__avg": 4.25}) - - def test_even_more_aggregate(self): - publishers = Publisher.objects.annotate(earliest_book=Min("book__pubdate")).exclude(earliest_book=None).order_by("earliest_book").values() - self.assertEqual( - list(publishers), [ - { - 'earliest_book': datetime.date(1991, 10, 15), - 'num_awards': 9, - 'id': 4, - 'name': u'Morgan Kaufmann' - }, - { - 'earliest_book': datetime.date(1995, 1, 15), - 'num_awards': 7, - 'id': 3, - 'name': u'Prentice Hall' - }, - { - 'earliest_book': datetime.date(2007, 12, 6), - 'num_awards': 3, - 'id': 1, - 'name': u'Apress' - }, - { - 'earliest_book': datetime.date(2008, 3, 3), - 'num_awards': 1, - 'id': 2, - 'name': u'Sams' - } - ] - ) - - vals = Store.objects.aggregate(Max("friday_night_closing"), Min("original_opening")) - self.assertEqual( - vals, - { - "friday_night_closing__max": datetime.time(23, 59, 59), - "original_opening__min": datetime.datetime(1945, 4, 25, 16, 24, 14), - } - ) - - def test_annotate_values_list(self): - books = Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values_list("pk", "isbn", "mean_age") - self.assertEqual( - list(books), [ - (1, "159059725", 34.5), - ] - ) - - books = Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values_list("isbn") - self.assertEqual( - list(books), [ - ('159059725',) - ] - ) - - books = Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values_list("mean_age") - self.assertEqual( - list(books), [ - (34.5,) - ] - ) - - books = Book.objects.filter(pk=1).annotate(mean_age=Avg("authors__age")).values_list("mean_age", flat=True) - self.assertEqual(list(books), [34.5]) - - books = Book.objects.values_list("price").annotate(count=Count("price")).order_by("-count", "price") - self.assertEqual( - list(books), [ - (Decimal("29.69"), 2), - (Decimal('23.09'), 1), - (Decimal('30'), 1), - (Decimal('75'), 1), - (Decimal('82.8'), 1), - ] - ) diff --git a/parts/django/tests/modeltests/basic/__init__.py b/parts/django/tests/modeltests/basic/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/basic/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/basic/models.py b/parts/django/tests/modeltests/basic/models.py deleted file mode 100644 index 97552a9..0000000 --- a/parts/django/tests/modeltests/basic/models.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding: utf-8 -""" -1. Bare-bones model - -This is a basic model with only two non-primary-key fields. -""" -from django.db import models, DEFAULT_DB_ALIAS - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - - class Meta: - ordering = ('pub_date','headline') - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/basic/tests.py b/parts/django/tests/modeltests/basic/tests.py deleted file mode 100644 index bafe9a0..0000000 --- a/parts/django/tests/modeltests/basic/tests.py +++ /dev/null @@ -1,562 +0,0 @@ -from datetime import datetime -import re - -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist -from django.db import models, DEFAULT_DB_ALIAS, connection -from django.db.models.fields import FieldDoesNotExist -from django.test import TestCase - -from models import Article - - -class ModelTest(TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_lookup(self): - # No articles are in the system yet. - self.assertQuerysetEqual(Article.objects.all(), []) - - # Create an Article. - a = Article( - id=None, - headline='Area man programs in Python', - pub_date=datetime(2005, 7, 28), - ) - - # Save it into the database. You have to call save() explicitly. - a.save() - - # Now it has an ID. - self.assertTrue(a.id != None) - - # Models have a pk property that is an alias for the primary key - # attribute (by default, the 'id' attribute). - self.assertEqual(a.pk, a.id) - - # Access database columns via Python attributes. - self.assertEqual(a.headline, 'Area man programs in Python') - self.assertEqual(a.pub_date, datetime(2005, 7, 28, 0, 0)) - - # Change values by changing the attributes, then calling save(). - a.headline = 'Area woman programs in Python' - a.save() - - # Article.objects.all() returns all the articles in the database. - self.assertQuerysetEqual(Article.objects.all(), - ['<Article: Area woman programs in Python>']) - - # Django provides a rich database lookup API. - self.assertEqual(Article.objects.get(id__exact=a.id), a) - self.assertEqual(Article.objects.get(headline__startswith='Area woman'), a) - self.assertEqual(Article.objects.get(pub_date__year=2005), a) - self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7), a) - self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7, pub_date__day=28), a) - self.assertEqual(Article.objects.get(pub_date__week_day=5), a) - - # The "__exact" lookup type can be omitted, as a shortcut. - self.assertEqual(Article.objects.get(id=a.id), a) - self.assertEqual(Article.objects.get(headline='Area woman programs in Python'), a) - - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2005), - ['<Article: Area woman programs in Python>'], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2004), - [], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2005, pub_date__month=7), - ['<Article: Area woman programs in Python>'], - ) - - self.assertQuerysetEqual( - Article.objects.filter(pub_date__week_day=5), - ['<Article: Area woman programs in Python>'], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__week_day=6), - [], - ) - - # Django raises an Article.DoesNotExist exception for get() if the - # parameters don't match any object. - self.assertRaisesErrorWithMessage( - ObjectDoesNotExist, - "Article matching query does not exist.", - Article.objects.get, - id__exact=2000, - ) - - self.assertRaisesErrorWithMessage( - ObjectDoesNotExist, - "Article matching query does not exist.", - Article.objects.get, - pub_date__year=2005, - pub_date__month=8, - ) - - self.assertRaisesErrorWithMessage( - ObjectDoesNotExist, - "Article matching query does not exist.", - Article.objects.get, - pub_date__week_day=6, - ) - - # Lookup by a primary key is the most common case, so Django - # provides a shortcut for primary-key exact lookups. - # The following is identical to articles.get(id=a.id). - self.assertEqual(Article.objects.get(pk=a.id), a) - - # pk can be used as a shortcut for the primary key name in any query. - self.assertQuerysetEqual(Article.objects.filter(pk__in=[a.id]), - ["<Article: Area woman programs in Python>"]) - - # Model instances of the same type and same ID are considered equal. - a = Article.objects.get(pk=a.id) - b = Article.objects.get(pk=a.id) - self.assertEqual(a, b) - - def test_object_creation(self): - # Create an Article. - a = Article( - id=None, - headline='Area man programs in Python', - pub_date=datetime(2005, 7, 28), - ) - - # Save it into the database. You have to call save() explicitly. - a.save() - - # You can initialize a model instance using positional arguments, - # which should match the field order as defined in the model. - a2 = Article(None, 'Second article', datetime(2005, 7, 29)) - a2.save() - - self.assertNotEqual(a2.id, a.id) - self.assertEqual(a2.headline, 'Second article') - self.assertEqual(a2.pub_date, datetime(2005, 7, 29, 0, 0)) - - # ...or, you can use keyword arguments. - a3 = Article( - id=None, - headline='Third article', - pub_date=datetime(2005, 7, 30), - ) - a3.save() - - self.assertNotEqual(a3.id, a.id) - self.assertNotEqual(a3.id, a2.id) - self.assertEqual(a3.headline, 'Third article') - self.assertEqual(a3.pub_date, datetime(2005, 7, 30, 0, 0)) - - # You can also mix and match position and keyword arguments, but - # be sure not to duplicate field information. - a4 = Article(None, 'Fourth article', pub_date=datetime(2005, 7, 31)) - a4.save() - self.assertEqual(a4.headline, 'Fourth article') - - # Don't use invalid keyword arguments. - self.assertRaisesErrorWithMessage( - TypeError, - "'foo' is an invalid keyword argument for this function", - Article, - id=None, - headline='Invalid', - pub_date=datetime(2005, 7, 31), - foo='bar', - ) - - # You can leave off the value for an AutoField when creating an - # object, because it'll get filled in automatically when you save(). - a5 = Article(headline='Article 6', pub_date=datetime(2005, 7, 31)) - a5.save() - self.assertEqual(a5.headline, 'Article 6') - - # If you leave off a field with "default" set, Django will use - # the default. - a6 = Article(pub_date=datetime(2005, 7, 31)) - a6.save() - self.assertEqual(a6.headline, u'Default headline') - - # For DateTimeFields, Django saves as much precision (in seconds) - # as you give it. - a7 = Article( - headline='Article 7', - pub_date=datetime(2005, 7, 31, 12, 30), - ) - a7.save() - self.assertEqual(Article.objects.get(id__exact=a7.id).pub_date, - datetime(2005, 7, 31, 12, 30)) - - a8 = Article( - headline='Article 8', - pub_date=datetime(2005, 7, 31, 12, 30, 45), - ) - a8.save() - self.assertEqual(Article.objects.get(id__exact=a8.id).pub_date, - datetime(2005, 7, 31, 12, 30, 45)) - - # Saving an object again doesn't create a new object -- it just saves - # the old one. - current_id = a8.id - a8.save() - self.assertEqual(a8.id, current_id) - a8.headline = 'Updated article 8' - a8.save() - self.assertEqual(a8.id, current_id) - - # Check that != and == operators behave as expecte on instances - self.assertTrue(a7 != a8) - self.assertFalse(a7 == a8) - self.assertEqual(a8, Article.objects.get(id__exact=a8.id)) - - self.assertTrue(Article.objects.get(id__exact=a8.id) != Article.objects.get(id__exact=a7.id)) - self.assertFalse(Article.objects.get(id__exact=a8.id) == Article.objects.get(id__exact=a7.id)) - - # You can use 'in' to test for membership... - self.assertTrue(a8 in Article.objects.all()) - - # ... but there will often be more efficient ways if that is all you need: - self.assertTrue(Article.objects.filter(id=a8.id).exists()) - - # dates() returns a list of available dates of the given scope for - # the given field. - self.assertQuerysetEqual( - Article.objects.dates('pub_date', 'year'), - ["datetime.datetime(2005, 1, 1, 0, 0)"]) - self.assertQuerysetEqual( - Article.objects.dates('pub_date', 'month'), - ["datetime.datetime(2005, 7, 1, 0, 0)"]) - self.assertQuerysetEqual( - Article.objects.dates('pub_date', 'day'), - ["datetime.datetime(2005, 7, 28, 0, 0)", - "datetime.datetime(2005, 7, 29, 0, 0)", - "datetime.datetime(2005, 7, 30, 0, 0)", - "datetime.datetime(2005, 7, 31, 0, 0)"]) - self.assertQuerysetEqual( - Article.objects.dates('pub_date', 'day', order='ASC'), - ["datetime.datetime(2005, 7, 28, 0, 0)", - "datetime.datetime(2005, 7, 29, 0, 0)", - "datetime.datetime(2005, 7, 30, 0, 0)", - "datetime.datetime(2005, 7, 31, 0, 0)"]) - self.assertQuerysetEqual( - Article.objects.dates('pub_date', 'day', order='DESC'), - ["datetime.datetime(2005, 7, 31, 0, 0)", - "datetime.datetime(2005, 7, 30, 0, 0)", - "datetime.datetime(2005, 7, 29, 0, 0)", - "datetime.datetime(2005, 7, 28, 0, 0)"]) - - # dates() requires valid arguments. - self.assertRaisesErrorWithMessage( - TypeError, - "dates() takes at least 3 arguments (1 given)", - Article.objects.dates, - ) - - self.assertRaisesErrorWithMessage( - FieldDoesNotExist, - "Article has no field named 'invalid_field'", - Article.objects.dates, - "invalid_field", - "year", - ) - - self.assertRaisesErrorWithMessage( - AssertionError, - "'kind' must be one of 'year', 'month' or 'day'.", - Article.objects.dates, - "pub_date", - "bad_kind", - ) - - self.assertRaisesErrorWithMessage( - AssertionError, - "'order' must be either 'ASC' or 'DESC'.", - Article.objects.dates, - "pub_date", - "year", - order="bad order", - ) - - # Use iterator() with dates() to return a generator that lazily - # requests each result one at a time, to save memory. - dates = [] - for article in Article.objects.dates('pub_date', 'day', order='DESC').iterator(): - dates.append(article) - self.assertEqual(dates, [ - datetime(2005, 7, 31, 0, 0), - datetime(2005, 7, 30, 0, 0), - datetime(2005, 7, 29, 0, 0), - datetime(2005, 7, 28, 0, 0)]) - - # You can combine queries with & and |. - s1 = Article.objects.filter(id__exact=a.id) - s2 = Article.objects.filter(id__exact=a2.id) - self.assertQuerysetEqual(s1 | s2, - ["<Article: Area man programs in Python>", - "<Article: Second article>"]) - self.assertQuerysetEqual(s1 & s2, []) - - # You can get the number of objects like this: - self.assertEqual(len(Article.objects.filter(id__exact=a.id)), 1) - - # You can get items using index and slice notation. - self.assertEqual(Article.objects.all()[0], a) - self.assertQuerysetEqual(Article.objects.all()[1:3], - ["<Article: Second article>", "<Article: Third article>"]) - - s3 = Article.objects.filter(id__exact=a3.id) - self.assertQuerysetEqual((s1 | s2 | s3)[::2], - ["<Article: Area man programs in Python>", - "<Article: Third article>"]) - - # Slicing works with longs. - self.assertEqual(Article.objects.all()[0L], a) - self.assertQuerysetEqual(Article.objects.all()[1L:3L], - ["<Article: Second article>", "<Article: Third article>"]) - self.assertQuerysetEqual((s1 | s2 | s3)[::2L], - ["<Article: Area man programs in Python>", - "<Article: Third article>"]) - - # And can be mixed with ints. - self.assertQuerysetEqual(Article.objects.all()[1:3L], - ["<Article: Second article>", "<Article: Third article>"]) - - # Slices (without step) are lazy: - self.assertQuerysetEqual(Article.objects.all()[0:5].filter(), - ["<Article: Area man programs in Python>", - "<Article: Second article>", - "<Article: Third article>", - "<Article: Article 6>", - "<Article: Default headline>"]) - - # Slicing again works: - self.assertQuerysetEqual(Article.objects.all()[0:5][0:2], - ["<Article: Area man programs in Python>", - "<Article: Second article>"]) - self.assertQuerysetEqual(Article.objects.all()[0:5][:2], - ["<Article: Area man programs in Python>", - "<Article: Second article>"]) - self.assertQuerysetEqual(Article.objects.all()[0:5][4:], - ["<Article: Default headline>"]) - self.assertQuerysetEqual(Article.objects.all()[0:5][5:], []) - - # Some more tests! - self.assertQuerysetEqual(Article.objects.all()[2:][0:2], - ["<Article: Third article>", "<Article: Article 6>"]) - self.assertQuerysetEqual(Article.objects.all()[2:][:2], - ["<Article: Third article>", "<Article: Article 6>"]) - self.assertQuerysetEqual(Article.objects.all()[2:][2:3], - ["<Article: Default headline>"]) - - # Using an offset without a limit is also possible. - self.assertQuerysetEqual(Article.objects.all()[5:], - ["<Article: Fourth article>", - "<Article: Article 7>", - "<Article: Updated article 8>"]) - - # Also, once you have sliced you can't filter, re-order or combine - self.assertRaisesErrorWithMessage( - AssertionError, - "Cannot filter a query once a slice has been taken.", - Article.objects.all()[0:5].filter, - id=a.id, - ) - - self.assertRaisesErrorWithMessage( - AssertionError, - "Cannot reorder a query once a slice has been taken.", - Article.objects.all()[0:5].order_by, - 'id', - ) - - try: - Article.objects.all()[0:1] & Article.objects.all()[4:5] - self.fail('Should raise an AssertionError') - except AssertionError, e: - self.assertEqual(str(e), "Cannot combine queries once a slice has been taken.") - except Exception, e: - self.fail('Should raise an AssertionError, not %s' % e) - - # Negative slices are not supported, due to database constraints. - # (hint: inverting your ordering might do what you need). - try: - Article.objects.all()[-1] - self.fail('Should raise an AssertionError') - except AssertionError, e: - self.assertEqual(str(e), "Negative indexing is not supported.") - except Exception, e: - self.fail('Should raise an AssertionError, not %s' % e) - - error = None - try: - Article.objects.all()[0:-5] - except Exception, e: - error = e - self.assertTrue(isinstance(error, AssertionError)) - self.assertEqual(str(error), "Negative indexing is not supported.") - - # An Article instance doesn't have access to the "objects" attribute. - # That's only available on the class. - self.assertRaisesErrorWithMessage( - AttributeError, - "Manager isn't accessible via Article instances", - getattr, - a7, - "objects", - ) - - # Bulk delete test: How many objects before and after the delete? - self.assertQuerysetEqual(Article.objects.all(), - ["<Article: Area man programs in Python>", - "<Article: Second article>", - "<Article: Third article>", - "<Article: Article 6>", - "<Article: Default headline>", - "<Article: Fourth article>", - "<Article: Article 7>", - "<Article: Updated article 8>"]) - Article.objects.filter(id__lte=a4.id).delete() - self.assertQuerysetEqual(Article.objects.all(), - ["<Article: Article 6>", - "<Article: Default headline>", - "<Article: Article 7>", - "<Article: Updated article 8>"]) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].startswith('django.db.backends.postgresql'): - def test_microsecond_precision(self): - # In PostgreSQL, microsecond-level precision is available. - a9 = Article( - headline='Article 9', - pub_date=datetime(2005, 7, 31, 12, 30, 45, 180), - ) - a9.save() - self.assertEqual(Article.objects.get(pk=a9.pk).pub_date, - datetime(2005, 7, 31, 12, 30, 45, 180)) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql': - def test_microsecond_precision_not_supported(self): - # In MySQL, microsecond-level precision isn't available. You'll lose - # microsecond-level precision once the data is saved. - a9 = Article( - headline='Article 9', - pub_date=datetime(2005, 7, 31, 12, 30, 45, 180), - ) - a9.save() - self.assertEqual(Article.objects.get(id__exact=a9.id).pub_date, - datetime(2005, 7, 31, 12, 30, 45)) - - def test_manually_specify_primary_key(self): - # You can manually specify the primary key when creating a new object. - a101 = Article( - id=101, - headline='Article 101', - pub_date=datetime(2005, 7, 31, 12, 30, 45), - ) - a101.save() - a101 = Article.objects.get(pk=101) - self.assertEqual(a101.headline, u'Article 101') - - def test_create_method(self): - # 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), - ) - self.assertEqual(Article.objects.get(headline="Article 10"), a10) - - def test_year_lookup_edge_case(self): - # Edge-case test: A year lookup should retrieve all objects in - # the given year, including Jan. 1 and Dec. 31. - a11 = Article.objects.create( - headline='Article 11', - pub_date=datetime(2008, 1, 1), - ) - a12 = Article.objects.create( - headline='Article 12', - pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999), - ) - self.assertQuerysetEqual(Article.objects.filter(pub_date__year=2008), - ["<Article: Article 11>", "<Article: Article 12>"]) - - def test_unicode_data(self): - # Unicode data works, too. - a = Article( - headline=u'\u6797\u539f \u3081\u3050\u307f', - pub_date=datetime(2005, 7, 28), - ) - a.save() - self.assertEqual(Article.objects.get(pk=a.id).headline, - u'\u6797\u539f \u3081\u3050\u307f') - - def test_hash_function(self): - # 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. - a10 = Article.objects.create( - headline="Article 10", - pub_date=datetime(2005, 7, 31, 12, 30, 45), - ) - a11 = Article.objects.create( - headline='Article 11', - pub_date=datetime(2008, 1, 1), - ) - a12 = Article.objects.create( - headline='Article 12', - pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999), - ) - - s = set([a10, a11, a12]) - self.assertTrue(Article.objects.get(headline='Article 11') in s) - - def test_extra_method_select_argument_with_dashes_and_values(self): - # The 'select' argument to extra() supports names with dashes in - # them, as long as you use values(). - a10 = Article.objects.create( - headline="Article 10", - pub_date=datetime(2005, 7, 31, 12, 30, 45), - ) - a11 = Article.objects.create( - headline='Article 11', - pub_date=datetime(2008, 1, 1), - ) - a12 = Article.objects.create( - headline='Article 12', - pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999), - ) - - dicts = Article.objects.filter( - pub_date__year=2008).extra( - select={'dashed-value': '1'} - ).values('headline', 'dashed-value') - self.assertEqual([sorted(d.items()) for d in dicts], - [[('dashed-value', 1), ('headline', u'Article 11')], [('dashed-value', 1), ('headline', u'Article 12')]]) - - def test_extra_method_select_argument_with_dashes(self): - # If you use 'select' with extra() and names containing dashes on a - # query that's *not* a values() query, those extra 'select' values - # will silently be ignored. - a10 = Article.objects.create( - headline="Article 10", - pub_date=datetime(2005, 7, 31, 12, 30, 45), - ) - a11 = Article.objects.create( - headline='Article 11', - pub_date=datetime(2008, 1, 1), - ) - a12 = Article.objects.create( - headline='Article 12', - pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999), - ) - - articles = Article.objects.filter( - pub_date__year=2008).extra( - select={'dashed-value': '1', 'undashedvalue': '2'}) - self.assertEqual(articles[0].undashedvalue, 2) diff --git a/parts/django/tests/modeltests/choices/__init__.py b/parts/django/tests/modeltests/choices/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/choices/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/choices/models.py b/parts/django/tests/modeltests/choices/models.py deleted file mode 100644 index 27316f5..0000000 --- a/parts/django/tests/modeltests/choices/models.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -21. Specifying 'choices' for a field - -Most fields take a ``choices`` parameter, which should be a tuple of tuples -specifying which are the valid values for that field. - -For each field that has ``choices``, a model instance gets a -``get_fieldname_display()`` method, where ``fieldname`` is the name of the -field. This method returns the "human-readable" value of the field. -""" - -from django.db import models - -GENDER_CHOICES = ( - ('M', 'Male'), - ('F', 'Female'), -) - -class Person(models.Model): - name = models.CharField(max_length=20) - gender = models.CharField(max_length=1, choices=GENDER_CHOICES) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/choices/tests.py b/parts/django/tests/modeltests/choices/tests.py deleted file mode 100644 index 09023d8..0000000 --- a/parts/django/tests/modeltests/choices/tests.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.test import TestCase - -from models import Person - - -class ChoicesTests(TestCase): - def test_display(self): - a = Person.objects.create(name='Adrian', gender='M') - s = Person.objects.create(name='Sara', gender='F') - self.assertEqual(a.gender, 'M') - self.assertEqual(s.gender, 'F') - - self.assertEqual(a.get_gender_display(), 'Male') - self.assertEqual(s.get_gender_display(), 'Female') - - # If the value for the field doesn't correspond to a valid choice, - # the value itself is provided as a display value. - a.gender = '' - self.assertEqual(a.get_gender_display(), '') - - a.gender = 'U' - self.assertEqual(a.get_gender_display(), 'U') - diff --git a/parts/django/tests/modeltests/custom_columns/__init__.py b/parts/django/tests/modeltests/custom_columns/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/custom_columns/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/custom_columns/models.py b/parts/django/tests/modeltests/custom_columns/models.py deleted file mode 100644 index 651f8a6..0000000 --- a/parts/django/tests/modeltests/custom_columns/models.py +++ /dev/null @@ -1,40 +0,0 @@ -""" -17. Custom column/table names - -If your database column name is different than your model attribute, use the -``db_column`` parameter. Note that you'll use the field's name, not its column -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 -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 -``ManyToManyField``. This has no effect on the API for querying the database. - -""" - -from django.db import models - -class Author(models.Model): - first_name = models.CharField(max_length=30, db_column='firstname') - last_name = models.CharField(max_length=30, db_column='last') - - def __unicode__(self): - return u'%s %s' % (self.first_name, self.last_name) - - class Meta: - db_table = 'my_author_table' - ordering = ('last_name','first_name') - -class Article(models.Model): - headline = models.CharField(max_length=100) - authors = models.ManyToManyField(Author, db_table='my_m2m_table') - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('headline',) - diff --git a/parts/django/tests/modeltests/custom_columns/tests.py b/parts/django/tests/modeltests/custom_columns/tests.py deleted file mode 100644 index f38f087..0000000 --- a/parts/django/tests/modeltests/custom_columns/tests.py +++ /dev/null @@ -1,71 +0,0 @@ -from django.core.exceptions import FieldError -from django.test import TestCase - -from models import Author, Article - - -class CustomColumnsTests(TestCase): - def test_db_column(self): - a1 = Author.objects.create(first_name="John", last_name="Smith") - a2 = Author.objects.create(first_name="Peter", last_name="Jones") - - art = Article.objects.create(headline="Django lets you build Web apps easily") - art.authors = [a1, a2] - - # Although the table and column names on Author have been set to custom - # values, nothing about using the Author model has changed... - - # Query the available authors - self.assertQuerysetEqual( - Author.objects.all(), [ - "Peter Jones", "John Smith", - ], - unicode - ) - self.assertQuerysetEqual( - Author.objects.filter(first_name__exact="John"), [ - "John Smith", - ], - unicode - ) - self.assertEqual( - Author.objects.get(first_name__exact="John"), - a1, - ) - - self.assertRaises(FieldError, - lambda: Author.objects.filter(firstname__exact="John") - ) - - a = Author.objects.get(last_name__exact="Smith") - a.first_name = "John" - a.last_name = "Smith" - - self.assertRaises(AttributeError, lambda: a.firstname) - self.assertRaises(AttributeError, lambda: a.last) - - # Although the Article table uses a custom m2m table, - # nothing about using the m2m relationship has changed... - - # Get all the authors for an article - self.assertQuerysetEqual( - art.authors.all(), [ - "Peter Jones", - "John Smith", - ], - unicode - ) - # Get the articles for an author - self.assertQuerysetEqual( - a.article_set.all(), [ - "Django lets you build Web apps easily", - ], - lambda a: a.headline - ) - # Query the authors across the m2m relation - self.assertQuerysetEqual( - art.authors.filter(last_name='Jones'), [ - "Peter Jones" - ], - unicode - ) diff --git a/parts/django/tests/modeltests/custom_managers/__init__.py b/parts/django/tests/modeltests/custom_managers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/custom_managers/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/custom_managers/models.py b/parts/django/tests/modeltests/custom_managers/models.py deleted file mode 100644 index 1052552..0000000 --- a/parts/django/tests/modeltests/custom_managers/models.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -23. Giving models a custom manager - -You can use a custom ``Manager`` in a particular model by extending the base -``Manager`` class and instantiating your custom ``Manager`` in your model. - -There are two reasons you might want to customize a ``Manager``: to add extra -``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager`` -returns. -""" - -from django.db import models - -# An example of a custom manager called "objects". - -class PersonManager(models.Manager): - def get_fun_people(self): - return self.filter(fun=True) - -class Person(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - fun = models.BooleanField() - objects = PersonManager() - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - -# An example of a custom manager that sets get_query_set(). - -class PublishedBookManager(models.Manager): - def get_query_set(self): - return super(PublishedBookManager, self).get_query_set().filter(is_published=True) - -class Book(models.Model): - title = models.CharField(max_length=50) - author = models.CharField(max_length=30) - is_published = models.BooleanField() - published_objects = PublishedBookManager() - authors = models.ManyToManyField(Person, related_name='books') - - def __unicode__(self): - return self.title - -# An example of providing multiple custom managers. - -class FastCarManager(models.Manager): - def get_query_set(self): - return super(FastCarManager, self).get_query_set().filter(top_speed__gt=150) - -class Car(models.Model): - name = models.CharField(max_length=10) - mileage = models.IntegerField() - top_speed = models.IntegerField(help_text="In miles per hour.") - cars = models.Manager() - fast_cars = FastCarManager() - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/custom_managers/tests.py b/parts/django/tests/modeltests/custom_managers/tests.py deleted file mode 100644 index 8721e9a..0000000 --- a/parts/django/tests/modeltests/custom_managers/tests.py +++ /dev/null @@ -1,71 +0,0 @@ -from django.test import TestCase - -from models import Person, Book, Car, PersonManager, PublishedBookManager - - -class CustomManagerTests(TestCase): - def test_manager(self): - p1 = Person.objects.create(first_name="Bugs", last_name="Bunny", fun=True) - p2 = Person.objects.create(first_name="Droopy", last_name="Dog", fun=False) - - self.assertQuerysetEqual( - Person.objects.get_fun_people(), [ - "Bugs Bunny" - ], - unicode - ) - # The RelatedManager used on the 'books' descriptor extends the default - # manager - self.assertTrue(isinstance(p2.books, PublishedBookManager)) - - b1 = Book.published_objects.create( - title="How to program", author="Rodney Dangerfield", is_published=True - ) - b2 = Book.published_objects.create( - title="How to be smart", author="Albert Einstein", is_published=False - ) - - # The default manager, "objects", doesn't exist, because a custom one - # was provided. - self.assertRaises(AttributeError, lambda: Book.objects) - - # The RelatedManager used on the 'authors' descriptor extends the - # default manager - self.assertTrue(isinstance(b2.authors, PersonManager)) - - self.assertQuerysetEqual( - Book.published_objects.all(), [ - "How to program", - ], - lambda b: b.title - ) - - c1 = Car.cars.create(name="Corvette", mileage=21, top_speed=180) - c2 = Car.cars.create(name="Neon", mileage=31, top_speed=100) - - self.assertQuerysetEqual( - Car.cars.order_by("name"), [ - "Corvette", - "Neon", - ], - lambda c: c.name - ) - - self.assertQuerysetEqual( - Car.fast_cars.all(), [ - "Corvette", - ], - lambda c: c.name - ) - - # Each model class gets a "_default_manager" attribute, which is a - # reference to the first manager defined in the class. In this case, - # it's "cars". - - self.assertQuerysetEqual( - Car._default_manager.order_by("name"), [ - "Corvette", - "Neon", - ], - lambda c: c.name - ) diff --git a/parts/django/tests/modeltests/custom_methods/__init__.py b/parts/django/tests/modeltests/custom_methods/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/custom_methods/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/custom_methods/models.py b/parts/django/tests/modeltests/custom_methods/models.py deleted file mode 100644 index 15150a6..0000000 --- a/parts/django/tests/modeltests/custom_methods/models.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -3. Giving models custom methods - -Any method you add to a model will be available to instances. -""" - -from django.db import models -import datetime - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - - def __unicode__(self): - return self.headline - - def was_published_today(self): - return self.pub_date == datetime.date.today() - - def articles_from_same_day_1(self): - return Article.objects.filter(pub_date=self.pub_date).exclude(id=self.id) - - def articles_from_same_day_2(self): - """ - Verbose version of get_articles_from_same_day_1, which does a custom - database query for the sake of demonstration. - """ - from django.db import connection - cursor = connection.cursor() - cursor.execute(""" - SELECT id, headline, pub_date - FROM custom_methods_article - WHERE pub_date = %s - AND id != %s""", [connection.ops.value_to_db_date(self.pub_date), - self.id]) - return [self.__class__(*row) for row in cursor.fetchall()] diff --git a/parts/django/tests/modeltests/custom_methods/tests.py b/parts/django/tests/modeltests/custom_methods/tests.py deleted file mode 100644 index 90a7f0d..0000000 --- a/parts/django/tests/modeltests/custom_methods/tests.py +++ /dev/null @@ -1,42 +0,0 @@ -from datetime import date - -from django.test import TestCase - -from models import Article - - -class MethodsTests(TestCase): - def test_custom_methods(self): - a = Article.objects.create( - headline="Area man programs in Python", pub_date=date(2005, 7, 27) - ) - b = Article.objects.create( - headline="Beatles reunite", pub_date=date(2005, 7, 27) - ) - - self.assertFalse(a.was_published_today()) - self.assertQuerysetEqual( - a.articles_from_same_day_1(), [ - "Beatles reunite", - ], - lambda a: a.headline, - ) - self.assertQuerysetEqual( - a.articles_from_same_day_2(), [ - "Beatles reunite", - ], - lambda a: a.headline - ) - - self.assertQuerysetEqual( - b.articles_from_same_day_1(), [ - "Area man programs in Python", - ], - lambda a: a.headline, - ) - self.assertQuerysetEqual( - b.articles_from_same_day_2(), [ - "Area man programs in Python", - ], - lambda a: a.headline - ) diff --git a/parts/django/tests/modeltests/custom_pk/__init__.py b/parts/django/tests/modeltests/custom_pk/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/custom_pk/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/custom_pk/fields.py b/parts/django/tests/modeltests/custom_pk/fields.py deleted file mode 100644 index 2eeb80e..0000000 --- a/parts/django/tests/modeltests/custom_pk/fields.py +++ /dev/null @@ -1,55 +0,0 @@ -import random -import string - -from django.db import models - - -class MyWrapper(object): - def __init__(self, value): - self.value = value - - def __repr__(self): - return "<%s: %s>" % (self.__class__.__name__, self.value) - - def __unicode__(self): - return self.value - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.value == other.value - return self.value == other - -class MyAutoField(models.CharField): - __metaclass__ = models.SubfieldBase - - def __init__(self, *args, **kwargs): - kwargs['max_length'] = 10 - super(MyAutoField, self).__init__(*args, **kwargs) - - def pre_save(self, instance, add): - value = getattr(instance, self.attname, None) - if not value: - value = MyWrapper(''.join(random.sample(string.lowercase, 10))) - setattr(instance, self.attname, value) - return value - - def to_python(self, value): - if not value: - return - if not isinstance(value, MyWrapper): - value = MyWrapper(value) - return value - - def get_db_prep_save(self, value): - if not value: - return - if isinstance(value, MyWrapper): - return unicode(value) - return value - - def get_db_prep_value(self, value): - if not value: - return - if isinstance(value, MyWrapper): - return unicode(value) - return value diff --git a/parts/django/tests/modeltests/custom_pk/models.py b/parts/django/tests/modeltests/custom_pk/models.py deleted file mode 100644 index ff2f2ba..0000000 --- a/parts/django/tests/modeltests/custom_pk/models.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -""" -14. Using a custom primary key - -By default, Django adds an ``"id"`` field to each model. But you can override -this behavior by explicitly adding ``primary_key=True`` to a field. -""" - -from django.conf import settings -from django.db import models, transaction, IntegrityError, DEFAULT_DB_ALIAS - -from fields import MyAutoField - -class Employee(models.Model): - employee_code = models.IntegerField(primary_key=True, db_column = 'code') - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=20) - class Meta: - ordering = ('last_name', 'first_name') - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - -class Business(models.Model): - name = models.CharField(max_length=20, primary_key=True) - employees = models.ManyToManyField(Employee) - class Meta: - verbose_name_plural = 'businesses' - - def __unicode__(self): - return self.name - -class Bar(models.Model): - id = MyAutoField(primary_key=True, db_index=True) - - def __unicode__(self): - return repr(self.pk) - - -class Foo(models.Model): - bar = models.ForeignKey(Bar) - diff --git a/parts/django/tests/modeltests/custom_pk/tests.py b/parts/django/tests/modeltests/custom_pk/tests.py deleted file mode 100644 index 6ef4bdd..0000000 --- a/parts/django/tests/modeltests/custom_pk/tests.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -from django.conf import settings -from django.db import DEFAULT_DB_ALIAS, transaction, IntegrityError -from django.test import TestCase - -from models import Employee, Business, Bar, Foo - - -class CustomPKTests(TestCase): - def test_custom_pk(self): - dan = Employee.objects.create( - employee_code=123, first_name="Dan", last_name="Jones" - ) - self.assertQuerysetEqual( - Employee.objects.all(), [ - "Dan Jones", - ], - unicode - ) - - fran = Employee.objects.create( - employee_code=456, first_name="Fran", last_name="Bones" - ) - self.assertQuerysetEqual( - Employee.objects.all(), [ - "Fran Bones", - "Dan Jones", - ], - unicode - ) - - self.assertEqual(Employee.objects.get(pk=123), dan) - self.assertEqual(Employee.objects.get(pk=456), fran) - - self.assertRaises(Employee.DoesNotExist, - lambda: Employee.objects.get(pk=42) - ) - - # Use the name of the primary key, rather than pk. - self.assertEqual(Employee.objects.get(employee_code=123), dan) - # pk can be used as a substitute for the primary key. - self.assertQuerysetEqual( - Employee.objects.filter(pk__in=[123, 456]), [ - "Fran Bones", - "Dan Jones", - ], - unicode - ) - # The primary key can be accessed via the pk property on the model. - e = Employee.objects.get(pk=123) - self.assertEqual(e.pk, 123) - # Or we can use the real attribute name for the primary key: - self.assertEqual(e.employee_code, 123) - - # Fran got married and changed her last name. - fran = Employee.objects.get(pk=456) - fran.last_name = "Jones" - fran.save() - - self.assertQuerysetEqual( - Employee.objects.filter(last_name="Jones"), [ - "Dan Jones", - "Fran Jones", - ], - unicode - ) - - emps = Employee.objects.in_bulk([123, 456]) - self.assertEqual(emps[123], dan) - - b = Business.objects.create(name="Sears") - b.employees.add(dan, fran) - self.assertQuerysetEqual( - b.employees.all(), [ - "Dan Jones", - "Fran Jones", - ], - unicode - ) - self.assertQuerysetEqual( - fran.business_set.all(), [ - "Sears", - ], - lambda b: b.name - ) - - self.assertEqual(Business.objects.in_bulk(["Sears"]), { - "Sears": b, - }) - - self.assertQuerysetEqual( - Business.objects.filter(name="Sears"), [ - "Sears" - ], - lambda b: b.name - ) - self.assertQuerysetEqual( - Business.objects.filter(pk="Sears"), [ - "Sears", - ], - lambda b: b.name - ) - - # Queries across tables, involving primary key - self.assertQuerysetEqual( - Employee.objects.filter(business__name="Sears"), [ - "Dan Jones", - "Fran Jones", - ], - unicode, - ) - self.assertQuerysetEqual( - Employee.objects.filter(business__pk="Sears"), [ - "Dan Jones", - "Fran Jones", - ], - unicode, - ) - - self.assertQuerysetEqual( - Business.objects.filter(employees__employee_code=123), [ - "Sears", - ], - lambda b: b.name - ) - self.assertQuerysetEqual( - Business.objects.filter(employees__pk=123), [ - "Sears", - ], - lambda b: b.name, - ) - - self.assertQuerysetEqual( - Business.objects.filter(employees__first_name__startswith="Fran"), [ - "Sears", - ], - lambda b: b.name - ) - - def test_unicode_pk(self): - # Primary key may be unicode string - bus = Business.objects.create(name=u'jaźń') - - def test_unique_pk(self): - # The primary key must also obviously be unique, so trying to create a - # new object with the same primary key will fail. - e = Employee.objects.create( - employee_code=123, first_name="Frank", last_name="Jones" - ) - sid = transaction.savepoint() - self.assertRaises(IntegrityError, - Employee.objects.create, employee_code=123, first_name="Fred", last_name="Jones" - ) - transaction.savepoint_rollback(sid) - - def test_custom_field_pk(self): - # Regression for #10785 -- Custom fields can be used for primary keys. - new_bar = Bar.objects.create() - new_foo = Foo.objects.create(bar=new_bar) - - # FIXME: This still doesn't work, but will require some changes in - # get_db_prep_lookup to fix it. - # f = Foo.objects.get(bar=new_bar.pk) - # self.assertEqual(f, new_foo) - # self.assertEqual(f.bar, new_bar) - - f = Foo.objects.get(bar=new_bar) - self.assertEqual(f, new_foo), - self.assertEqual(f.bar, new_bar) - - - # SQLite lets objects be saved with an empty primary key, even though an - # integer is expected. So we can't check for an error being raised in that - # case for SQLite. Remove it from the suite for this next bit. - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3': - def test_required_pk(self): - # The primary key must be specified, so an error is raised if you - # try to create an object without it. - sid = transaction.savepoint() - self.assertRaises(IntegrityError, - Employee.objects.create, first_name="Tom", last_name="Smith" - ) - transaction.savepoint_rollback(sid) diff --git a/parts/django/tests/modeltests/defer/__init__.py b/parts/django/tests/modeltests/defer/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/defer/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/defer/models.py b/parts/django/tests/modeltests/defer/models.py deleted file mode 100644 index 4fddd39..0000000 --- a/parts/django/tests/modeltests/defer/models.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -Tests for defer() and only(). -""" - -from django.db import models - - -class Secondary(models.Model): - first = models.CharField(max_length=50) - second = models.CharField(max_length=50) - -class Primary(models.Model): - name = models.CharField(max_length=50) - value = models.CharField(max_length=50) - related = models.ForeignKey(Secondary) - - def __unicode__(self): - return self.name - -class Child(Primary): - pass - -class BigChild(Primary): - other = models.CharField(max_length=50) diff --git a/parts/django/tests/modeltests/defer/tests.py b/parts/django/tests/modeltests/defer/tests.py deleted file mode 100644 index 5f6c53d..0000000 --- a/parts/django/tests/modeltests/defer/tests.py +++ /dev/null @@ -1,137 +0,0 @@ -from django.db.models.query_utils import DeferredAttribute -from django.test import TestCase - -from models import Secondary, Primary, Child, BigChild - - -class DeferTests(TestCase): - def assert_delayed(self, obj, num): - count = 0 - for field in obj._meta.fields: - if isinstance(obj.__class__.__dict__.get(field.attname), - DeferredAttribute): - count += 1 - self.assertEqual(count, num) - - def test_defer(self): - # To all outward appearances, instances with deferred fields look the - # same as normal instances when we examine attribute values. Therefore - # we test for the number of deferred fields on returned instances (by - # poking at the internals), as a way to observe what is going on. - - s1 = Secondary.objects.create(first="x1", second="y1") - p1 = Primary.objects.create(name="p1", value="xx", related=s1) - - qs = Primary.objects.all() - - self.assert_delayed(qs.defer("name")[0], 1) - self.assert_delayed(qs.only("name")[0], 2) - self.assert_delayed(qs.defer("related__first")[0], 0) - - obj = qs.select_related().only("related__first")[0] - self.assert_delayed(obj, 2) - - self.assertEqual(obj.related_id, s1.pk) - - self.assert_delayed(qs.defer("name").extra(select={"a": 1})[0], 1) - self.assert_delayed(qs.extra(select={"a": 1}).defer("name")[0], 1) - self.assert_delayed(qs.defer("name").defer("value")[0], 2) - self.assert_delayed(qs.only("name").only("value")[0], 2) - self.assert_delayed(qs.only("name").defer("value")[0], 2) - self.assert_delayed(qs.only("name", "value").defer("value")[0], 2) - self.assert_delayed(qs.defer("name").only("value")[0], 2) - - obj = qs.only()[0] - self.assert_delayed(qs.defer(None)[0], 0) - self.assert_delayed(qs.only("name").defer(None)[0], 0) - - # User values() won't defer anything (you get the full list of - # dictionaries back), but it still works. - self.assertEqual(qs.defer("name").values()[0], { - "id": p1.id, - "name": "p1", - "value": "xx", - "related_id": s1.id, - }) - self.assertEqual(qs.only("name").values()[0], { - "id": p1.id, - "name": "p1", - "value": "xx", - "related_id": s1.id, - }) - - # Using defer() and only() with get() is also valid. - self.assert_delayed(qs.defer("name").get(pk=p1.pk), 1) - self.assert_delayed(qs.only("name").get(pk=p1.pk), 2) - - # DOES THIS WORK? - self.assert_delayed(qs.only("name").select_related("related")[0], 1) - self.assert_delayed(qs.defer("related").select_related("related")[0], 0) - - # Saving models with deferred fields is possible (but inefficient, - # since every field has to be retrieved first). - obj = Primary.objects.defer("value").get(name="p1") - obj.name = "a new name" - obj.save() - self.assertQuerysetEqual( - Primary.objects.all(), [ - "a new name", - ], - lambda p: p.name - ) - - # Regression for #10572 - A subclass with no extra fields can defer - # fields from the base class - Child.objects.create(name="c1", value="foo", related=s1) - # You can defer a field on a baseclass when the subclass has no fields - obj = Child.objects.defer("value").get(name="c1") - self.assert_delayed(obj, 1) - self.assertEqual(obj.name, "c1") - self.assertEqual(obj.value, "foo") - obj.name = "c2" - obj.save() - - # You can retrive a single column on a base class with no fields - obj = Child.objects.only("name").get(name="c2") - self.assert_delayed(obj, 3) - self.assertEqual(obj.name, "c2") - self.assertEqual(obj.value, "foo") - obj.name = "cc" - obj.save() - - BigChild.objects.create(name="b1", value="foo", related=s1, other="bar") - # You can defer a field on a baseclass - obj = BigChild.objects.defer("value").get(name="b1") - self.assert_delayed(obj, 1) - self.assertEqual(obj.name, "b1") - self.assertEqual(obj.value, "foo") - self.assertEqual(obj.other, "bar") - obj.name = "b2" - obj.save() - - # You can defer a field on a subclass - obj = BigChild.objects.defer("other").get(name="b2") - self.assert_delayed(obj, 1) - self.assertEqual(obj.name, "b2") - self.assertEqual(obj.value, "foo") - self.assertEqual(obj.other, "bar") - obj.name = "b3" - obj.save() - - # You can retrieve a single field on a baseclass - obj = BigChild.objects.only("name").get(name="b3") - self.assert_delayed(obj, 4) - self.assertEqual(obj.name, "b3") - self.assertEqual(obj.value, "foo") - self.assertEqual(obj.other, "bar") - obj.name = "b4" - obj.save() - - # You can retrieve a single field on a baseclass - obj = BigChild.objects.only("other").get(name="b4") - self.assert_delayed(obj, 4) - self.assertEqual(obj.name, "b4") - self.assertEqual(obj.value, "foo") - self.assertEqual(obj.other, "bar") - obj.name = "bb" - obj.save() diff --git a/parts/django/tests/modeltests/delete/__init__.py b/parts/django/tests/modeltests/delete/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/modeltests/delete/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/modeltests/delete/models.py b/parts/django/tests/modeltests/delete/models.py deleted file mode 100644 index 9c81f6b..0000000 --- a/parts/django/tests/modeltests/delete/models.py +++ /dev/null @@ -1,42 +0,0 @@ -# coding: utf-8 -""" -Tests for some corner cases with deleting. -""" - -from django.db import models - -class DefaultRepr(object): - def __repr__(self): - return u"<%s: %s>" % (self.__class__.__name__, self.__dict__) - -class A(DefaultRepr, models.Model): - pass - -class B(DefaultRepr, models.Model): - a = models.ForeignKey(A) - -class C(DefaultRepr, models.Model): - b = models.ForeignKey(B) - -class D(DefaultRepr, models.Model): - c = models.ForeignKey(C) - a = models.ForeignKey(A) - -# Simplified, we have: -# A -# B -> A -# C -> B -# D -> C -# D -> A - -# So, we must delete Ds first of all, then Cs then Bs then As. -# However, if we start at As, we might find Bs first (in which -# case things will be nice), or find Ds first. - -# Some mutually dependent models, but nullable -class E(DefaultRepr, models.Model): - f = models.ForeignKey('F', null=True, related_name='e_rel') - -class F(DefaultRepr, models.Model): - e = models.ForeignKey(E, related_name='f_rel') - diff --git a/parts/django/tests/modeltests/delete/tests.py b/parts/django/tests/modeltests/delete/tests.py deleted file mode 100644 index 7927cce..0000000 --- a/parts/django/tests/modeltests/delete/tests.py +++ /dev/null @@ -1,135 +0,0 @@ -from django.db.models import sql -from django.db.models.loading import cache -from django.db.models.query import CollectedObjects -from django.db.models.query_utils import CyclicDependency -from django.test import TestCase - -from models import A, B, C, D, E, F - - -class DeleteTests(TestCase): - def clear_rel_obj_caches(self, *models): - for m in models: - if hasattr(m._meta, '_related_objects_cache'): - del m._meta._related_objects_cache - - def order_models(self, *models): - cache.app_models["delete"].keyOrder = models - - def setUp(self): - self.order_models("a", "b", "c", "d", "e", "f") - self.clear_rel_obj_caches(A, B, C, D, E, F) - - def tearDown(self): - self.order_models("a", "b", "c", "d", "e", "f") - self.clear_rel_obj_caches(A, B, C, D, E, F) - - def test_collected_objects(self): - g = CollectedObjects() - self.assertFalse(g.add("key1", 1, "item1", None)) - self.assertEqual(g["key1"], {1: "item1"}) - - self.assertFalse(g.add("key2", 1, "item1", "key1")) - self.assertFalse(g.add("key2", 2, "item2", "key1")) - - self.assertEqual(g["key2"], {1: "item1", 2: "item2"}) - - self.assertFalse(g.add("key3", 1, "item1", "key1")) - self.assertTrue(g.add("key3", 1, "item1", "key2")) - self.assertEqual(g.ordered_keys(), ["key3", "key2", "key1"]) - - self.assertTrue(g.add("key2", 1, "item1", "key3")) - self.assertRaises(CyclicDependency, g.ordered_keys) - - def test_delete(self): - ## Second, test the usage of CollectedObjects by Model.delete() - - # Due to the way that transactions work in the test harness, doing - # m.delete() here can work but fail in a real situation, since it may - # delete all objects, but not in the right order. So we manually check - # that the order of deletion is correct. - - # Also, it is possible that the order is correct 'accidentally', due - # solely to order of imports etc. To check this, we set the order that - # 'get_models()' will retrieve to a known 'nice' order, and then try - # again with a known 'tricky' order. Slightly naughty access to - # internals here :-) - - # If implementation changes, then the tests may need to be simplified: - # - remove the lines that set the .keyOrder and clear the related - # object caches - # - remove the second set of tests (with a2, b2 etc) - - a1 = A.objects.create() - b1 = B.objects.create(a=a1) - c1 = C.objects.create(b=b1) - d1 = D.objects.create(c=c1, a=a1) - - o = CollectedObjects() - a1._collect_sub_objects(o) - self.assertEqual(o.keys(), [D, C, B, A]) - a1.delete() - - # Same again with a known bad order - self.order_models("d", "c", "b", "a") - self.clear_rel_obj_caches(A, B, C, D) - - a2 = A.objects.create() - b2 = B.objects.create(a=a2) - c2 = C.objects.create(b=b2) - d2 = D.objects.create(c=c2, a=a2) - - o = CollectedObjects() - a2._collect_sub_objects(o) - self.assertEqual(o.keys(), [D, C, B, A]) - a2.delete() - - def test_collected_objects_null(self): - g = CollectedObjects() - self.assertFalse(g.add("key1", 1, "item1", None)) - self.assertFalse(g.add("key2", 1, "item1", "key1", nullable=True)) - self.assertTrue(g.add("key1", 1, "item1", "key2")) - self.assertEqual(g.ordered_keys(), ["key1", "key2"]) - - def test_delete_nullable(self): - e1 = E.objects.create() - f1 = F.objects.create(e=e1) - e1.f = f1 - e1.save() - - # Since E.f is nullable, we should delete F first (after nulling out - # the E.f field), then E. - - o = CollectedObjects() - e1._collect_sub_objects(o) - self.assertEqual(o.keys(), [F, E]) - - # temporarily replace the UpdateQuery class to verify that E.f is - # actually nulled out first - - logged = [] - class LoggingUpdateQuery(sql.UpdateQuery): - def clear_related(self, related_field, pk_list, using): - logged.append(related_field.name) - return super(LoggingUpdateQuery, self).clear_related(related_field, pk_list, using) - original = sql.UpdateQuery - sql.UpdateQuery = LoggingUpdateQuery - - e1.delete() - self.assertEqual(logged, ["f"]) - logged = [] - - e2 = E.objects.create() - f2 = F.objects.create(e=e2) - e2.f = f2 - e2.save() - - # Same deal as before, though we are starting from the other object. - o = CollectedObjects() - f2._collect_sub_objects(o) - self.assertEqual(o.keys(), [F, E]) - f2.delete() - self.assertEqual(logged, ["f"]) - logged = [] - - sql.UpdateQuery = original diff --git a/parts/django/tests/modeltests/empty/__init__.py b/parts/django/tests/modeltests/empty/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/empty/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/empty/models.py b/parts/django/tests/modeltests/empty/models.py deleted file mode 100644 index a6cdb0a..0000000 --- a/parts/django/tests/modeltests/empty/models.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -40. Empty model tests - -These test that things behave sensibly for the rare corner-case of a model with -no fields. -""" - -from django.db import models - - -class Empty(models.Model): - pass diff --git a/parts/django/tests/modeltests/empty/tests.py b/parts/django/tests/modeltests/empty/tests.py deleted file mode 100644 index 01fa1c5..0000000 --- a/parts/django/tests/modeltests/empty/tests.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.test import TestCase - -from models import Empty - - -class EmptyModelTests(TestCase): - def test_empty(self): - m = Empty() - self.assertEqual(m.id, None) - m.save() - m2 = Empty.objects.create() - self.assertEqual(len(Empty.objects.all()), 2) - self.assertTrue(m.id is not None) - existing = Empty(m.id) - existing.save() diff --git a/parts/django/tests/modeltests/expressions/__init__.py b/parts/django/tests/modeltests/expressions/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/expressions/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/expressions/models.py b/parts/django/tests/modeltests/expressions/models.py deleted file mode 100644 index b004408..0000000 --- a/parts/django/tests/modeltests/expressions/models.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Tests for F() query expression syntax. -""" - -from django.db import models - -class Employee(models.Model): - firstname = models.CharField(max_length=50) - lastname = models.CharField(max_length=50) - - def __unicode__(self): - return u'%s %s' % (self.firstname, self.lastname) - -class Company(models.Model): - name = models.CharField(max_length=100) - num_employees = models.PositiveIntegerField() - num_chairs = models.PositiveIntegerField() - ceo = models.ForeignKey( - Employee, - related_name='company_ceo_set') - point_of_contact = models.ForeignKey( - Employee, - related_name='company_point_of_contact_set', - null=True) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/expressions/tests.py b/parts/django/tests/modeltests/expressions/tests.py deleted file mode 100644 index 0a136ae..0000000 --- a/parts/django/tests/modeltests/expressions/tests.py +++ /dev/null @@ -1,218 +0,0 @@ -from django.core.exceptions import FieldError -from django.db.models import F -from django.test import TestCase - -from models import Company, Employee - - -class ExpressionsTests(TestCase): - def test_filter(self): - Company.objects.create( - name="Example Inc.", num_employees=2300, num_chairs=5, - ceo=Employee.objects.create(firstname="Joe", lastname="Smith") - ) - Company.objects.create( - name="Foobar Ltd.", num_employees=3, num_chairs=4, - ceo=Employee.objects.create(firstname="Frank", lastname="Meyer") - ) - Company.objects.create( - name="Test GmbH", num_employees=32, num_chairs=1, - ceo=Employee.objects.create(firstname="Max", lastname="Mustermann") - ) - - company_query = Company.objects.values( - "name", "num_employees", "num_chairs" - ).order_by( - "name", "num_employees", "num_chairs" - ) - - # We can filter for companies where the number of employees is greater - # than the number of chairs. - self.assertQuerysetEqual( - company_query.filter(num_employees__gt=F("num_chairs")), [ - { - "num_chairs": 5, - "name": "Example Inc.", - "num_employees": 2300, - }, - { - "num_chairs": 1, - "name": "Test GmbH", - "num_employees": 32 - }, - ], - lambda o: o - ) - - # We can set one field to have the value of another field - # Make sure we have enough chairs - company_query.update(num_chairs=F("num_employees")) - self.assertQuerysetEqual( - company_query, [ - { - "num_chairs": 2300, - "name": "Example Inc.", - "num_employees": 2300 - }, - { - "num_chairs": 3, - "name": "Foobar Ltd.", - "num_employees": 3 - }, - { - "num_chairs": 32, - "name": "Test GmbH", - "num_employees": 32 - } - ], - lambda o: o - ) - - # We can perform arithmetic operations in expressions - # Make sure we have 2 spare chairs - company_query.update(num_chairs=F("num_employees")+2) - self.assertQuerysetEqual( - company_query, [ - { - 'num_chairs': 2302, - 'name': u'Example Inc.', - 'num_employees': 2300 - }, - { - 'num_chairs': 5, - 'name': u'Foobar Ltd.', - 'num_employees': 3 - }, - { - 'num_chairs': 34, - 'name': u'Test GmbH', - 'num_employees': 32 - } - ], - lambda o: o, - ) - - # Law of order of operations is followed - company_query.update( - num_chairs=F('num_employees') + 2 * F('num_employees') - ) - self.assertQuerysetEqual( - company_query, [ - { - 'num_chairs': 6900, - 'name': u'Example Inc.', - 'num_employees': 2300 - }, - { - 'num_chairs': 9, - 'name': u'Foobar Ltd.', - 'num_employees': 3 - }, - { - 'num_chairs': 96, - 'name': u'Test GmbH', - 'num_employees': 32 - } - ], - lambda o: o, - ) - - # Law of order of operations can be overridden by parentheses - company_query.update( - num_chairs=((F('num_employees') + 2) * F('num_employees')) - ) - self.assertQuerysetEqual( - company_query, [ - { - 'num_chairs': 5294600, - 'name': u'Example Inc.', - 'num_employees': 2300 - }, - { - 'num_chairs': 15, - 'name': u'Foobar Ltd.', - 'num_employees': 3 - }, - { - 'num_chairs': 1088, - 'name': u'Test GmbH', - 'num_employees': 32 - } - ], - lambda o: o, - ) - - # The relation of a foreign key can become copied over to an other - # foreign key. - self.assertEqual( - Company.objects.update(point_of_contact=F('ceo')), - 3 - ) - self.assertQuerysetEqual( - Company.objects.all(), [ - "Joe Smith", - "Frank Meyer", - "Max Mustermann", - ], - lambda c: unicode(c.point_of_contact), - ) - - c = Company.objects.all()[0] - c.point_of_contact = Employee.objects.create(firstname="Guido", lastname="van Rossum") - c.save() - - # F Expressions can also span joins - self.assertQuerysetEqual( - Company.objects.filter(ceo__firstname=F("point_of_contact__firstname")), [ - "Foobar Ltd.", - "Test GmbH", - ], - lambda c: c.name - ) - - Company.objects.exclude( - ceo__firstname=F("point_of_contact__firstname") - ).update(name="foo") - self.assertEqual( - Company.objects.exclude( - ceo__firstname=F('point_of_contact__firstname') - ).get().name, - "foo", - ) - - self.assertRaises(FieldError, - lambda: Company.objects.exclude( - ceo__firstname=F('point_of_contact__firstname') - ).update(name=F('point_of_contact__lastname')) - ) - - # F expressions can be used to update attributes on single objects - test_gmbh = Company.objects.get(name="Test GmbH") - self.assertEqual(test_gmbh.num_employees, 32) - test_gmbh.num_employees = F("num_employees") + 4 - test_gmbh.save() - test_gmbh = Company.objects.get(pk=test_gmbh.pk) - self.assertEqual(test_gmbh.num_employees, 36) - - # F expressions cannot be used to update attributes which are foreign - # keys, or attributes which involve joins. - test_gmbh.point_of_contact = None - test_gmbh.save() - self.assertTrue(test_gmbh.point_of_contact is None) - def test(): - test_gmbh.point_of_contact = F("ceo") - self.assertRaises(ValueError, test) - - test_gmbh.point_of_contact = test_gmbh.ceo - test_gmbh.save() - test_gmbh.name = F("ceo__last_name") - self.assertRaises(FieldError, test_gmbh.save) - - # F expressions cannot be used to update attributes on objects which do - # not yet exist in the database - acme = Company( - name="The Acme Widget Co.", num_employees=12, num_chairs=5, - ceo=test_gmbh.ceo - ) - acme.num_employees = F("num_employees") + 16 - self.assertRaises(TypeError, acme.save) diff --git a/parts/django/tests/modeltests/field_defaults/__init__.py b/parts/django/tests/modeltests/field_defaults/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/field_defaults/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/field_defaults/models.py b/parts/django/tests/modeltests/field_defaults/models.py deleted file mode 100644 index 0dd1f72..0000000 --- a/parts/django/tests/modeltests/field_defaults/models.py +++ /dev/null @@ -1,21 +0,0 @@ -# coding: utf-8 -""" -32. Callable defaults - -You can pass callable objects as the ``default`` parameter to a field. When -the object is created without an explicit value passed in, Django will call -the method to determine the default value. - -This example uses ``datetime.datetime.now`` as the default for the ``pub_date`` -field. -""" - -from django.db import models -from datetime import datetime - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField(default=datetime.now) - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/field_defaults/tests.py b/parts/django/tests/modeltests/field_defaults/tests.py deleted file mode 100644 index a23f644..0000000 --- a/parts/django/tests/modeltests/field_defaults/tests.py +++ /dev/null @@ -1,16 +0,0 @@ -from datetime import datetime - -from django.test import TestCase - -from models import Article - - -class DefaultTests(TestCase): - def test_field_defaults(self): - a = Article() - now = datetime.now() - a.save() - - self.assertTrue(isinstance(a.id, (int, long))) - self.assertEqual(a.headline, "Default headline") - self.assertTrue((now - a.pub_date).seconds < 5) diff --git a/parts/django/tests/modeltests/field_subclassing/__init__.py b/parts/django/tests/modeltests/field_subclassing/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/field_subclassing/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/field_subclassing/fields.py b/parts/django/tests/modeltests/field_subclassing/fields.py deleted file mode 100644 index 8675b31..0000000 --- a/parts/django/tests/modeltests/field_subclassing/fields.py +++ /dev/null @@ -1,74 +0,0 @@ -from django.core.exceptions import FieldError -from django.db import models -from django.utils import simplejson as json -from django.utils.encoding import force_unicode - - -class Small(object): - """ - A simple class to show that non-trivial Python objects can be used as - attributes. - """ - def __init__(self, first, second): - self.first, self.second = first, second - - def __unicode__(self): - return u'%s%s' % (force_unicode(self.first), force_unicode(self.second)) - - def __str__(self): - return unicode(self).encode('utf-8') - -class SmallField(models.Field): - """ - Turns the "Small" class into a Django field. Because of the similarities - with normal character fields and the fact that Small.__unicode__ does - something sensible, we don't need to implement a lot here. - """ - __metaclass__ = models.SubfieldBase - - def __init__(self, *args, **kwargs): - kwargs['max_length'] = 2 - super(SmallField, self).__init__(*args, **kwargs) - - def get_internal_type(self): - return 'CharField' - - def to_python(self, value): - if isinstance(value, Small): - return value - return Small(value[0], value[1]) - - def get_db_prep_save(self, value): - return unicode(value) - - def get_prep_lookup(self, lookup_type, value): - if lookup_type == 'exact': - return force_unicode(value) - if lookup_type == 'in': - return [force_unicode(v) for v in value] - if lookup_type == 'isnull': - return [] - raise TypeError('Invalid lookup type: %r' % lookup_type) - -class SmallerField(SmallField): - pass - - -class JSONField(models.TextField): - __metaclass__ = models.SubfieldBase - - description = ("JSONField automatically serializes and desializes values to " - "and from JSON.") - - def to_python(self, value): - if not value: - return None - - if isinstance(value, basestring): - value = json.loads(value) - return value - - def get_db_prep_save(self, value): - if value is None: - return None - return json.dumps(value) diff --git a/parts/django/tests/modeltests/field_subclassing/models.py b/parts/django/tests/modeltests/field_subclassing/models.py deleted file mode 100644 index b0d8336..0000000 --- a/parts/django/tests/modeltests/field_subclassing/models.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -Tests for field subclassing. -""" - -from django.db import models -from django.utils.encoding import force_unicode - -from fields import Small, SmallField, SmallerField, JSONField - - -class MyModel(models.Model): - name = models.CharField(max_length=10) - data = SmallField('small field') - - def __unicode__(self): - return force_unicode(self.name) - -class OtherModel(models.Model): - data = SmallerField() - -class DataModel(models.Model): - data = JSONField() diff --git a/parts/django/tests/modeltests/field_subclassing/tests.py b/parts/django/tests/modeltests/field_subclassing/tests.py deleted file mode 100644 index 25f5160..0000000 --- a/parts/django/tests/modeltests/field_subclassing/tests.py +++ /dev/null @@ -1,81 +0,0 @@ -from django.core import serializers -from django.test import TestCase - -from fields import Small -from models import DataModel, MyModel, OtherModel - - -class CustomField(TestCase): - def test_defer(self): - d = DataModel.objects.create(data=[1, 2, 3]) - - self.assertTrue(isinstance(d.data, list)) - - d = DataModel.objects.get(pk=d.pk) - self.assertTrue(isinstance(d.data, list)) - self.assertEqual(d.data, [1, 2, 3]) - - d = DataModel.objects.defer("data").get(pk=d.pk) - d.save() - - d = DataModel.objects.get(pk=d.pk) - self.assertTrue(isinstance(d.data, list)) - self.assertEqual(d.data, [1, 2, 3]) - - def test_custom_field(self): - # Creating a model with custom fields is done as per normal. - s = Small(1, 2) - self.assertEqual(str(s), "12") - - m = MyModel.objects.create(name="m", data=s) - # Custom fields still have normal field's attributes. - self.assertEqual(m._meta.get_field("data").verbose_name, "small field") - - # The m.data attribute has been initialised correctly. It's a Small - # object. - self.assertEqual((m.data.first, m.data.second), (1, 2)) - - # The data loads back from the database correctly and 'data' has the - # right type. - m1 = MyModel.objects.get(pk=m.pk) - self.assertTrue(isinstance(m1.data, Small)) - self.assertEqual(str(m1.data), "12") - - # We can do normal filtering on the custom field (and will get an error - # when we use a lookup type that does not make sense). - s1 = Small(1, 3) - s2 = Small("a", "b") - self.assertQuerysetEqual( - MyModel.objects.filter(data__in=[s, s1, s2]), [ - "m", - ], - lambda m: m.name, - ) - self.assertRaises(TypeError, lambda: MyModel.objects.filter(data__lt=s)) - - # Serialization works, too. - stream = serializers.serialize("json", MyModel.objects.all()) - self.assertEqual(stream, '[{"pk": 1, "model": "field_subclassing.mymodel", "fields": {"data": "12", "name": "m"}}]') - - obj = list(serializers.deserialize("json", stream))[0] - self.assertEqual(obj.object, m) - - # Test retrieving custom field data - m.delete() - - m1 = MyModel.objects.create(name="1", data=Small(1, 2)) - m2 = MyModel.objects.create(name="2", data=Small(2, 3)) - - self.assertQuerysetEqual( - MyModel.objects.all(), [ - "12", - "23", - ], - lambda m: str(m.data) - ) - - def test_field_subclassing(self): - o = OtherModel.objects.create(data=Small("a", "b")) - o = OtherModel.objects.get() - self.assertEqual(o.data.first, "a") - self.assertEqual(o.data.second, "b") diff --git a/parts/django/tests/modeltests/files/__init__.py b/parts/django/tests/modeltests/files/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/modeltests/files/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/modeltests/files/models.py b/parts/django/tests/modeltests/files/models.py deleted file mode 100644 index f798f74..0000000 --- a/parts/django/tests/modeltests/files/models.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -42. Storing files according to a custom storage system - -``FileField`` and its variations can take a ``storage`` argument to specify how -and where files should be stored. -""" - -import random -import tempfile - -from django.db import models -from django.core.files.base import ContentFile -from django.core.files.storage import FileSystemStorage - - -temp_storage_location = tempfile.mkdtemp() -temp_storage = FileSystemStorage(location=temp_storage_location) - -# Write out a file to be used as default content -temp_storage.save('tests/default.txt', ContentFile('default content')) - -class Storage(models.Model): - def custom_upload_to(self, filename): - return 'foo' - - def random_upload_to(self, filename): - # This returns a different result each time, - # to make sure it only gets called once. - return '%s/%s' % (random.randint(100, 999), filename) - - normal = models.FileField(storage=temp_storage, upload_to='tests') - custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to) - random = models.FileField(storage=temp_storage, upload_to=random_upload_to) - default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt') diff --git a/parts/django/tests/modeltests/files/tests.py b/parts/django/tests/modeltests/files/tests.py deleted file mode 100644 index 025fcc5..0000000 --- a/parts/django/tests/modeltests/files/tests.py +++ /dev/null @@ -1,100 +0,0 @@ -import shutil - -from django.core.cache import cache -from django.core.files.base import ContentFile -from django.core.files.uploadedfile import SimpleUploadedFile -from django.test import TestCase - -from models import Storage, temp_storage, temp_storage_location - - -class FileTests(TestCase): - def tearDown(self): - shutil.rmtree(temp_storage_location) - - def test_files(self): - # Attempting to access a FileField from the class raises a descriptive - # error - self.assertRaises(AttributeError, lambda: Storage.normal) - - # An object without a file has limited functionality. - obj1 = Storage() - self.assertEqual(obj1.normal.name, "") - self.assertRaises(ValueError, lambda: obj1.normal.size) - - # Saving a file enables full functionality. - obj1.normal.save("django_test.txt", ContentFile("content")) - self.assertEqual(obj1.normal.name, "tests/django_test.txt") - self.assertEqual(obj1.normal.size, 7) - self.assertEqual(obj1.normal.read(), "content") - - # File objects can be assigned to FileField attributes, but shouldn't - # get committed until the model it's attached to is saved. - obj1.normal = SimpleUploadedFile("assignment.txt", "content") - dirs, files = temp_storage.listdir("tests") - self.assertEqual(dirs, []) - self.assertEqual(sorted(files), ["default.txt", "django_test.txt"]) - - obj1.save() - dirs, files = temp_storage.listdir("tests") - self.assertEqual( - sorted(files), ["assignment.txt", "default.txt", "django_test.txt"] - ) - - # Files can be read in a little at a time, if necessary. - obj1.normal.open() - self.assertEqual(obj1.normal.read(3), "con") - self.assertEqual(obj1.normal.read(), "tent") - self.assertEqual(list(obj1.normal.chunks(chunk_size=2)), ["co", "nt", "en", "t"]) - - # Save another file with the same name. - obj2 = Storage() - obj2.normal.save("django_test.txt", ContentFile("more content")) - self.assertEqual(obj2.normal.name, "tests/django_test_1.txt") - self.assertEqual(obj2.normal.size, 12) - - # Push the objects into the cache to make sure they pickle properly - cache.set("obj1", obj1) - cache.set("obj2", obj2) - self.assertEqual(cache.get("obj2").normal.name, "tests/django_test_1.txt") - - # Deleting an object deletes the file it uses, if there are no other - # objects still using that file. - obj2.delete() - obj2.normal.save("django_test.txt", ContentFile("more content")) - self.assertEqual(obj2.normal.name, "tests/django_test_1.txt") - - # Multiple files with the same name get _N appended to them. - objs = [Storage() for i in range(3)] - for o in objs: - o.normal.save("multiple_files.txt", ContentFile("Same Content")) - self.assertEqual( - [o.normal.name for o in objs], - ["tests/multiple_files.txt", "tests/multiple_files_1.txt", "tests/multiple_files_2.txt"] - ) - for o in objs: - o.delete() - - # Default values allow an object to access a single file. - obj3 = Storage.objects.create() - self.assertEqual(obj3.default.name, "tests/default.txt") - self.assertEqual(obj3.default.read(), "default content") - - # But it shouldn't be deleted, even if there are no more objects using - # it. - obj3.delete() - obj3 = Storage() - self.assertEqual(obj3.default.read(), "default content") - - # Verify the fix for #5655, making sure the directory is only - # determined once. - obj4 = Storage() - obj4.random.save("random_file", ContentFile("random content")) - self.assertTrue(obj4.random.name.endswith("/random_file")) - - # Clean up the temporary files and dir. - obj1.normal.delete() - obj2.normal.delete() - obj3.default.delete() - obj4.random.delete() - diff --git a/parts/django/tests/modeltests/fixtures/__init__.py b/parts/django/tests/modeltests/fixtures/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/modeltests/fixtures/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_1.default.json b/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_1.default.json deleted file mode 100644 index 9bb39e4..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_1.default.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": "6", - "model": "fixtures.article", - "fields": { - "headline": "Who needs more than one database?", - "pub_date": "2006-06-16 14:00:00" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_2.default.json.gz b/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_2.default.json.gz Binary files differdeleted file mode 100644 index 80e4ba1..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_2.default.json.gz +++ /dev/null diff --git a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_3.nosuchdb.json b/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_3.nosuchdb.json deleted file mode 100644 index 3da326b..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/db_fixture_3.nosuchdb.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": "8", - "model": "fixtures.article", - "fields": { - "headline": "There is no spoon.", - "pub_date": "2006-06-16 14:00:00" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture1.json b/parts/django/tests/modeltests/fixtures/fixtures/fixture1.json deleted file mode 100644 index 332feae..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture1.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "pk": 1, - "model": "sites.site", - "fields": { - "domain": "example.com", - "name": "example.com" - } - }, - { - "pk": "2", - "model": "fixtures.article", - "fields": { - "headline": "Poker has no place on ESPN", - "pub_date": "2006-06-16 12:00:00" - } - }, - { - "pk": "3", - "model": "fixtures.article", - "fields": { - "headline": "Time to reform copyright", - "pub_date": "2006-06-16 13:00:00" - } - }, - { - "pk": 1, - "model": "fixtures.category", - "fields": { - "description": "Latest news stories", - "title": "News Stories" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture2.json b/parts/django/tests/modeltests/fixtures/fixtures/fixture2.json deleted file mode 100644 index 01b40d7..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture2.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "pk": "3", - "model": "fixtures.article", - "fields": { - "headline": "Copyright is fine the way it is", - "pub_date": "2006-06-16 14:00:00" - } - }, - { - "pk": "4", - "model": "fixtures.article", - "fields": { - "headline": "Django conquers world!", - "pub_date": "2006-06-16 15:00:00" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture2.xml b/parts/django/tests/modeltests/fixtures/fixtures/fixture2.xml deleted file mode 100644 index 9ced781..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture2.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures.article"> - <field type="CharField" name="headline">Poker on TV is great!</field> - <field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field> - </object> - <object pk="5" model="fixtures.article"> - <field type="CharField" name="headline">XML identified as leading cause of cancer</field> - <field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture3.xml b/parts/django/tests/modeltests/fixtures/fixtures/fixture3.xml deleted file mode 100644 index 9ced781..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture3.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures.article"> - <field type="CharField" name="headline">Poker on TV is great!</field> - <field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field> - </object> - <object pk="5" model="fixtures.article"> - <field type="CharField" name="headline">XML identified as leading cause of cancer</field> - <field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture4.json.zip b/parts/django/tests/modeltests/fixtures/fixtures/fixture4.json.zip Binary files differdeleted file mode 100644 index 270cccb..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture4.json.zip +++ /dev/null diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.gz b/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.gz Binary files differdeleted file mode 100644 index bb6baca..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.gz +++ /dev/null diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.zip b/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.zip Binary files differdeleted file mode 100644 index 9380cef..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture5.json.zip +++ /dev/null diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture6.json b/parts/django/tests/modeltests/fixtures/fixtures/fixture6.json deleted file mode 100644 index 60e4733..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture6.json +++ /dev/null @@ -1,41 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures.tag", - "fields": { - "name": "copyright", - "tagged_type": ["fixtures", "article"], - "tagged_id": "3" - } - }, - { - "pk": "2", - "model": "fixtures.tag", - "fields": { - "name": "law", - "tagged_type": ["fixtures", "article"], - "tagged_id": "3" - } - }, - { - "pk": "1", - "model": "fixtures.person", - "fields": { - "name": "Django Reinhardt" - } - }, - { - "pk": "2", - "model": "fixtures.person", - "fields": { - "name": "Stephane Grappelli" - } - }, - { - "pk": "3", - "model": "fixtures.person", - "fields": { - "name": "Prince" - } - } -] diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture7.xml b/parts/django/tests/modeltests/fixtures/fixtures/fixture7.xml deleted file mode 100644 index 547cba1..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture7.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures.tag"> - <field type="CharField" name="name">legal</field> - <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> - <natural>fixtures</natural> - <natural>article</natural> - </field> - <field type="PositiveIntegerField" name="tagged_id">3</field> - </object> - <object pk="3" model="fixtures.tag"> - <field type="CharField" name="name">django</field> - <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> - <natural>fixtures</natural> - <natural>article</natural> - </field> - <field type="PositiveIntegerField" name="tagged_id">4</field> - </object> - <object pk="4" model="fixtures.tag"> - <field type="CharField" name="name">world domination</field> - <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> - <natural>fixtures</natural> - <natural>article</natural> - </field> - <field type="PositiveIntegerField" name="tagged_id">4</field> - </object> -</django-objects> diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture8.json b/parts/django/tests/modeltests/fixtures/fixtures/fixture8.json deleted file mode 100644 index bc113aa..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture8.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures.visa", - "fields": { - "person": ["Django Reinhardt"], - "permissions": [ - ["add_user", "auth", "user"], - ["change_user", "auth", "user"], - ["delete_user", "auth", "user"] - ] - } - }, - { - "pk": "2", - "model": "fixtures.visa", - "fields": { - "person": ["Stephane Grappelli"], - "permissions": [ - ["add_user", "auth", "user"] - ] - } - }, - { - "pk": "3", - "model": "fixtures.visa", - "fields": { - "person": ["Prince"], - "permissions": [] - } - } -] diff --git a/parts/django/tests/modeltests/fixtures/fixtures/fixture9.xml b/parts/django/tests/modeltests/fixtures/fixtures/fixture9.xml deleted file mode 100644 index 100f63d..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/fixture9.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures.visa"> - <field type="CharField" name="person"> - <natural>Stephane Grappelli</natural> - </field> - <field to="auth.permission" name="permissions" rel="ManyToManyRel"> - <object> - <natural>add_user</natural> - <natural>auth</natural> - <natural>user</natural> - </object> - <object> - <natural>delete_user</natural> - <natural>auth</natural> - <natural>user</natural> - </object> - </field> - </object> - <object pk="3" model="fixtures.person"> - <field type="CharField" name="name"> - <natural>Artist formerly known as "Prince"</natural> - </field> - </object> - <object pk="3" model="fixtures.visa"> - <field type="CharField" name="person"> - <natural>Artist formerly known as "Prince"</natural> - </field> - <field to="auth.permission" name="permissions" rel="ManyToManyRel"> - <object> - <natural>change_user</natural> - <natural>auth</natural> - <natural>user</natural> - </object> - </field> - </object> - <object pk="1" model="fixtures.book"> - <field type="CharField" name="name">Music for all ages</field> - <field to="fixtures.person" name="authors" rel="ManyToManyRel"> - <object> - <natural>Django Reinhardt</natural> - </object> - <object> - <natural>Artist formerly known as "Prince"</natural> - </object> - </field> - </object> -</django-objects> diff --git a/parts/django/tests/modeltests/fixtures/fixtures/initial_data.json b/parts/django/tests/modeltests/fixtures/fixtures/initial_data.json deleted file mode 100644 index 477d781..0000000 --- a/parts/django/tests/modeltests/fixtures/fixtures/initial_data.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures.article", - "fields": { - "headline": "Python program becomes self aware", - "pub_date": "2006-06-16 11:00:00" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/fixtures/models.py b/parts/django/tests/modeltests/fixtures/models.py deleted file mode 100644 index 216a8e2..0000000 --- a/parts/django/tests/modeltests/fixtures/models.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -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 -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 -``FIXTURE_DIRS`` setting. -""" - -from django.contrib.auth.models import Permission -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.db import models, DEFAULT_DB_ALIAS -from django.conf import settings - - -class Category(models.Model): - title = models.CharField(max_length=100) - description = models.TextField() - - def __unicode__(self): - return self.title - - class Meta: - ordering = ('title',) - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('-pub_date', 'headline') - -class Blog(models.Model): - name = models.CharField(max_length=100) - featured = models.ForeignKey(Article, related_name='fixtures_featured_set') - articles = models.ManyToManyField(Article, blank=True, - related_name='fixtures_articles_set') - - def __unicode__(self): - return self.name - - -class Tag(models.Model): - name = models.CharField(max_length=100) - tagged_type = models.ForeignKey(ContentType, related_name="fixtures_tag_set") - tagged_id = models.PositiveIntegerField(default=0) - tagged = generic.GenericForeignKey(ct_field='tagged_type', - fk_field='tagged_id') - - def __unicode__(self): - return '<%s: %s> tagged "%s"' % (self.tagged.__class__.__name__, - self.tagged, self.name) - -class PersonManager(models.Manager): - def get_by_natural_key(self, name): - return self.get(name=name) - -class Person(models.Model): - objects = PersonManager() - name = models.CharField(max_length=100) - def __unicode__(self): - return self.name - - class Meta: - ordering = ('name',) - - def natural_key(self): - return (self.name,) - -class Visa(models.Model): - person = models.ForeignKey(Person) - permissions = models.ManyToManyField(Permission, blank=True) - - def __unicode__(self): - return '%s %s' % (self.person.name, - ', '.join(p.name for p in self.permissions.all())) - -class Book(models.Model): - name = models.CharField(max_length=100) - authors = models.ManyToManyField(Person) - - def __unicode__(self): - return '%s by %s' % (self.name, - ' and '.join(a.name for a in self.authors.all())) - - class Meta: - ordering = ('name',) diff --git a/parts/django/tests/modeltests/fixtures/tests.py b/parts/django/tests/modeltests/fixtures/tests.py deleted file mode 100644 index 4facc6d..0000000 --- a/parts/django/tests/modeltests/fixtures/tests.py +++ /dev/null @@ -1,277 +0,0 @@ -import StringIO -import sys - -from django.test import TestCase, TransactionTestCase -from django.conf import settings -from django.core import management -from django.db import DEFAULT_DB_ALIAS - -from models import Article, Blog, Book, Category, Person, Tag, Visa - -class TestCaseFixtureLoadingTests(TestCase): - fixtures = ['fixture1.json', 'fixture2.json'] - - def testClassFixtures(self): - "Check that test case has installed 4 fixture objects" - self.assertEqual(Article.objects.count(), 4) - self.assertQuerysetEqual(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>' - ]) - -class FixtureLoadingTests(TestCase): - - def _dumpdata_assert(self, args, output, format='json', natural_keys=False): - new_io = StringIO.StringIO() - management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io, 'use_natural_keys':natural_keys}) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, output) - - def test_initial_data(self): - # Syncdb introduces 1 initial data object from initial_data.json. - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Python program becomes self aware>' - ]) - - def test_loading_and_dumping(self): - new_io = StringIO.StringIO() - - # Load fixture 1. Single JSON file, with two objects. - management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Time to reform copyright>', - '<Article: Poker has no place on ESPN>', - '<Article: Python program becomes self aware>' - ]) - - # Dump the current contents of the database as a JSON fixture - self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Try just dumping the contents of fixtures.Category - self._dumpdata_assert(['fixtures.Category'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]') - - # ...and just fixtures.Article - self._dumpdata_assert(['fixtures.Article'], '[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # ...and both - self._dumpdata_assert(['fixtures.Category', 'fixtures.Article'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Specify a specific model twice - self._dumpdata_assert(['fixtures.Article', 'fixtures.Article'], '[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Specify a dump that specifies Article both explicitly and implicitly - self._dumpdata_assert(['fixtures.Article', 'fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Same again, but specify in the reverse order - self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Specify one model from one application, and an entire other application. - self._dumpdata_assert(['fixtures.Category', 'sites'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}]') - - # Load fixture 2. JSON file imported by default. Overwrites some existing objects - management.call_command('loaddata', 'fixture2.json', verbosity=0, commit=False) - self.assertQuerysetEqual(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. - management.call_command('loaddata', 'fixture3.xml', verbosity=0, commit=False) - self.assertQuerysetEqual(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>' - ]) - - # Load fixture 6, JSON file with dynamic ContentType fields. Testing ManyToOne. - management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False) - self.assertQuerysetEqual(Tag.objects.all(), [ - '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', - '<Tag: <Article: Copyright is fine the way it is> tagged "law">' - ]) - - # Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne. - management.call_command('loaddata', 'fixture7.xml', verbosity=0, commit=False) - self.assertQuerysetEqual(Tag.objects.all(), [ - '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', - '<Tag: <Article: Copyright is fine the way it is> tagged "legal">', - '<Tag: <Article: Django conquers world!> tagged "django">', - '<Tag: <Article: Django conquers world!> tagged "world domination">' - ]) - - # Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany. - management.call_command('loaddata', 'fixture8.json', verbosity=0, commit=False) - self.assertQuerysetEqual(Visa.objects.all(), [ - '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', - '<Visa: Stephane Grappelli Can add user>', - '<Visa: Prince >' - ]) - - # Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany. - management.call_command('loaddata', 'fixture9.xml', verbosity=0, commit=False) - self.assertQuerysetEqual(Visa.objects.all(), [ - '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', - '<Visa: Stephane Grappelli Can add user, Can delete user>', - '<Visa: Artist formerly known as "Prince" Can change user>' - ]) - - self.assertQuerysetEqual(Book.objects.all(), [ - '<Book: Music for all ages by Artist formerly known as "Prince" and Django Reinhardt>' - ]) - - # Load a fixture that doesn't exist - management.call_command('loaddata', 'unknown.json', verbosity=0, commit=False) - - # object list is unaffected - self.assertQuerysetEqual(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>' - ]) - - # By default, you get raw keys on dumpdata - self._dumpdata_assert(['fixtures.book'], '[{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [3, 1]}}]') - - # But you can get natural keys if you ask for them and they are available - self._dumpdata_assert(['fixtures.book'], '[{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]', natural_keys=True) - - # Dump the current contents of the database as a JSON fixture - self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 5, "model": "fixtures.article", "fields": {"headline": "XML identified as leading cause of cancer", "pub_date": "2006-06-16 16:00:00"}}, {"pk": 4, "model": "fixtures.article", "fields": {"headline": "Django conquers world!", "pub_date": "2006-06-16 15:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Copyright is fine the way it is", "pub_date": "2006-06-16 14:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker on TV is great!", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "legal", "tagged_id": 3}}, {"pk": 3, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "django", "tagged_id": 4}}, {"pk": 4, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "world domination", "tagged_id": 4}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Artist formerly known as \\"Prince\\""}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}, {"pk": 1, "model": "fixtures.visa", "fields": {"person": ["Django Reinhardt"], "permissions": [["add_user", "auth", "user"], ["change_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 2, "model": "fixtures.visa", "fields": {"person": ["Stephane Grappelli"], "permissions": [["add_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 3, "model": "fixtures.visa", "fields": {"person": ["Artist formerly known as \\"Prince\\""], "permissions": [["change_user", "auth", "user"]]}}, {"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]', natural_keys=True) - - # Dump the current contents of the database as an XML fixture - self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Artist formerly known as "Prince"</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="1" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Django Reinhardt</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="2" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Stephane Grappelli</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="3" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Artist formerly known as "Prince"</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="1" model="fixtures.book"><field type="CharField" name="name">Music for all ages</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"><object><natural>Artist formerly known as "Prince"</natural></object><object><natural>Django Reinhardt</natural></object></field></object></django-objects>""", format='xml', natural_keys=True) - - def test_compress_format_loading(self): - # Load fixture 4 (compressed), using format specification - management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Django pets kitten>', - '<Article: Python program becomes self aware>' - ]) - - def test_compressed_specified_loading(self): - # Load fixture 5 (compressed), using format *and* compression specification - management.call_command('loaddata', 'fixture5.json.zip', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: WoW subscribers now outnumber readers>', - '<Article: Python program becomes self aware>' - ]) - - def test_compressed_loading(self): - # Load fixture 5 (compressed), only compression specification - management.call_command('loaddata', 'fixture5.zip', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: WoW subscribers now outnumber readers>', - '<Article: Python program becomes self aware>' - ]) - - def test_ambiguous_compressed_fixture(self): - # The name "fixture5" is ambigous, so loading it will raise an error - new_io = StringIO.StringIO() - management.call_command('loaddata', 'fixture5', verbosity=0, stderr=new_io, commit=False) - output = new_io.getvalue().strip().split('\n') - self.assertEqual(len(output), 1) - self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture5'")) - - def test_db_loading(self): - # Load db fixtures 1 and 2. These will load using the 'default' database identifier implicitly - management.call_command('loaddata', 'db_fixture_1', verbosity=0, commit=False) - management.call_command('loaddata', 'db_fixture_2', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Who needs more than one database?>', - '<Article: Who needs to use compressed data?>', - '<Article: Python program becomes self aware>' - ]) - - def test_loading_using(self): - # Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly - management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default', commit=False) - management.call_command('loaddata', 'db_fixture_2', verbosity=0, using='default', commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Who needs more than one database?>', - '<Article: Who needs to use compressed data?>', - '<Article: Python program becomes self aware>' - ]) - - def test_unmatched_identifier_loading(self): - # Try to load db fixture 3. This won't load because the database identifier doesn't match - management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Python program becomes self aware>' - ]) - - management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Python program becomes self aware>' - ]) - - def test_output_formats(self): - # Load back in fixture 1, we need the articles from it - management.call_command('loaddata', 'fixture1', verbosity=0, commit=False) - - # Try to load fixture 6 using format discovery - management.call_command('loaddata', 'fixture6', verbosity=0, commit=False) - self.assertQuerysetEqual(Tag.objects.all(), [ - '<Tag: <Article: Time to reform copyright> tagged "copyright">', - '<Tag: <Article: Time to reform copyright> tagged "law">' - ]) - - # Dump the current contents of the database as a JSON fixture - self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "law", "tagged_id": 3}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Prince"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}]', natural_keys=True) - - # Dump the current contents of the database as an XML fixture - self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16 13:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16 12:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Prince</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object></django-objects>""", format='xml', natural_keys=True) - -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql': - class FixtureTransactionTests(TransactionTestCase): - def _dumpdata_assert(self, args, output, format='json'): - new_io = StringIO.StringIO() - management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io}) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, output) - - def test_format_discovery(self): - # Load fixture 1 again, using format discovery - management.call_command('loaddata', 'fixture1', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<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 - new_io = StringIO.StringIO() - management.call_command('loaddata', 'fixture2', verbosity=0, stderr=new_io) - output = new_io.getvalue().strip().split('\n') - self.assertEqual(len(output), 1) - self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture2'")) - - # object list is unaffected - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Time to reform copyright>', - '<Article: Poker has no place on ESPN>', - '<Article: Python program becomes self aware>' - ]) - - # Dump the current contents of the database as a JSON fixture - self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]') - - # Load fixture 4 (compressed), using format discovery - management.call_command('loaddata', 'fixture4', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), [ - '<Article: Django pets kitten>', - '<Article: Time to reform copyright>', - '<Article: Poker has no place on ESPN>', - '<Article: Python program becomes self aware>' - ]) diff --git a/parts/django/tests/modeltests/fixtures_model_package/__init__.py b/parts/django/tests/modeltests/fixtures_model_package/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture1.json b/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture1.json deleted file mode 100644 index 7684d84..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture1.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "pk": "2", - "model": "fixtures_model_package.article", - "fields": { - "headline": "Poker has no place on ESPN", - "pub_date": "2006-06-16 12:00:00" - } - }, - { - "pk": "3", - "model": "fixtures_model_package.article", - "fields": { - "headline": "Time to reform copyright", - "pub_date": "2006-06-16 13:00:00" - } - } -] diff --git a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.json b/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.json deleted file mode 100644 index 4997627..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "pk": "3", - "model": "fixtures_model_package.article", - "fields": { - "headline": "Copyright is fine the way it is", - "pub_date": "2006-06-16 14:00:00" - } - }, - { - "pk": "4", - "model": "fixtures_model_package.article", - "fields": { - "headline": "Django conquers world!", - "pub_date": "2006-06-16 15:00:00" - } - } -] diff --git a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.xml b/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.xml deleted file mode 100644 index 55337cf..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/fixtures/fixture2.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures_model_package.article"> - <field type="CharField" name="headline">Poker on TV is great!</field> - <field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field> - </object> - <object pk="5" model="fixtures_model_package.article"> - <field type="CharField" name="headline">XML identified as leading cause of cancer</field> - <field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field> - </object> -</django-objects> diff --git a/parts/django/tests/modeltests/fixtures_model_package/fixtures/initial_data.json b/parts/django/tests/modeltests/fixtures_model_package/fixtures/initial_data.json deleted file mode 100644 index 66cb5d7..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/fixtures/initial_data.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures_model_package.article", - "fields": { - "headline": "Python program becomes self aware", - "pub_date": "2006-06-16 11:00:00" - } - } -] diff --git a/parts/django/tests/modeltests/fixtures_model_package/models/__init__.py b/parts/django/tests/modeltests/fixtures_model_package/models/__init__.py deleted file mode 100644 index c0450b2..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/models/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.db import models -from django.conf import settings - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - - def __unicode__(self): - return self.headline - - class Meta: - app_label = 'fixtures_model_package' - ordering = ('-pub_date', 'headline') - diff --git a/parts/django/tests/modeltests/fixtures_model_package/tests.py b/parts/django/tests/modeltests/fixtures_model_package/tests.py deleted file mode 100644 index 1fae5ee..0000000 --- a/parts/django/tests/modeltests/fixtures_model_package/tests.py +++ /dev/null @@ -1,71 +0,0 @@ -from django.core import management -from django.test import TestCase - -from models import Article - - -class SampleTestCase(TestCase): - fixtures = ['fixture1.json', 'fixture2.json'] - - def testClassFixtures(self): - "Test cases can load fixture objects into models defined in packages" - self.assertEqual(Article.objects.count(), 4) - self.assertQuerysetEqual( - Article.objects.all(),[ - "Django conquers world!", - "Copyright is fine the way it is", - "Poker has no place on ESPN", - "Python program becomes self aware" - ], - lambda a: a.headline - ) - - -class FixtureTestCase(TestCase): - def test_initial_data(self): - "Fixtures can load initial data into models defined in packages" - #Syncdb introduces 1 initial data object from initial_data.json - self.assertQuerysetEqual( - Article.objects.all(), [ - "Python program becomes self aware" - ], - lambda a: a.headline - ) - - def test_loaddata(self): - "Fixtures can load data into models defined in packages" - # Load fixture 1. Single JSON file, with two objects - management.call_command("loaddata", "fixture1.json", verbosity=0, commit=False) - self.assertQuerysetEqual( - Article.objects.all(), [ - "Time to reform copyright", - "Poker has no place on ESPN", - "Python program becomes self aware", - ], - lambda a: a.headline, - ) - - # Load fixture 2. JSON file imported by default. Overwrites some - # existing objects - management.call_command("loaddata", "fixture2.json", verbosity=0, commit=False) - self.assertQuerysetEqual( - Article.objects.all(), [ - "Django conquers world!", - "Copyright is fine the way it is", - "Poker has no place on ESPN", - "Python program becomes self aware", - ], - lambda a: a.headline, - ) - - # Load a fixture that doesn't exist - management.call_command("loaddata", "unknown.json", verbosity=0, commit=False) - self.assertQuerysetEqual( - Article.objects.all(), [ - "Django conquers world!", - "Copyright is fine the way it is", - "Poker has no place on ESPN", - "Python program becomes self aware", - ], - lambda a: a.headline, - ) diff --git a/parts/django/tests/modeltests/force_insert_update/__init__.py b/parts/django/tests/modeltests/force_insert_update/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/force_insert_update/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/force_insert_update/models.py b/parts/django/tests/modeltests/force_insert_update/models.py deleted file mode 100644 index 9516be7..0000000 --- a/parts/django/tests/modeltests/force_insert_update/models.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Tests for forcing insert and update queries (instead of Django's normal -automatic behaviour). -""" -from django.db import models, transaction, IntegrityError - -class Counter(models.Model): - name = models.CharField(max_length = 10) - value = models.IntegerField() - -class WithCustomPK(models.Model): - name = models.IntegerField(primary_key=True) - value = models.IntegerField() diff --git a/parts/django/tests/modeltests/force_insert_update/tests.py b/parts/django/tests/modeltests/force_insert_update/tests.py deleted file mode 100644 index bd3eb7d..0000000 --- a/parts/django/tests/modeltests/force_insert_update/tests.py +++ /dev/null @@ -1,38 +0,0 @@ -from django.db import transaction, IntegrityError, DatabaseError -from django.test import TestCase - -from models import Counter, WithCustomPK - - -class ForceTests(TestCase): - def test_force_update(self): - c = Counter.objects.create(name="one", value=1) - # The normal case - - c.value = 2 - c.save() - # Same thing, via an update - c.value = 3 - c.save(force_update=True) - - # Won't work because force_update and force_insert are mutually - # exclusive - c.value = 4 - self.assertRaises(ValueError, c.save, force_insert=True, force_update=True) - - # Try to update something that doesn't have a primary key in the first - # place. - c1 = Counter(name="two", value=2) - self.assertRaises(ValueError, c1.save, force_update=True) - c1.save(force_insert=True) - - # Won't work because we can't insert a pk of the same value. - sid = transaction.savepoint() - c.value = 5 - self.assertRaises(IntegrityError, c.save, force_insert=True) - transaction.savepoint_rollback(sid) - - # Trying to update should still fail, even with manual primary keys, if - # the data isn't in the database already. - obj = WithCustomPK(name=1, value=1) - self.assertRaises(DatabaseError, obj.save, force_update=True) diff --git a/parts/django/tests/modeltests/generic_relations/__init__.py b/parts/django/tests/modeltests/generic_relations/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/generic_relations/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/generic_relations/models.py b/parts/django/tests/modeltests/generic_relations/models.py deleted file mode 100644 index 18b77a3..0000000 --- a/parts/django/tests/modeltests/generic_relations/models.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -34. Generic relations - -Generic relations let an object have a foreign key to any object through a -content-type/object-id field. A ``GenericForeignKey`` field can point to any -object, be it animal, vegetable, or mineral. - -The canonical example is tags (although this example implementation is *far* -from complete). -""" - -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.db import models - - -class TaggedItem(models.Model): - """A tag on an item.""" - tag = models.SlugField() - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - - content_object = generic.GenericForeignKey() - - class Meta: - ordering = ["tag", "content_type__name"] - - def __unicode__(self): - return self.tag - -class ValuableTaggedItem(TaggedItem): - value = models.PositiveIntegerField() - -class Comparison(models.Model): - """ - A model that tests having multiple GenericForeignKeys - """ - comparative = models.CharField(max_length=50) - - content_type1 = models.ForeignKey(ContentType, related_name="comparative1_set") - object_id1 = models.PositiveIntegerField() - - content_type2 = models.ForeignKey(ContentType, related_name="comparative2_set") - object_id2 = models.PositiveIntegerField() - - first_obj = generic.GenericForeignKey(ct_field="content_type1", fk_field="object_id1") - other_obj = generic.GenericForeignKey(ct_field="content_type2", fk_field="object_id2") - - def __unicode__(self): - return u"%s is %s than %s" % (self.first_obj, self.comparative, self.other_obj) - -class Animal(models.Model): - common_name = models.CharField(max_length=150) - latin_name = models.CharField(max_length=150) - - tags = generic.GenericRelation(TaggedItem) - comparisons = generic.GenericRelation(Comparison, - object_id_field="object_id1", - content_type_field="content_type1") - - def __unicode__(self): - return self.common_name - -class Vegetable(models.Model): - name = models.CharField(max_length=150) - is_yucky = models.BooleanField(default=True) - - tags = generic.GenericRelation(TaggedItem) - - def __unicode__(self): - return self.name - -class Mineral(models.Model): - name = models.CharField(max_length=150) - hardness = models.PositiveSmallIntegerField() - - # note the lack of an explicit GenericRelation here... - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/generic_relations/tests.py b/parts/django/tests/modeltests/generic_relations/tests.py deleted file mode 100644 index 3d25301..0000000 --- a/parts/django/tests/modeltests/generic_relations/tests.py +++ /dev/null @@ -1,223 +0,0 @@ -from django.contrib.contenttypes.generic import generic_inlineformset_factory -from django.contrib.contenttypes.models import ContentType -from django.test import TestCase - -from models import (TaggedItem, ValuableTaggedItem, Comparison, Animal, - Vegetable, Mineral) - - -class GenericRelationsTests(TestCase): - def test_generic_relations(self): - # Create the world in 7 lines of code... - lion = Animal.objects.create(common_name="Lion", latin_name="Panthera leo") - platypus = Animal.objects.create( - common_name="Platypus", latin_name="Ornithorhynchus anatinus" - ) - eggplant = Vegetable.objects.create(name="Eggplant", is_yucky=True) - bacon = Vegetable.objects.create(name="Bacon", is_yucky=False) - quartz = Mineral.objects.create(name="Quartz", hardness=7) - - # Objects with declared GenericRelations can be tagged directly -- the - # API mimics the many-to-many API. - bacon.tags.create(tag="fatty") - bacon.tags.create(tag="salty") - lion.tags.create(tag="yellow") - lion.tags.create(tag="hairy") - platypus.tags.create(tag="fatty") - self.assertQuerysetEqual(lion.tags.all(), [ - "<TaggedItem: hairy>", - "<TaggedItem: yellow>" - ]) - self.assertQuerysetEqual(bacon.tags.all(), [ - "<TaggedItem: fatty>", - "<TaggedItem: salty>" - ]) - - # You can easily access the content object like a foreign key. - t = TaggedItem.objects.get(tag="salty") - self.assertEqual(t.content_object, bacon) - - # Recall that the Mineral class doesn't have an explicit GenericRelation - # defined. That's OK, because you can create TaggedItems explicitly. - tag1 = TaggedItem.objects.create(content_object=quartz, tag="shiny") - tag2 = TaggedItem.objects.create(content_object=quartz, tag="clearish") - - # However, excluding GenericRelations means your lookups have to be a - # bit more explicit. - ctype = ContentType.objects.get_for_model(quartz) - q = TaggedItem.objects.filter( - content_type__pk=ctype.id, object_id=quartz.id - ) - self.assertQuerysetEqual(q, [ - "<TaggedItem: clearish>", - "<TaggedItem: shiny>" - ]) - - # You can set a generic foreign key in the way you'd expect. - tag1.content_object = platypus - tag1.save() - self.assertQuerysetEqual(platypus.tags.all(), [ - "<TaggedItem: fatty>", - "<TaggedItem: shiny>" - ]) - q = TaggedItem.objects.filter( - content_type__pk=ctype.id, object_id=quartz.id - ) - self.assertQuerysetEqual(q, ["<TaggedItem: clearish>"]) - - # Queries across generic relations respect the content types. Even - # though there are two TaggedItems with a tag of "fatty", this query - # only pulls out the one with the content type related to Animals. - self.assertQuerysetEqual(Animal.objects.order_by('common_name'), [ - "<Animal: Lion>", - "<Animal: Platypus>" - ]) - self.assertQuerysetEqual(Animal.objects.filter(tags__tag='fatty'), [ - "<Animal: Platypus>" - ]) - self.assertQuerysetEqual(Animal.objects.exclude(tags__tag='fatty'), [ - "<Animal: Lion>" - ]) - - # If you delete an object with an explicit Generic relation, the related - # objects are deleted when the source object is deleted. - # Original list of tags: - comp_func = lambda obj: ( - obj.tag, obj.content_type.model_class(), obj.object_id - ) - - self.assertQuerysetEqual(TaggedItem.objects.all(), [ - (u'clearish', Mineral, quartz.pk), - (u'fatty', Animal, platypus.pk), - (u'fatty', Vegetable, bacon.pk), - (u'hairy', Animal, lion.pk), - (u'salty', Vegetable, bacon.pk), - (u'shiny', Animal, platypus.pk), - (u'yellow', Animal, lion.pk) - ], - comp_func - ) - lion.delete() - self.assertQuerysetEqual(TaggedItem.objects.all(), [ - (u'clearish', Mineral, quartz.pk), - (u'fatty', Animal, platypus.pk), - (u'fatty', Vegetable, bacon.pk), - (u'salty', Vegetable, bacon.pk), - (u'shiny', Animal, platypus.pk) - ], - comp_func - ) - - # If Generic Relation is not explicitly defined, any related objects - # remain after deletion of the source object. - quartz_pk = quartz.pk - quartz.delete() - self.assertQuerysetEqual(TaggedItem.objects.all(), [ - (u'clearish', Mineral, quartz_pk), - (u'fatty', Animal, platypus.pk), - (u'fatty', Vegetable, bacon.pk), - (u'salty', Vegetable, bacon.pk), - (u'shiny', Animal, platypus.pk) - ], - comp_func - ) - # If you delete a tag, the objects using the tag are unaffected - # (other than losing a tag) - tag = TaggedItem.objects.order_by("id")[0] - tag.delete() - self.assertQuerysetEqual(bacon.tags.all(), ["<TaggedItem: salty>"]) - self.assertQuerysetEqual(TaggedItem.objects.all(), [ - (u'clearish', Mineral, quartz_pk), - (u'fatty', Animal, platypus.pk), - (u'salty', Vegetable, bacon.pk), - (u'shiny', Animal, platypus.pk) - ], - comp_func - ) - TaggedItem.objects.filter(tag='fatty').delete() - ctype = ContentType.objects.get_for_model(lion) - self.assertQuerysetEqual(Animal.objects.filter(tags__content_type=ctype), [ - "<Animal: Platypus>" - ]) - - - def test_multiple_gfk(self): - # Simple tests for multiple GenericForeignKeys - # only uses one model, since the above tests should be sufficient. - tiger = Animal.objects.create(common_name="tiger") - cheetah = Animal.objects.create(common_name="cheetah") - bear = Animal.objects.create(common_name="bear") - - # Create directly - Comparison.objects.create( - first_obj=cheetah, other_obj=tiger, comparative="faster" - ) - Comparison.objects.create( - first_obj=tiger, other_obj=cheetah, comparative="cooler" - ) - - # Create using GenericRelation - tiger.comparisons.create(other_obj=bear, comparative="cooler") - tiger.comparisons.create(other_obj=cheetah, comparative="stronger") - self.assertQuerysetEqual(cheetah.comparisons.all(), [ - "<Comparison: cheetah is faster than tiger>" - ]) - - # Filtering works - self.assertQuerysetEqual(tiger.comparisons.filter(comparative="cooler"), [ - "<Comparison: tiger is cooler than cheetah>", - "<Comparison: tiger is cooler than bear>" - ]) - - # Filtering and deleting works - subjective = ["cooler"] - tiger.comparisons.filter(comparative__in=subjective).delete() - self.assertQuerysetEqual(Comparison.objects.all(), [ - "<Comparison: cheetah is faster than tiger>", - "<Comparison: tiger is stronger than cheetah>" - ]) - - # If we delete cheetah, Comparisons with cheetah as 'first_obj' will be - # deleted since Animal has an explicit GenericRelation to Comparison - # through first_obj. Comparisons with cheetah as 'other_obj' will not - # be deleted. - cheetah.delete() - self.assertQuerysetEqual(Comparison.objects.all(), [ - "<Comparison: tiger is stronger than None>" - ]) - - def test_gfk_subclasses(self): - # GenericForeignKey should work with subclasses (see #8309) - quartz = Mineral.objects.create(name="Quartz", hardness=7) - valuedtag = ValuableTaggedItem.objects.create( - content_object=quartz, tag="shiny", value=10 - ) - self.assertEqual(valuedtag.content_object, quartz) - - def test_generic_inline_formsets(self): - GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) - formset = GenericFormSet() - self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""") - - formset = GenericFormSet(instance=Animal()) - self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""") - - platypus = Animal.objects.create( - common_name="Platypus", latin_name="Ornithorhynchus anatinus" - ) - platypus.tags.create(tag="shiny") - GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) - formset = GenericFormSet(instance=platypus) - tagged_item_id = TaggedItem.objects.get( - tag='shiny', object_id=platypus.id - ).id - self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" value="shiny" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" value="%s" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p><p><label for="id_generic_relations-taggeditem-content_type-object_id-1-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-1-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-1-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-1-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-1-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-1-id" id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tagged_item_id) - - lion = Animal.objects.create(common_name="Lion", latin_name="Panthera leo") - formset = GenericFormSet(instance=lion, prefix='x') - self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_x-0-tag">Tag:</label> <input id="id_x-0-tag" type="text" name="x-0-tag" maxlength="50" /></p> -<p><label for="id_x-0-DELETE">Delete:</label> <input type="checkbox" name="x-0-DELETE" id="id_x-0-DELETE" /><input type="hidden" name="x-0-id" id="id_x-0-id" /></p>""") diff --git a/parts/django/tests/modeltests/get_latest/__init__.py b/parts/django/tests/modeltests/get_latest/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/get_latest/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/get_latest/models.py b/parts/django/tests/modeltests/get_latest/models.py deleted file mode 100644 index 1eeb299..0000000 --- a/parts/django/tests/modeltests/get_latest/models.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -8. get_latest_by - -Models can have a ``get_latest_by`` attribute, which should be set to the name -of a ``DateField`` or ``DateTimeField``. If ``get_latest_by`` exists, the -model's manager will get a ``latest()`` method, which will return the latest -object in the database according to that field. "Latest" means "having the date -farthest into the future." -""" - -from django.db import models - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - expire_date = models.DateField() - class Meta: - get_latest_by = 'pub_date' - - def __unicode__(self): - return self.headline - -class Person(models.Model): - name = models.CharField(max_length=30) - birthday = models.DateField() - - # Note that this model doesn't have "get_latest_by" set. - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/get_latest/tests.py b/parts/django/tests/modeltests/get_latest/tests.py deleted file mode 100644 index 3c3588b..0000000 --- a/parts/django/tests/modeltests/get_latest/tests.py +++ /dev/null @@ -1,53 +0,0 @@ -from datetime import datetime - -from django.test import TestCase - -from models import Article, Person - - -class LatestTests(TestCase): - def test_latest(self): - # Because no Articles exist yet, latest() raises ArticleDoesNotExist. - self.assertRaises(Article.DoesNotExist, Article.objects.latest) - - a1 = Article.objects.create( - headline="Article 1", pub_date=datetime(2005, 7, 26), - expire_date=datetime(2005, 9, 1) - ) - a2 = Article.objects.create( - headline="Article 2", pub_date=datetime(2005, 7, 27), - expire_date=datetime(2005, 7, 28) - ) - a3 = Article.objects.create( - headline="Article 3", pub_date=datetime(2005, 7, 27), - expire_date=datetime(2005, 8, 27) - ) - a4 = Article.objects.create( - headline="Article 4", pub_date=datetime(2005, 7, 28), - expire_date=datetime(2005, 7, 30) - ) - - # Get the latest Article. - self.assertEqual(Article.objects.latest(), a4) - # Get the latest Article that matches certain filters. - self.assertEqual( - Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest(), - a1 - ) - - # Pass a custom field name to latest() to change the field that's used - # to determine the latest object. - self.assertEqual(Article.objects.latest('expire_date'), a1) - self.assertEqual( - Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date'), - a3, - ) - - def test_latest_manual(self): - # You can still use latest() with a model that doesn't have - # "get_latest_by" set -- just pass in the field name manually. - p1 = Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1)) - p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3)) - self.assertRaises(AssertionError, Person.objects.latest) - - self.assertEqual(Person.objects.latest("birthday"), p2) diff --git a/parts/django/tests/modeltests/get_object_or_404/__init__.py b/parts/django/tests/modeltests/get_object_or_404/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/get_object_or_404/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/get_object_or_404/models.py b/parts/django/tests/modeltests/get_object_or_404/models.py deleted file mode 100644 index eb3cd82..0000000 --- a/parts/django/tests/modeltests/get_object_or_404/models.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -35. DB-API Shortcuts - -``get_object_or_404()`` is a shortcut function to be used in view functions for -performing a ``get()`` lookup and raising a ``Http404`` exception if a -``DoesNotExist`` exception was raised during the ``get()`` call. - -``get_list_or_404()`` is a shortcut function to be used in view functions for -performing a ``filter()`` lookup and raising a ``Http404`` exception if a -``DoesNotExist`` exception was raised during the ``filter()`` call. -""" - -from django.db import models -from django.http import Http404 -from django.shortcuts import get_object_or_404, get_list_or_404 - -class Author(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return self.name - -class ArticleManager(models.Manager): - def get_query_set(self): - return super(ArticleManager, self).get_query_set().filter(authors__name__icontains='sir') - -class Article(models.Model): - authors = models.ManyToManyField(Author) - title = models.CharField(max_length=50) - objects = models.Manager() - by_a_sir = ArticleManager() - - def __unicode__(self): - return self.title diff --git a/parts/django/tests/modeltests/get_object_or_404/tests.py b/parts/django/tests/modeltests/get_object_or_404/tests.py deleted file mode 100644 index b8c4f75..0000000 --- a/parts/django/tests/modeltests/get_object_or_404/tests.py +++ /dev/null @@ -1,80 +0,0 @@ -from django.http import Http404 -from django.shortcuts import get_object_or_404, get_list_or_404 -from django.test import TestCase - -from models import Author, Article - - -class GetObjectOr404Tests(TestCase): - def test_get_object_or_404(self): - a1 = Author.objects.create(name="Brave Sir Robin") - a2 = Author.objects.create(name="Patsy") - - # No Articles yet, so we should get a Http404 error. - self.assertRaises(Http404, get_object_or_404, Article, title="Foo") - - article = Article.objects.create(title="Run away!") - article.authors = [a1, a2] - # get_object_or_404 can be passed a Model to query. - self.assertEqual( - get_object_or_404(Article, title__contains="Run"), - article - ) - - # We can also use the Article manager through an Author object. - self.assertEqual( - get_object_or_404(a1.article_set, title__contains="Run"), - article - ) - - # No articles containing "Camelot". This should raise a Http404 error. - self.assertRaises(Http404, - get_object_or_404, a1.article_set, title__contains="Camelot" - ) - - # Custom managers can be used too. - self.assertEqual( - get_object_or_404(Article.by_a_sir, title="Run away!"), - article - ) - - # QuerySets can be used too. - self.assertEqual( - get_object_or_404(Article.objects.all(), title__contains="Run"), - article - ) - - # Just as when using a get() lookup, you will get an error if more than - # one object is returned. - - self.assertRaises(Author.MultipleObjectsReturned, - get_object_or_404, Author.objects.all() - ) - - # Using an EmptyQuerySet raises a Http404 error. - self.assertRaises(Http404, - get_object_or_404, Article.objects.none(), title__contains="Run" - ) - - # get_list_or_404 can be used to get lists of objects - self.assertEqual( - get_list_or_404(a1.article_set, title__icontains="Run"), - [article] - ) - - # Http404 is returned if the list is empty. - self.assertRaises(Http404, - get_list_or_404, a1.article_set, title__icontains="Shrubbery" - ) - - # Custom managers can be used too. - self.assertEqual( - get_list_or_404(Article.by_a_sir, title__icontains="Run"), - [article] - ) - - # QuerySets can be used too. - self.assertEqual( - get_list_or_404(Article.objects.all(), title__icontains="Run"), - [article] - ) diff --git a/parts/django/tests/modeltests/get_or_create/__init__.py b/parts/django/tests/modeltests/get_or_create/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/get_or_create/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/get_or_create/models.py b/parts/django/tests/modeltests/get_or_create/models.py deleted file mode 100644 index db5719b..0000000 --- a/parts/django/tests/modeltests/get_or_create/models.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -33. get_or_create() - -``get_or_create()`` does what it says: it tries to look up an object with the -given parameters. If an object isn't found, it creates one with the given -parameters. -""" - -from django.db import models, IntegrityError - -class Person(models.Model): - first_name = models.CharField(max_length=100) - last_name = models.CharField(max_length=100) - birthday = models.DateField() - - def __unicode__(self): - return u'%s %s' % (self.first_name, self.last_name) - -class ManualPrimaryKeyTest(models.Model): - id = models.IntegerField(primary_key=True) - data = models.CharField(max_length=100) diff --git a/parts/django/tests/modeltests/get_or_create/tests.py b/parts/django/tests/modeltests/get_or_create/tests.py deleted file mode 100644 index 1999b20..0000000 --- a/parts/django/tests/modeltests/get_or_create/tests.py +++ /dev/null @@ -1,52 +0,0 @@ -from datetime import date - -from django.db import IntegrityError -from django.test import TransactionTestCase - -from models import Person, ManualPrimaryKeyTest - - -class GetOrCreateTests(TransactionTestCase): - def test_get_or_create(self): - p = Person.objects.create( - first_name='John', last_name='Lennon', birthday=date(1940, 10, 9) - ) - - p, created = Person.objects.get_or_create( - first_name="John", last_name="Lennon", defaults={ - "birthday": date(1940, 10, 9) - } - ) - self.assertFalse(created) - self.assertEqual(Person.objects.count(), 1) - - p, created = Person.objects.get_or_create( - first_name='George', last_name='Harrison', defaults={ - 'birthday': date(1943, 2, 25) - } - ) - self.assertTrue(created) - self.assertEqual(Person.objects.count(), 2) - - # If we execute the exact same statement, it won't create a Person. - p, created = Person.objects.get_or_create( - first_name='George', last_name='Harrison', defaults={ - 'birthday': date(1943, 2, 25) - } - ) - self.assertFalse(created) - self.assertEqual(Person.objects.count(), 2) - - # If you don't specify a value or default value for all required - # fields, you will get an error. - self.assertRaises(IntegrityError, - Person.objects.get_or_create, first_name="Tom", last_name="Smith" - ) - - # If you specify an existing primary key, but different other fields, - # then you will get an error and data will not be updated. - m = ManualPrimaryKeyTest.objects.create(id=1, data="Original") - self.assertRaises(IntegrityError, - ManualPrimaryKeyTest.objects.get_or_create, id=1, data="Different" - ) - self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original") diff --git a/parts/django/tests/modeltests/invalid_models/__init__.py b/parts/django/tests/modeltests/invalid_models/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/modeltests/invalid_models/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/modeltests/invalid_models/models.py b/parts/django/tests/modeltests/invalid_models/models.py deleted file mode 100644 index 09301ed..0000000 --- a/parts/django/tests/modeltests/invalid_models/models.py +++ /dev/null @@ -1,335 +0,0 @@ -""" -26. Invalid models - -This example exists purely to point out errors in models. -""" - -from django.contrib.contenttypes import generic -from django.db import models - -class FieldErrors(models.Model): - charfield = models.CharField() - charfield2 = models.CharField(max_length=-1) - charfield3 = models.CharField(max_length="bad") - decimalfield = models.DecimalField() - decimalfield2 = models.DecimalField(max_digits=-1, decimal_places=-1) - decimalfield3 = models.DecimalField(max_digits="bad", decimal_places="bad") - filefield = models.FileField() - choices = models.CharField(max_length=10, choices='bad') - choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)]) - index = models.CharField(max_length=10, db_index='bad') - field_ = models.CharField(max_length=10) - nullbool = models.BooleanField(null=True) - -class Target(models.Model): - tgt_safe = models.CharField(max_length=10) - clash1 = models.CharField(max_length=10) - clash2 = models.CharField(max_length=10) - - clash1_set = models.CharField(max_length=10) - -class Clash1(models.Model): - src_safe = models.CharField(max_length=10) - - foreign = models.ForeignKey(Target) - m2m = models.ManyToManyField(Target) - -class Clash2(models.Model): - src_safe = models.CharField(max_length=10) - - foreign_1 = models.ForeignKey(Target, related_name='id') - foreign_2 = models.ForeignKey(Target, related_name='src_safe') - - m2m_1 = models.ManyToManyField(Target, related_name='id') - m2m_2 = models.ManyToManyField(Target, related_name='src_safe') - -class Target2(models.Model): - clash3 = models.CharField(max_length=10) - foreign_tgt = models.ForeignKey(Target) - clashforeign_set = models.ForeignKey(Target) - - m2m_tgt = models.ManyToManyField(Target) - clashm2m_set = models.ManyToManyField(Target) - -class Clash3(models.Model): - src_safe = models.CharField(max_length=10) - - foreign_1 = models.ForeignKey(Target2, related_name='foreign_tgt') - foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt') - - m2m_1 = models.ManyToManyField(Target2, related_name='foreign_tgt') - m2m_2 = models.ManyToManyField(Target2, related_name='m2m_tgt') - -class ClashForeign(models.Model): - foreign = models.ForeignKey(Target2) - -class ClashM2M(models.Model): - m2m = models.ManyToManyField(Target2) - -class SelfClashForeign(models.Model): - src_safe = models.CharField(max_length=10) - selfclashforeign = models.CharField(max_length=10) - - selfclashforeign_set = models.ForeignKey("SelfClashForeign") - foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id') - foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe') - -class ValidM2M(models.Model): - src_safe = models.CharField(max_length=10) - validm2m = models.CharField(max_length=10) - - # M2M fields are symmetrical by default. Symmetrical M2M fields - # on self don't require a related accessor, so many potential - # clashes are avoided. - validm2m_set = models.ManyToManyField("self") - - m2m_1 = models.ManyToManyField("self", related_name='id') - m2m_2 = models.ManyToManyField("self", related_name='src_safe') - - m2m_3 = models.ManyToManyField('self') - m2m_4 = models.ManyToManyField('self') - -class SelfClashM2M(models.Model): - src_safe = models.CharField(max_length=10) - selfclashm2m = models.CharField(max_length=10) - - # Non-symmetrical M2M fields _do_ have related accessors, so - # there is potential for clashes. - selfclashm2m_set = models.ManyToManyField("self", symmetrical=False) - - m2m_1 = models.ManyToManyField("self", related_name='id', symmetrical=False) - m2m_2 = models.ManyToManyField("self", related_name='src_safe', symmetrical=False) - - m2m_3 = models.ManyToManyField('self', symmetrical=False) - m2m_4 = models.ManyToManyField('self', symmetrical=False) - -class Model(models.Model): - "But it's valid to call a model Model." - year = models.PositiveIntegerField() #1960 - make = models.CharField(max_length=10) #Aston Martin - name = models.CharField(max_length=10) #DB 4 GT - -class Car(models.Model): - colour = models.CharField(max_length=5) - model = models.ForeignKey(Model) - -class MissingRelations(models.Model): - rel1 = models.ForeignKey("Rel1") - rel2 = models.ManyToManyField("Rel2") - -class MissingManualM2MModel(models.Model): - name = models.CharField(max_length=5) - missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel") - -class Person(models.Model): - name = models.CharField(max_length=5) - -class Group(models.Model): - name = models.CharField(max_length=5) - primary = models.ManyToManyField(Person, through="Membership", related_name="primary") - secondary = models.ManyToManyField(Person, through="Membership", related_name="secondary") - tertiary = models.ManyToManyField(Person, through="RelationshipDoubleFK", related_name="tertiary") - -class GroupTwo(models.Model): - name = models.CharField(max_length=5) - primary = models.ManyToManyField(Person, through="Membership") - secondary = models.ManyToManyField(Group, through="MembershipMissingFK") - -class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) - not_default_or_null = models.CharField(max_length=5) - -class MembershipMissingFK(models.Model): - person = models.ForeignKey(Person) - -class PersonSelfRefM2M(models.Model): - name = models.CharField(max_length=5) - friends = models.ManyToManyField('self', through="Relationship") - too_many_friends = models.ManyToManyField('self', through="RelationshipTripleFK") - -class PersonSelfRefM2MExplicit(models.Model): - name = models.CharField(max_length=5) - friends = models.ManyToManyField('self', through="ExplicitRelationship", symmetrical=True) - -class Relationship(models.Model): - first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set") - second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set") - date_added = models.DateTimeField() - -class ExplicitRelationship(models.Model): - first = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_from_set") - second = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_to_set") - date_added = models.DateTimeField() - -class RelationshipTripleFK(models.Model): - first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set_2") - second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set_2") - third = models.ForeignKey(PersonSelfRefM2M, related_name="too_many_by_far") - date_added = models.DateTimeField() - -class RelationshipDoubleFK(models.Model): - first = models.ForeignKey(Person, related_name="first_related_name") - second = models.ForeignKey(Person, related_name="second_related_name") - third = models.ForeignKey(Group, related_name="rel_to_set") - date_added = models.DateTimeField() - -class AbstractModel(models.Model): - name = models.CharField(max_length=10) - class Meta: - abstract = True - -class AbstractRelationModel(models.Model): - fk1 = models.ForeignKey('AbstractModel') - fk2 = models.ManyToManyField('AbstractModel') - -class UniqueM2M(models.Model): - """ Model to test for unique ManyToManyFields, which are invalid. """ - unique_people = models.ManyToManyField(Person, unique=True) - -class NonUniqueFKTarget1(models.Model): - """ Model to test for non-unique FK target in yet-to-be-defined model: expect an error """ - tgt = models.ForeignKey('FKTarget', to_field='bad') - -class UniqueFKTarget1(models.Model): - """ Model to test for unique FK target in yet-to-be-defined model: expect no error """ - tgt = models.ForeignKey('FKTarget', to_field='good') - -class FKTarget(models.Model): - bad = models.IntegerField() - good = models.IntegerField(unique=True) - -class NonUniqueFKTarget2(models.Model): - """ Model to test for non-unique FK target in previously seen model: expect an error """ - tgt = models.ForeignKey(FKTarget, to_field='bad') - -class UniqueFKTarget2(models.Model): - """ Model to test for unique FK target in previously seen model: expect no error """ - tgt = models.ForeignKey(FKTarget, to_field='good') - -class NonExistingOrderingWithSingleUnderscore(models.Model): - class Meta: - ordering = ("does_not_exist",) - -class Tag(models.Model): - name = models.CharField("name", max_length=20) - -class TaggedObject(models.Model): - object_id = models.PositiveIntegerField("Object ID") - tag = models.ForeignKey(Tag) - content_object = generic.GenericForeignKey() - -class UserTaggedObject(models.Model): - object_tag = models.ForeignKey(TaggedObject) - -class ArticleAttachment(models.Model): - tags = generic.GenericRelation(TaggedObject) - user_tags = generic.GenericRelation(UserTaggedObject) - -model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute that is a positive integer. -invalid_models.fielderrors: "charfield2": CharFields require a "max_length" attribute that is a positive integer. -invalid_models.fielderrors: "charfield3": CharFields require a "max_length" attribute that is a positive integer. -invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute that is a non-negative integer. -invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute that is a positive integer. -invalid_models.fielderrors: "decimalfield2": DecimalFields require a "decimal_places" attribute that is a non-negative integer. -invalid_models.fielderrors: "decimalfield2": DecimalFields require a "max_digits" attribute that is a positive integer. -invalid_models.fielderrors: "decimalfield3": DecimalFields require a "decimal_places" attribute that is a non-negative integer. -invalid_models.fielderrors: "decimalfield3": DecimalFields require a "max_digits" attribute that is a positive integer. -invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute. -invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list). -invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. -invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. -invalid_models.fielderrors: "index": "db_index" should be either None, True or False. -invalid_models.fielderrors: "field_": Field names cannot end with underscores, because this would lead to ambiguous queryset filters. -invalid_models.fielderrors: "nullbool": BooleanFields do not accept null values. Use a NullBooleanField instead. -invalid_models.clash1: Accessor for field 'foreign' clashes with field 'Target.clash1_set'. Add a related_name argument to the definition for 'foreign'. -invalid_models.clash1: Accessor for field 'foreign' clashes with related m2m field 'Target.clash1_set'. Add a related_name argument to the definition for 'foreign'. -invalid_models.clash1: Reverse query name for field 'foreign' clashes with field 'Target.clash1'. Add a related_name argument to the definition for 'foreign'. -invalid_models.clash1: Accessor for m2m field 'm2m' clashes with field 'Target.clash1_set'. Add a related_name argument to the definition for 'm2m'. -invalid_models.clash1: Accessor for m2m field 'm2m' clashes with related field 'Target.clash1_set'. Add a related_name argument to the definition for 'm2m'. -invalid_models.clash1: Reverse query name for m2m field 'm2m' clashes with field 'Target.clash1'. Add a related_name argument to the definition for 'm2m'. -invalid_models.clash2: Accessor for field 'foreign_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash2: Accessor for field 'foreign_1' clashes with related m2m field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash2: Reverse query name for field 'foreign_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash2: Reverse query name for field 'foreign_1' clashes with related m2m field 'Target.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash2: Accessor for field 'foreign_2' clashes with related m2m field 'Target.src_safe'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash2: Reverse query name for field 'foreign_2' clashes with related m2m field 'Target.src_safe'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash2: Accessor for m2m field 'm2m_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash2: Accessor for m2m field 'm2m_1' clashes with related field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash2: Reverse query name for m2m field 'm2m_1' clashes with field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash2: Reverse query name for m2m field 'm2m_1' clashes with related field 'Target.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash2: Accessor for m2m field 'm2m_2' clashes with related field 'Target.src_safe'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clash2: Reverse query name for m2m field 'm2m_2' clashes with related field 'Target.src_safe'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clash3: Accessor for field 'foreign_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash3: Accessor for field 'foreign_1' clashes with related m2m field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash3: Reverse query name for field 'foreign_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash3: Reverse query name for field 'foreign_1' clashes with related m2m field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.clash3: Accessor for field 'foreign_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash3: Accessor for field 'foreign_2' clashes with related m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash3: Reverse query name for field 'foreign_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash3: Reverse query name for field 'foreign_2' clashes with related m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.clash3: Accessor for m2m field 'm2m_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash3: Accessor for m2m field 'm2m_1' clashes with related field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash3: Reverse query name for m2m field 'm2m_1' clashes with field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash3: Reverse query name for m2m field 'm2m_1' clashes with related field 'Target2.foreign_tgt'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.clash3: Accessor for m2m field 'm2m_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clash3: Accessor for m2m field 'm2m_2' clashes with related field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clash3: Reverse query name for m2m field 'm2m_2' clashes with m2m field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clash3: Reverse query name for m2m field 'm2m_2' clashes with related field 'Target2.m2m_tgt'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.clashforeign: Accessor for field 'foreign' clashes with field 'Target2.clashforeign_set'. Add a related_name argument to the definition for 'foreign'. -invalid_models.clashm2m: Accessor for m2m field 'm2m' clashes with m2m field 'Target2.clashm2m_set'. Add a related_name argument to the definition for 'm2m'. -invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'. -invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'. -invalid_models.target2: Accessor for field 'foreign_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'foreign_tgt'. -invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'. -invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'. -invalid_models.target2: Accessor for field 'clashforeign_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashforeign_set'. -invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'. -invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'. -invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'. -invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'. -invalid_models.target2: Accessor for m2m field 'm2m_tgt' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'm2m_tgt'. -invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'. -invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'. -invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'. -invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'. -invalid_models.target2: Accessor for m2m field 'clashm2m_set' clashes with related m2m field 'Target.target2_set'. Add a related_name argument to the definition for 'clashm2m_set'. -invalid_models.selfclashforeign: Accessor for field 'selfclashforeign_set' clashes with field 'SelfClashForeign.selfclashforeign_set'. Add a related_name argument to the definition for 'selfclashforeign_set'. -invalid_models.selfclashforeign: Reverse query name for field 'selfclashforeign_set' clashes with field 'SelfClashForeign.selfclashforeign'. Add a related_name argument to the definition for 'selfclashforeign_set'. -invalid_models.selfclashforeign: Accessor for field 'foreign_1' clashes with field 'SelfClashForeign.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.selfclashforeign: Reverse query name for field 'foreign_1' clashes with field 'SelfClashForeign.id'. Add a related_name argument to the definition for 'foreign_1'. -invalid_models.selfclashforeign: Accessor for field 'foreign_2' clashes with field 'SelfClashForeign.src_safe'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.selfclashforeign: Reverse query name for field 'foreign_2' clashes with field 'SelfClashForeign.src_safe'. Add a related_name argument to the definition for 'foreign_2'. -invalid_models.selfclashm2m: Accessor for m2m field 'selfclashm2m_set' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'selfclashm2m_set'. -invalid_models.selfclashm2m: Reverse query name for m2m field 'selfclashm2m_set' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'selfclashm2m_set'. -invalid_models.selfclashm2m: Accessor for m2m field 'selfclashm2m_set' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'selfclashm2m_set'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_1' clashes with field 'SelfClashM2M.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_2' clashes with field 'SelfClashM2M.src_safe'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_1' clashes with field 'SelfClashM2M.id'. Add a related_name argument to the definition for 'm2m_1'. -invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_2' clashes with field 'SelfClashM2M.src_safe'. Add a related_name argument to the definition for 'm2m_2'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_3' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_3'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'. -invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'. -invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_3'. -invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_4' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_4'. -invalid_models.missingrelations: 'rel1' has a relation with model Rel1, which has either not been installed or is abstract. -invalid_models.missingrelations: 'rel2' has an m2m relation with model Rel2, which has either not been installed or is abstract. -invalid_models.grouptwo: 'primary' is a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo -invalid_models.grouptwo: 'secondary' is a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo -invalid_models.missingmanualm2mmodel: 'missing_m2m' specifies an m2m relation through model MissingM2MModel, which has not been installed -invalid_models.group: The model Group has two manually-defined m2m relations through the model Membership, which is not permitted. Please consider using an extra field on your intermediary model instead. -invalid_models.group: Intermediary model RelationshipDoubleFK has more than one foreign key to Person, which is ambiguous and is not permitted. -invalid_models.personselfrefm2m: Many-to-many fields with intermediate tables cannot be symmetrical. -invalid_models.personselfrefm2m: Intermediary model RelationshipTripleFK has more than two foreign keys to PersonSelfRefM2M, which is ambiguous and is not permitted. -invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical. -invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract. -invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract. -invalid_models.uniquem2m: ManyToManyFields cannot be unique. Remove the unique argument on 'unique_people'. -invalid_models.nonuniquefktarget1: Field 'bad' under model 'FKTarget' must have a unique=True constraint. -invalid_models.nonuniquefktarget2: Field 'bad' under model 'FKTarget' must have a unique=True constraint. -invalid_models.nonexistingorderingwithsingleunderscore: "ordering" refers to "does_not_exist", a field that doesn't exist. -invalid_models.articleattachment: Model 'UserTaggedObject' must have a GenericForeignKey in order to create a GenericRelation that points to it. -""" diff --git a/parts/django/tests/modeltests/lookup/__init__.py b/parts/django/tests/modeltests/lookup/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/lookup/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/lookup/models.py b/parts/django/tests/modeltests/lookup/models.py deleted file mode 100644 index 99eec51..0000000 --- a/parts/django/tests/modeltests/lookup/models.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -7. The lookup API - -This demonstrates features of the database API. -""" - -from django.db import models - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateTimeField() - class Meta: - ordering = ('-pub_date', 'headline') - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/lookup/tests.py b/parts/django/tests/modeltests/lookup/tests.py deleted file mode 100644 index 9e0b68e..0000000 --- a/parts/django/tests/modeltests/lookup/tests.py +++ /dev/null @@ -1,547 +0,0 @@ -from datetime import datetime -from operator import attrgetter - -from django.conf import settings -from django.core.exceptions import FieldError -from django.db import connection, DEFAULT_DB_ALIAS -from django.test import TestCase - -from models import Article - -class LookupTests(TestCase): - - #def setUp(self): - def setUp(self): - # Create a couple of Articles. - self.a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) - self.a1.save() - self.a2 = Article(headline='Article 2', pub_date=datetime(2005, 7, 27)) - self.a2.save() - self.a3 = Article(headline='Article 3', pub_date=datetime(2005, 7, 27)) - self.a3.save() - self.a4 = Article(headline='Article 4', pub_date=datetime(2005, 7, 28)) - self.a4.save() - self.a5 = Article(headline='Article 5', pub_date=datetime(2005, 8, 1, 9, 0)) - self.a5.save() - self.a6 = Article(headline='Article 6', pub_date=datetime(2005, 8, 1, 8, 0)) - self.a6.save() - self.a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 27)) - self.a7.save() - - def test_exists(self): - # We can use .exists() to check that there are some - self.assertTrue(Article.objects.exists()) - for a in Article.objects.all(): - a.delete() - # There should be none now! - self.assertFalse(Article.objects.exists()) - - def test_lookup_int_as_str(self): - # Integer value can be queried using string - self.assertQuerysetEqual(Article.objects.filter(id__iexact=str(self.a1.id)), - ['<Article: Article 1>']) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] in ( - 'django.db.backends.postgresql', - 'django.db.backends.postgresql_psycopg2'): - def test_lookup_date_as_str(self): - # A date lookup can be performed using a string search - self.assertQuerysetEqual(Article.objects.filter(pub_date__startswith='2005'), - [ - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - - def test_iterator(self): - # Each QuerySet gets iterator(), which is a generator that "lazily" - # returns results using database-level iteration. - self.assertQuerysetEqual(Article.objects.iterator(), - [ - 'Article 5', - 'Article 6', - 'Article 4', - 'Article 2', - 'Article 3', - 'Article 7', - 'Article 1', - ], - transform=attrgetter('headline')) - # iterator() can be used on any QuerySet. - self.assertQuerysetEqual( - Article.objects.filter(headline__endswith='4').iterator(), - ['Article 4'], - transform=attrgetter('headline')) - - def test_count(self): - # count() returns the number of objects matching search criteria. - self.assertEqual(Article.objects.count(), 7) - self.assertEqual(Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).count(), 3) - self.assertEqual(Article.objects.filter(headline__startswith='Blah blah').count(), 0) - - # count() should respect sliced query sets. - articles = Article.objects.all() - self.assertEqual(articles.count(), 7) - self.assertEqual(articles[:4].count(), 4) - self.assertEqual(articles[1:100].count(), 6) - self.assertEqual(articles[10:100].count(), 0) - - # Date and date/time lookups can also be done with strings. - self.assertEqual(Article.objects.filter(pub_date__exact='2005-07-27 00:00:00').count(), 3) - - def test_in_bulk(self): - # in_bulk() takes a list of IDs and returns a dictionary mapping IDs to objects. - arts = Article.objects.in_bulk([self.a1.id, self.a2.id]) - self.assertEqual(arts[self.a1.id], self.a1) - self.assertEqual(arts[self.a2.id], self.a2) - self.assertEqual(Article.objects.in_bulk([self.a3.id]), {self.a3.id: self.a3}) - self.assertEqual(Article.objects.in_bulk(set([self.a3.id])), {self.a3.id: self.a3}) - self.assertEqual(Article.objects.in_bulk(frozenset([self.a3.id])), {self.a3.id: self.a3}) - self.assertEqual(Article.objects.in_bulk((self.a3.id,)), {self.a3.id: self.a3}) - self.assertEqual(Article.objects.in_bulk([1000]), {}) - self.assertEqual(Article.objects.in_bulk([]), {}) - self.assertRaises(AssertionError, Article.objects.in_bulk, 'foo') - self.assertRaises(TypeError, Article.objects.in_bulk) - self.assertRaises(TypeError, Article.objects.in_bulk, headline__startswith='Blah') - - def test_values(self): - # values() returns a list of dictionaries instead of object instances -- - # and you can specify which fields you want to retrieve. - identity = lambda x:x - self.assertQuerysetEqual(Article.objects.values('headline'), - [ - {'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'}, - ], - transform=identity) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id'), - [{'id': self.a2.id}, {'id': self.a3.id}, {'id': self.a7.id}], - transform=identity) - self.assertQuerysetEqual(Article.objects.values('id', 'headline'), - [ - {'id': self.a5.id, 'headline': 'Article 5'}, - {'id': self.a6.id, 'headline': 'Article 6'}, - {'id': self.a4.id, 'headline': 'Article 4'}, - {'id': self.a2.id, 'headline': 'Article 2'}, - {'id': self.a3.id, 'headline': 'Article 3'}, - {'id': self.a7.id, 'headline': 'Article 7'}, - {'id': self.a1.id, 'headline': 'Article 1'}, - ], - transform=identity) - # You can use values() with iterator() for memory savings, - # because iterator() uses database-level iteration. - self.assertQuerysetEqual(Article.objects.values('id', 'headline').iterator(), - [ - {'headline': u'Article 5', 'id': self.a5.id}, - {'headline': u'Article 6', 'id': self.a6.id}, - {'headline': u'Article 4', 'id': self.a4.id}, - {'headline': u'Article 2', 'id': self.a2.id}, - {'headline': u'Article 3', 'id': self.a3.id}, - {'headline': u'Article 7', 'id': self.a7.id}, - {'headline': u'Article 1', 'id': self.a1.id}, - ], - transform=identity) - # The values() method works with "extra" fields specified in extra(select). - self.assertQuerysetEqual( - Article.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_one'), - [ - {'id': self.a5.id, 'id_plus_one': self.a5.id + 1}, - {'id': self.a6.id, 'id_plus_one': self.a6.id + 1}, - {'id': self.a4.id, 'id_plus_one': self.a4.id + 1}, - {'id': self.a2.id, 'id_plus_one': self.a2.id + 1}, - {'id': self.a3.id, 'id_plus_one': self.a3.id + 1}, - {'id': self.a7.id, 'id_plus_one': self.a7.id + 1}, - {'id': self.a1.id, 'id_plus_one': self.a1.id + 1}, - ], - transform=identity) - data = { - 'id_plus_one': 'id+1', - 'id_plus_two': 'id+2', - 'id_plus_three': 'id+3', - 'id_plus_four': 'id+4', - 'id_plus_five': 'id+5', - 'id_plus_six': 'id+6', - 'id_plus_seven': 'id+7', - 'id_plus_eight': 'id+8', - } - self.assertQuerysetEqual( - Article.objects.filter(id=self.a1.id).extra(select=data).values(*data.keys()), - [{ - 'id_plus_one': self.a1.id + 1, - 'id_plus_two': self.a1.id + 2, - 'id_plus_three': self.a1.id + 3, - 'id_plus_four': self.a1.id + 4, - 'id_plus_five': self.a1.id + 5, - 'id_plus_six': self.a1.id + 6, - 'id_plus_seven': self.a1.id + 7, - 'id_plus_eight': self.a1.id + 8, - }], transform=identity) - # However, an exception FieldDoesNotExist will be thrown if you specify - # a non-existent field name in values() (a field that is neither in the - # model nor in extra(select)). - self.assertRaises(FieldError, - Article.objects.extra(select={'id_plus_one': 'id + 1'}).values, - 'id', 'id_plus_two') - # If you don't specify field names to values(), all are returned. - self.assertQuerysetEqual(Article.objects.filter(id=self.a5.id).values(), - [{ - 'id': self.a5.id, - 'headline': 'Article 5', - 'pub_date': datetime(2005, 8, 1, 9, 0) - }], transform=identity) - - def test_values_list(self): - # values_list() is similar to values(), except that the results are - # returned as a list of tuples, rather than a list of dictionaries. - # Within each tuple, the order of the elemnts is the same as the order - # of fields in the values_list() call. - identity = lambda x:x - self.assertQuerysetEqual(Article.objects.values_list('headline'), - [ - (u'Article 5',), - (u'Article 6',), - (u'Article 4',), - (u'Article 2',), - (u'Article 3',), - (u'Article 7',), - (u'Article 1',), - ], transform=identity) - self.assertQuerysetEqual(Article.objects.values_list('id').order_by('id'), - [(self.a1.id,), (self.a2.id,), (self.a3.id,), (self.a4.id,), (self.a5.id,), (self.a6.id,), (self.a7.id,)], - transform=identity) - self.assertQuerysetEqual( - Article.objects.values_list('id', flat=True).order_by('id'), - [self.a1.id, self.a2.id, self.a3.id, self.a4.id, self.a5.id, self.a6.id, self.a7.id], - transform=identity) - self.assertQuerysetEqual( - Article.objects.extra(select={'id_plus_one': 'id+1'}) - .order_by('id').values_list('id'), - [(self.a1.id,), (self.a2.id,), (self.a3.id,), (self.a4.id,), (self.a5.id,), (self.a6.id,), (self.a7.id,)], - transform=identity) - self.assertQuerysetEqual( - Article.objects.extra(select={'id_plus_one': 'id+1'}) - .order_by('id').values_list('id_plus_one', 'id'), - [ - (self.a1.id+1, self.a1.id), - (self.a2.id+1, self.a2.id), - (self.a3.id+1, self.a3.id), - (self.a4.id+1, self.a4.id), - (self.a5.id+1, self.a5.id), - (self.a6.id+1, self.a6.id), - (self.a7.id+1, self.a7.id) - ], - transform=identity) - self.assertQuerysetEqual( - Article.objects.extra(select={'id_plus_one': 'id+1'}) - .order_by('id').values_list('id', 'id_plus_one'), - [ - (self.a1.id, self.a1.id+1), - (self.a2.id, self.a2.id+1), - (self.a3.id, self.a3.id+1), - (self.a4.id, self.a4.id+1), - (self.a5.id, self.a5.id+1), - (self.a6.id, self.a6.id+1), - (self.a7.id, self.a7.id+1) - ], - transform=identity) - self.assertRaises(TypeError, Article.objects.values_list, 'id', 'headline', flat=True) - - def test_get_next_previous_by(self): - # Every DateField and DateTimeField creates get_next_by_FOO() and - # get_previous_by_FOO() methods. In the case of identical date values, - # these methods will use the ID as a fallback check. This guarantees - # that no records are skipped or duplicated. - self.assertEqual(repr(self.a1.get_next_by_pub_date()), - '<Article: Article 2>') - self.assertEqual(repr(self.a2.get_next_by_pub_date()), - '<Article: Article 3>') - self.assertEqual(repr(self.a2.get_next_by_pub_date(headline__endswith='6')), - '<Article: Article 6>') - self.assertEqual(repr(self.a3.get_next_by_pub_date()), - '<Article: Article 7>') - self.assertEqual(repr(self.a4.get_next_by_pub_date()), - '<Article: Article 6>') - self.assertRaises(Article.DoesNotExist, self.a5.get_next_by_pub_date) - self.assertEqual(repr(self.a6.get_next_by_pub_date()), - '<Article: Article 5>') - self.assertEqual(repr(self.a7.get_next_by_pub_date()), - '<Article: Article 4>') - - self.assertEqual(repr(self.a7.get_previous_by_pub_date()), - '<Article: Article 3>') - self.assertEqual(repr(self.a6.get_previous_by_pub_date()), - '<Article: Article 4>') - self.assertEqual(repr(self.a5.get_previous_by_pub_date()), - '<Article: Article 6>') - self.assertEqual(repr(self.a4.get_previous_by_pub_date()), - '<Article: Article 7>') - self.assertEqual(repr(self.a3.get_previous_by_pub_date()), - '<Article: Article 2>') - self.assertEqual(repr(self.a2.get_previous_by_pub_date()), - '<Article: Article 1>') - - def test_escaping(self): - # Underscores, percent signs and backslashes have special meaning in the - # underlying SQL code, but Django handles the quoting of them automatically. - a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20)) - a8.save() - self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article'), - [ - '<Article: Article_ with underscore>', - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article_'), - ['<Article: Article_ with underscore>']) - a9 = Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21)) - a9.save() - self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article'), - [ - '<Article: Article% with percent sign>', - '<Article: Article_ with underscore>', - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article%'), - ['<Article: Article% with percent sign>']) - a10 = Article(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22)) - a10.save() - self.assertQuerysetEqual(Article.objects.filter(headline__contains='\\'), - ['<Article: Article with \ backslash>']) - - def test_exclude(self): - a8 = Article.objects.create(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20)) - a9 = Article.objects.create(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21)) - a10 = Article.objects.create(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22)) - - # exclude() is the opposite of filter() when doing lookups: - self.assertQuerysetEqual( - Article.objects.filter(headline__contains='Article').exclude(headline__contains='with'), - [ - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - self.assertQuerysetEqual(Article.objects.exclude(headline__startswith="Article_"), - [ - '<Article: Article with \\ backslash>', - '<Article: Article% with percent sign>', - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - self.assertQuerysetEqual(Article.objects.exclude(headline="Article 7"), - [ - '<Article: Article with \\ backslash>', - '<Article: Article% with percent sign>', - '<Article: Article_ with underscore>', - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 1>', - ]) - - def test_none(self): - # none() returns an EmptyQuerySet that behaves like any other QuerySet object - self.assertQuerysetEqual(Article.objects.none(), []) - self.assertQuerysetEqual( - Article.objects.none().filter(headline__startswith='Article'), []) - self.assertQuerysetEqual( - Article.objects.filter(headline__startswith='Article').none(), []) - self.assertEqual(Article.objects.none().count(), 0) - self.assertEqual( - Article.objects.none().update(headline="This should not take effect"), 0) - self.assertQuerysetEqual( - [article for article in Article.objects.none().iterator()], - []) - - def test_in(self): - # using __in with an empty list should return an empty query set - self.assertQuerysetEqual(Article.objects.filter(id__in=[]), []) - self.assertQuerysetEqual(Article.objects.exclude(id__in=[]), - [ - '<Article: Article 5>', - '<Article: Article 6>', - '<Article: Article 4>', - '<Article: Article 2>', - '<Article: Article 3>', - '<Article: Article 7>', - '<Article: Article 1>', - ]) - - def test_error_messages(self): - # Programming errors are pointed out with nice error messages - try: - Article.objects.filter(pub_date_year='2005').count() - self.fail('FieldError not raised') - except FieldError, ex: - self.assertEqual(str(ex), "Cannot resolve keyword 'pub_date_year' " - "into field. Choices are: headline, id, pub_date") - try: - Article.objects.filter(headline__starts='Article') - self.fail('FieldError not raised') - except FieldError, ex: - self.assertEqual(str(ex), "Join on field 'headline' not permitted. " - "Did you misspell 'starts' for the lookup type?") - - def test_regex(self): - # Create some articles with a bit more interesting headlines for testing field lookups: - for a in Article.objects.all(): - a.delete() - now = datetime.now() - a1 = Article(pub_date=now, headline='f') - a1.save() - a2 = Article(pub_date=now, headline='fo') - a2.save() - a3 = Article(pub_date=now, headline='foo') - a3.save() - a4 = Article(pub_date=now, headline='fooo') - a4.save() - a5 = Article(pub_date=now, headline='hey-Foo') - a5.save() - a6 = Article(pub_date=now, headline='bar') - a6.save() - a7 = Article(pub_date=now, headline='AbBa') - a7.save() - a8 = Article(pub_date=now, headline='baz') - a8.save() - a9 = Article(pub_date=now, headline='baxZ') - a9.save() - # zero-or-more - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fo*'), - ['<Article: f>', '<Article: fo>', '<Article: foo>', '<Article: fooo>']) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'fo*'), - [ - '<Article: f>', - '<Article: fo>', - '<Article: foo>', - '<Article: fooo>', - '<Article: hey-Foo>', - ]) - # one-or-more - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fo+'), - ['<Article: fo>', '<Article: foo>', '<Article: fooo>']) - # wildcard - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fooo?'), - ['<Article: foo>', '<Article: fooo>']) - # leading anchor - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'^b'), - ['<Article: bar>', '<Article: baxZ>', '<Article: baz>']) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'^a'), - ['<Article: AbBa>']) - # trailing anchor - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'z$'), - ['<Article: baz>']) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'z$'), - ['<Article: baxZ>', '<Article: baz>']) - # character sets - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'ba[rz]'), - ['<Article: bar>', '<Article: baz>']) - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'ba.[RxZ]'), - ['<Article: baxZ>']) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'ba[RxZ]'), - ['<Article: bar>', '<Article: baxZ>', '<Article: baz>']) - - # and more articles: - a10 = Article(pub_date=now, headline='foobar') - a10.save() - a11 = Article(pub_date=now, headline='foobaz') - a11.save() - a12 = Article(pub_date=now, headline='ooF') - a12.save() - a13 = Article(pub_date=now, headline='foobarbaz') - a13.save() - a14 = Article(pub_date=now, headline='zoocarfaz') - a14.save() - a15 = Article(pub_date=now, headline='barfoobaz') - a15.save() - a16 = Article(pub_date=now, headline='bazbaRFOO') - a16.save() - - # alternation - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'oo(f|b)'), - [ - '<Article: barfoobaz>', - '<Article: foobar>', - '<Article: foobarbaz>', - '<Article: foobaz>', - ]) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'oo(f|b)'), - [ - '<Article: barfoobaz>', - '<Article: foobar>', - '<Article: foobarbaz>', - '<Article: foobaz>', - '<Article: ooF>', - ]) - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'^foo(f|b)'), - ['<Article: foobar>', '<Article: foobarbaz>', '<Article: foobaz>']) - - # greedy matching - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'b.*az'), - [ - '<Article: barfoobaz>', - '<Article: baz>', - '<Article: bazbaRFOO>', - '<Article: foobarbaz>', - '<Article: foobaz>', - ]) - self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'b.*ar'), - [ - '<Article: bar>', - '<Article: barfoobaz>', - '<Article: bazbaRFOO>', - '<Article: foobar>', - '<Article: foobarbaz>', - ]) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql': - def test_regex_backreferencing(self): - # grouping and backreferences - now = datetime.now() - a10 = Article(pub_date=now, headline='foobar') - a10.save() - a11 = Article(pub_date=now, headline='foobaz') - a11.save() - a12 = Article(pub_date=now, headline='ooF') - a12.save() - a13 = Article(pub_date=now, headline='foobarbaz') - a13.save() - a14 = Article(pub_date=now, headline='zoocarfaz') - a14.save() - a15 = Article(pub_date=now, headline='barfoobaz') - a15.save() - a16 = Article(pub_date=now, headline='bazbaRFOO') - a16.save() - self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'b(.).*b\1'), - ['<Article: barfoobaz>', '<Article: bazbaRFOO>', '<Article: foobarbaz>']) diff --git a/parts/django/tests/modeltests/m2m_and_m2o/__init__.py b/parts/django/tests/modeltests/m2m_and_m2o/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/m2m_and_m2o/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/m2m_and_m2o/models.py b/parts/django/tests/modeltests/m2m_and_m2o/models.py deleted file mode 100644 index 0fea1a2..0000000 --- a/parts/django/tests/modeltests/m2m_and_m2o/models.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -29. Many-to-many and many-to-one relationships to the same table - -Make sure to set ``related_name`` if you use relationships to the same table. -""" - -from django.db import models - -class User(models.Model): - username = models.CharField(max_length=20) - -class Issue(models.Model): - num = models.IntegerField() - cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc') - client = models.ForeignKey(User, related_name='test_issue_client') - - def __unicode__(self): - return unicode(self.num) - - class Meta: - ordering = ('num',) diff --git a/parts/django/tests/modeltests/m2m_and_m2o/tests.py b/parts/django/tests/modeltests/m2m_and_m2o/tests.py deleted file mode 100644 index dedf9cd..0000000 --- a/parts/django/tests/modeltests/m2m_and_m2o/tests.py +++ /dev/null @@ -1,75 +0,0 @@ -from django.db.models import Q -from django.test import TestCase - -from models import Issue, User - - -class RelatedObjectTests(TestCase): - def test_m2m_and_m2o(self): - r = User.objects.create(username="russell") - g = User.objects.create(username="gustav") - - i1 = Issue(num=1) - i1.client = r - i1.save() - - i2 = Issue(num=2) - i2.client = r - i2.save() - i2.cc.add(r) - - i3 = Issue(num=3) - i3.client = g - i3.save() - i3.cc.add(r) - - self.assertQuerysetEqual( - Issue.objects.filter(client=r.id), [ - 1, - 2, - ], - lambda i: i.num - ) - self.assertQuerysetEqual( - Issue.objects.filter(client=g.id), [ - 3, - ], - lambda i: i.num - ) - self.assertQuerysetEqual( - Issue.objects.filter(cc__id__exact=g.id), [] - ) - self.assertQuerysetEqual( - Issue.objects.filter(cc__id__exact=r.id), [ - 2, - 3, - ], - lambda i: i.num - ) - - # These queries combine results from the m2m and the m2o relationships. - # They're three ways of saying the same thing. - self.assertQuerysetEqual( - Issue.objects.filter(Q(cc__id__exact = r.id) | Q(client=r.id)), [ - 1, - 2, - 3, - ], - lambda i: i.num - ) - self.assertQuerysetEqual( - Issue.objects.filter(cc__id__exact=r.id) | Issue.objects.filter(client=r.id), [ - 1, - 2, - 3, - ], - lambda i: i.num - ) - self.assertQuerysetEqual( - Issue.objects.filter(Q(client=r.id) | Q(cc__id__exact=r.id)), [ - 1, - 2, - 3, - ], - lambda i: i.num - ) diff --git a/parts/django/tests/modeltests/m2m_intermediary/__init__.py b/parts/django/tests/modeltests/m2m_intermediary/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/m2m_intermediary/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/m2m_intermediary/models.py b/parts/django/tests/modeltests/m2m_intermediary/models.py deleted file mode 100644 index 8042a52..0000000 --- a/parts/django/tests/modeltests/m2m_intermediary/models.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -9. Many-to-many relationships via an intermediary table - -For many-to-many relationships that need extra fields on the intermediary -table, use an intermediary model. - -In this example, an ``Article`` can have multiple ``Reporter`` objects, and -each ``Article``-``Reporter`` combination (a ``Writer``) has a ``position`` -field, which specifies the ``Reporter``'s position for the given article -(e.g. "Staff writer"). -""" - -from django.db import models - -class Reporter(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - - def __unicode__(self): - return self.headline - -class Writer(models.Model): - reporter = models.ForeignKey(Reporter) - article = models.ForeignKey(Article) - position = models.CharField(max_length=100) - - def __unicode__(self): - return u'%s (%s)' % (self.reporter, self.position) - diff --git a/parts/django/tests/modeltests/m2m_intermediary/tests.py b/parts/django/tests/modeltests/m2m_intermediary/tests.py deleted file mode 100644 index 5f35741..0000000 --- a/parts/django/tests/modeltests/m2m_intermediary/tests.py +++ /dev/null @@ -1,38 +0,0 @@ -from datetime import datetime - -from django.test import TestCase - -from models import Reporter, Article, Writer - - -class M2MIntermediaryTests(TestCase): - def test_intermeiary(self): - r1 = Reporter.objects.create(first_name="John", last_name="Smith") - r2 = Reporter.objects.create(first_name="Jane", last_name="Doe") - - a = Article.objects.create( - headline="This is a test", pub_date=datetime(2005, 7, 27) - ) - - w1 = Writer.objects.create(reporter=r1, article=a, position="Main writer") - w2 = Writer.objects.create(reporter=r2, article=a, position="Contributor") - - self.assertQuerysetEqual( - a.writer_set.select_related().order_by("-position"), [ - ("John Smith", "Main writer"), - ("Jane Doe", "Contributor"), - ], - lambda w: (unicode(w.reporter), w.position) - ) - self.assertEqual(w1.reporter, r1) - self.assertEqual(w2.reporter, r2) - - self.assertEqual(w1.article, a) - self.assertEqual(w2.article, a) - - self.assertQuerysetEqual( - r1.writer_set.all(), [ - ("John Smith", "Main writer") - ], - lambda w: (unicode(w.reporter), w.position) - ) diff --git a/parts/django/tests/modeltests/m2m_multiple/__init__.py b/parts/django/tests/modeltests/m2m_multiple/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/m2m_multiple/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/m2m_multiple/models.py b/parts/django/tests/modeltests/m2m_multiple/models.py deleted file mode 100644 index e53f840..0000000 --- a/parts/django/tests/modeltests/m2m_multiple/models.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -20. Multiple many-to-many relationships between the same two tables - -In this example, an ``Article`` can have many "primary" ``Category`` objects -and many "secondary" ``Category`` objects. - -Set ``related_name`` to designate what the reverse relationship is called. -""" - -from django.db import models - -class Category(models.Model): - name = models.CharField(max_length=20) - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class Article(models.Model): - headline = models.CharField(max_length=50) - pub_date = models.DateTimeField() - primary_categories = models.ManyToManyField(Category, related_name='primary_article_set') - secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set') - class Meta: - ordering = ('pub_date',) - - def __unicode__(self): - return self.headline - diff --git a/parts/django/tests/modeltests/m2m_multiple/tests.py b/parts/django/tests/modeltests/m2m_multiple/tests.py deleted file mode 100644 index 1f4503a..0000000 --- a/parts/django/tests/modeltests/m2m_multiple/tests.py +++ /dev/null @@ -1,84 +0,0 @@ -from datetime import datetime - -from django.test import TestCase - -from models import Article, Category - - -class M2MMultipleTests(TestCase): - def test_multiple(self): - c1, c2, c3, c4 = [ - Category.objects.create(name=name) - for name in ["Sports", "News", "Crime", "Life"] - ] - - a1 = Article.objects.create( - headline="Area man steals", pub_date=datetime(2005, 11, 27) - ) - a1.primary_categories.add(c2, c3) - a1.secondary_categories.add(c4) - - a2 = Article.objects.create( - headline="Area man runs", pub_date=datetime(2005, 11, 28) - ) - a2.primary_categories.add(c1, c2) - a2.secondary_categories.add(c4) - - self.assertQuerysetEqual( - a1.primary_categories.all(), [ - "Crime", - "News", - ], - lambda c: c.name - ) - self.assertQuerysetEqual( - a2.primary_categories.all(), [ - "News", - "Sports", - ], - lambda c: c.name - ) - self.assertQuerysetEqual( - a1.secondary_categories.all(), [ - "Life", - ], - lambda c: c.name - ) - self.assertQuerysetEqual( - c1.primary_article_set.all(), [ - "Area man runs", - ], - lambda a: a.headline - ) - self.assertQuerysetEqual( - c1.secondary_article_set.all(), [] - ) - self.assertQuerysetEqual( - c2.primary_article_set.all(), [ - "Area man steals", - "Area man runs", - ], - lambda a: a.headline - ) - self.assertQuerysetEqual( - c2.secondary_article_set.all(), [] - ) - self.assertQuerysetEqual( - c3.primary_article_set.all(), [ - "Area man steals", - ], - lambda a: a.headline - ) - self.assertQuerysetEqual( - c3.secondary_article_set.all(), [] - ) - self.assertQuerysetEqual( - c4.primary_article_set.all(), [] - ) - self.assertQuerysetEqual( - c4.secondary_article_set.all(), [ - "Area man steals", - "Area man runs", - ], - lambda a: a.headline - ) diff --git a/parts/django/tests/modeltests/m2m_recursive/__init__.py b/parts/django/tests/modeltests/m2m_recursive/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/m2m_recursive/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/m2m_recursive/models.py b/parts/django/tests/modeltests/m2m_recursive/models.py deleted file mode 100644 index 83c943a..0000000 --- a/parts/django/tests/modeltests/m2m_recursive/models.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -28. Many-to-many relationships between the same two tables - -In this example, a ``Person`` can have many friends, who are also ``Person`` -objects. Friendship is a symmetrical relationship - if I am your friend, you -are my friend. Here, ``friends`` is an example of a symmetrical -``ManyToManyField``. - -A ``Person`` can also have many idols - but while I may idolize you, you may -not think the same of me. Here, ``idols`` is an example of a non-symmetrical -``ManyToManyField``. Only recursive ``ManyToManyField`` fields may be -non-symmetrical, and they are symmetrical by default. - -This test validates that the many-to-many table is created using a mangled name -if there is a name clash, and tests that symmetry is preserved where -appropriate. -""" - -from django.db import models - - -class Person(models.Model): - name = models.CharField(max_length=20) - friends = models.ManyToManyField('self') - idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers') - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/m2m_recursive/tests.py b/parts/django/tests/modeltests/m2m_recursive/tests.py deleted file mode 100644 index 4251028..0000000 --- a/parts/django/tests/modeltests/m2m_recursive/tests.py +++ /dev/null @@ -1,253 +0,0 @@ -from operator import attrgetter - -from django.test import TestCase - -from models import Person - - -class RecursiveM2MTests(TestCase): - def test_recursive_m2m(self): - a, b, c, d = [ - Person.objects.create(name=name) - for name in ["Anne", "Bill", "Chuck", "David"] - ] - - # Add some friends in the direction of field definition - # Anne is friends with Bill and Chuck - a.friends.add(b, c) - - # David is friends with Anne and Chuck - add in reverse direction - d.friends.add(a,c) - - # Who is friends with Anne? - self.assertQuerysetEqual( - a.friends.all(), [ - "Bill", - "Chuck", - "David" - ], - attrgetter("name") - ) - # Who is friends with Bill? - self.assertQuerysetEqual( - b.friends.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who is friends with Chuck? - self.assertQuerysetEqual( - c.friends.all(), [ - "Anne", - "David" - ], - attrgetter("name") - ) - # Who is friends with David? - self.assertQuerysetEqual( - d.friends.all(), [ - "Anne", - "Chuck", - ], - attrgetter("name") - ) - # Bill is already friends with Anne - add Anne again, but in the - # reverse direction - b.friends.add(a) - - # Who is friends with Anne? - self.assertQuerysetEqual( - a.friends.all(), [ - "Bill", - "Chuck", - "David", - ], - attrgetter("name") - ) - # Who is friends with Bill? - self.assertQuerysetEqual( - b.friends.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Remove Anne from Bill's friends - b.friends.remove(a) - # Who is friends with Anne? - self.assertQuerysetEqual( - a.friends.all(), [ - "Chuck", - "David", - ], - attrgetter("name") - ) - # Who is friends with Bill? - self.assertQuerysetEqual( - b.friends.all(), [] - ) - - # Clear Anne's group of friends - a.friends.clear() - # Who is friends with Anne? - self.assertQuerysetEqual( - a.friends.all(), [] - ) - # Reverse relationships should also be gone - # Who is friends with Chuck? - self.assertQuerysetEqual( - c.friends.all(), [ - "David", - ], - attrgetter("name") - ) - # Who is friends with David? - self.assertQuerysetEqual( - d.friends.all(), [ - "Chuck", - ], - attrgetter("name") - ) - - # Add some idols in the direction of field definition - # Anne idolizes Bill and Chuck - a.idols.add(b, c) - # Bill idolizes Anne right back - b.idols.add(a) - # David is idolized by Anne and Chuck - add in reverse direction - d.stalkers.add(a, c) - - # Who are Anne's idols? - self.assertQuerysetEqual( - a.idols.all(), [ - "Bill", - "Chuck", - "David", - ], - attrgetter("name") - ) - # Who is stalking Anne? - self.assertQuerysetEqual( - a.stalkers.all(), [ - "Bill", - ], - attrgetter("name") - ) - # Who are Bill's idols? - self.assertQuerysetEqual( - b.idols.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who is stalking Bill? - self.assertQuerysetEqual( - b.stalkers.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who are Chuck's idols? - self.assertQuerysetEqual( - c.idols.all(), [ - "David", - ], - attrgetter("name"), - ) - # Who is stalking Chuck? - self.assertQuerysetEqual( - c.stalkers.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who are David's idols? - self.assertQuerysetEqual( - d.idols.all(), [] - ) - # Who is stalking David - self.assertQuerysetEqual( - d.stalkers.all(), [ - "Anne", - "Chuck", - ], - attrgetter("name") - ) - # Bill is already being stalked by Anne - add Anne again, but in the - # reverse direction - b.stalkers.add(a) - # Who are Anne's idols? - self.assertQuerysetEqual( - a.idols.all(), [ - "Bill", - "Chuck", - "David", - ], - attrgetter("name") - ) - # Who is stalking Anne? - self.assertQuerysetEqual( - a.stalkers.all(), [ - "Bill", - ], - attrgetter("name") - ) - # Who are Bill's idols - self.assertQuerysetEqual( - b.idols.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who is stalking Bill? - self.assertQuerysetEqual( - b.stalkers.all(), [ - "Anne", - ], - attrgetter("name"), - ) - # Remove Anne from Bill's list of stalkers - b.stalkers.remove(a) - # Who are Anne's idols? - self.assertQuerysetEqual( - a.idols.all(), [ - "Chuck", - "David", - ], - attrgetter("name") - ) - # Who is stalking Anne? - self.assertQuerysetEqual( - a.stalkers.all(), [ - "Bill", - ], - attrgetter("name") - ) - # Who are Bill's idols? - self.assertQuerysetEqual( - b.idols.all(), [ - "Anne", - ], - attrgetter("name") - ) - # Who is stalking Bill? - self.assertQuerysetEqual( - b.stalkers.all(), [] - ) - # Clear Anne's group of idols - a.idols.clear() - # Who are Anne's idols - self.assertQuerysetEqual( - a.idols.all(), [] - ) - # Reverse relationships should also be gone - # Who is stalking Chuck? - self.assertQuerysetEqual( - c.stalkers.all(), [] - ) - # Who is friends with David? - self.assertQuerysetEqual( - d.stalkers.all(), [ - "Chuck", - ], - attrgetter("name") - ) diff --git a/parts/django/tests/modeltests/m2m_signals/__init__.py b/parts/django/tests/modeltests/m2m_signals/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/modeltests/m2m_signals/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/modeltests/m2m_signals/models.py b/parts/django/tests/modeltests/m2m_signals/models.py deleted file mode 100644 index 526c4a7..0000000 --- a/parts/django/tests/modeltests/m2m_signals/models.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.db import models - - -class Part(models.Model): - name = models.CharField(max_length=20) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class Car(models.Model): - name = models.CharField(max_length=20) - default_parts = models.ManyToManyField(Part) - optional_parts = models.ManyToManyField(Part, related_name='cars_optional') - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class SportsCar(Car): - price = models.IntegerField() - -class Person(models.Model): - name = models.CharField(max_length=20) - fans = models.ManyToManyField('self', related_name='idols', symmetrical=False) - friends = models.ManyToManyField('self') - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/m2m_signals/tests.py b/parts/django/tests/modeltests/m2m_signals/tests.py deleted file mode 100644 index 9e9158f..0000000 --- a/parts/django/tests/modeltests/m2m_signals/tests.py +++ /dev/null @@ -1,427 +0,0 @@ -""" -Testing signals emitted on changing m2m relations. -""" - -from django.db import models -from django.test import TestCase - -from models import Part, Car, SportsCar, Person - - -class ManyToManySignalsTest(TestCase): - def m2m_changed_signal_receiver(self, signal, sender, **kwargs): - message = { - 'instance': kwargs['instance'], - 'action': kwargs['action'], - 'reverse': kwargs['reverse'], - 'model': kwargs['model'], - } - if kwargs['pk_set']: - message['objects'] = list( - kwargs['model'].objects.filter(pk__in=kwargs['pk_set']) - ) - self.m2m_changed_messages.append(message) - - def setUp(self): - self.m2m_changed_messages = [] - - self.vw = Car.objects.create(name='VW') - self.bmw = Car.objects.create(name='BMW') - self.toyota = Car.objects.create(name='Toyota') - self.wheelset = Part.objects.create(name='Wheelset') - self.doors = Part.objects.create(name='Doors') - self.engine = Part.objects.create(name='Engine') - self.airbag = Part.objects.create(name='Airbag') - self.sunroof = Part.objects.create(name='Sunroof') - - self.alice = Person.objects.create(name='Alice') - self.bob = Person.objects.create(name='Bob') - self.chuck = Person.objects.create(name='Chuck') - self.daisy = Person.objects.create(name='Daisy') - - def tearDown(self): - # disconnect all signal handlers - models.signals.m2m_changed.disconnect( - self.m2m_changed_signal_receiver, Car.default_parts.through - ) - models.signals.m2m_changed.disconnect( - self.m2m_changed_signal_receiver, Car.optional_parts.through - ) - models.signals.m2m_changed.disconnect( - self.m2m_changed_signal_receiver, Person.fans.through - ) - models.signals.m2m_changed.disconnect( - self.m2m_changed_signal_receiver, Person.friends.through - ) - - def test_m2m_relations_add_remove_clear(self): - expected_messages = [] - - # Install a listener on one of the two m2m relations. - models.signals.m2m_changed.connect( - self.m2m_changed_signal_receiver, Car.optional_parts.through - ) - - # Test the add, remove and clear methods on both sides of the - # many-to-many relation - - # adding a default part to our car - no signal listener installed - self.vw.default_parts.add(self.sunroof) - - # Now install a listener - models.signals.m2m_changed.connect( - self.m2m_changed_signal_receiver, Car.default_parts.through - ) - - self.vw.default_parts.add(self.wheelset, self.doors, self.engine) - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors, self.engine, self.wheelset], - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors, self.engine, self.wheelset], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # give the BMW and Toyata some doors as well - self.doors.car_set.add(self.bmw, self.toyota) - expected_messages.append({ - 'instance': self.doors, - 'action': 'pre_add', - 'reverse': True, - 'model': Car, - 'objects': [self.bmw, self.toyota], - }) - expected_messages.append({ - 'instance': self.doors, - 'action': 'post_add', - 'reverse': True, - 'model': Car, - 'objects': [self.bmw, self.toyota], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # remove the engine from the self.vw and the airbag (which is not set - # but is returned) - self.vw.default_parts.remove(self.engine, self.airbag) - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_remove', - 'reverse': False, - 'model': Part, - 'objects': [self.airbag, self.engine], - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_remove', - 'reverse': False, - 'model': Part, - 'objects': [self.airbag, self.engine], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # give the self.vw some optional parts (second relation to same model) - self.vw.optional_parts.add(self.airbag, self.sunroof) - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_add', - 'reverse': False, - 'model': Part, - 'objects': [self.airbag, self.sunroof], - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_add', - 'reverse': False, - 'model': Part, - 'objects': [self.airbag, self.sunroof], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # add airbag to all the cars (even though the self.vw already has one) - self.airbag.cars_optional.add(self.vw, self.bmw, self.toyota) - expected_messages.append({ - 'instance': self.airbag, - 'action': 'pre_add', - 'reverse': True, - 'model': Car, - 'objects': [self.bmw, self.toyota], - }) - expected_messages.append({ - 'instance': self.airbag, - 'action': 'post_add', - 'reverse': True, - 'model': Car, - 'objects': [self.bmw, self.toyota], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # remove airbag from the self.vw (reverse relation with custom - # related_name) - self.airbag.cars_optional.remove(self.vw) - expected_messages.append({ - 'instance': self.airbag, - 'action': 'pre_remove', - 'reverse': True, - 'model': Car, - 'objects': [self.vw], - }) - expected_messages.append({ - 'instance': self.airbag, - 'action': 'post_remove', - 'reverse': True, - 'model': Car, - 'objects': [self.vw], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # clear all parts of the self.vw - self.vw.default_parts.clear() - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_clear', - 'reverse': False, - 'model': Part, - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_clear', - 'reverse': False, - 'model': Part, - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # take all the doors off of cars - self.doors.car_set.clear() - expected_messages.append({ - 'instance': self.doors, - 'action': 'pre_clear', - 'reverse': True, - 'model': Car, - }) - expected_messages.append({ - 'instance': self.doors, - 'action': 'post_clear', - 'reverse': True, - 'model': Car, - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # take all the airbags off of cars (clear reverse relation with custom - # related_name) - self.airbag.cars_optional.clear() - expected_messages.append({ - 'instance': self.airbag, - 'action': 'pre_clear', - 'reverse': True, - 'model': Car, - }) - expected_messages.append({ - 'instance': self.airbag, - 'action': 'post_clear', - 'reverse': True, - 'model': Car, - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # alternative ways of setting relation: - self.vw.default_parts.create(name='Windows') - p6 = Part.objects.get(name='Windows') - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_add', - 'reverse': False, - 'model': Part, - 'objects': [p6], - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_add', - 'reverse': False, - 'model': Part, - 'objects': [p6], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # direct assignment clears the set first, then adds - self.vw.default_parts = [self.wheelset,self.doors,self.engine] - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_clear', - 'reverse': False, - 'model': Part, - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_clear', - 'reverse': False, - 'model': Part, - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'pre_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors, self.engine, self.wheelset], - }) - expected_messages.append({ - 'instance': self.vw, - 'action': 'post_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors, self.engine, self.wheelset], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - # Check that signals still work when model inheritance is involved - c4 = SportsCar.objects.create(name='Bugatti', price='1000000') - c4b = Car.objects.get(name='Bugatti') - c4.default_parts = [self.doors] - expected_messages.append({ - 'instance': c4, - 'action': 'pre_clear', - 'reverse': False, - 'model': Part, - }) - expected_messages.append({ - 'instance': c4, - 'action': 'post_clear', - 'reverse': False, - 'model': Part, - }) - expected_messages.append({ - 'instance': c4, - 'action': 'pre_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors], - }) - expected_messages.append({ - 'instance': c4, - 'action': 'post_add', - 'reverse': False, - 'model': Part, - 'objects': [self.doors], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - self.engine.car_set.add(c4) - expected_messages.append({ - 'instance': self.engine, - 'action': 'pre_add', - 'reverse': True, - 'model': Car, - 'objects': [c4b], - }) - expected_messages.append({ - 'instance': self.engine, - 'action': 'post_add', - 'reverse': True, - 'model': Car, - 'objects': [c4b], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - def test_m2m_relations_with_self(self): - expected_messages = [] - - models.signals.m2m_changed.connect( - self.m2m_changed_signal_receiver, Person.fans.through - ) - models.signals.m2m_changed.connect( - self.m2m_changed_signal_receiver, Person.friends.through - ) - - self.alice.friends = [self.bob, self.chuck] - expected_messages.append({ - 'instance': self.alice, - 'action': 'pre_clear', - 'reverse': False, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'post_clear', - 'reverse': False, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'pre_add', - 'reverse': False, - 'model': Person, - 'objects': [self.bob, self.chuck], - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'post_add', - 'reverse': False, - 'model': Person, - 'objects': [self.bob, self.chuck], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - self.alice.fans = [self.daisy] - expected_messages.append({ - 'instance': self.alice, - 'action': 'pre_clear', - 'reverse': False, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'post_clear', - 'reverse': False, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'pre_add', - 'reverse': False, - 'model': Person, - 'objects': [self.daisy], - }) - expected_messages.append({ - 'instance': self.alice, - 'action': 'post_add', - 'reverse': False, - 'model': Person, - 'objects': [self.daisy], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) - - self.chuck.idols = [self.alice,self.bob] - expected_messages.append({ - 'instance': self.chuck, - 'action': 'pre_clear', - 'reverse': True, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.chuck, - 'action': 'post_clear', - 'reverse': True, - 'model': Person, - }) - expected_messages.append({ - 'instance': self.chuck, - 'action': 'pre_add', - 'reverse': True, - 'model': Person, - 'objects': [self.alice, self.bob], - }) - expected_messages.append({ - 'instance': self.chuck, - 'action': 'post_add', - 'reverse': True, - 'model': Person, - 'objects': [self.alice, self.bob], - }) - self.assertEqual(self.m2m_changed_messages, expected_messages) diff --git a/parts/django/tests/modeltests/m2m_through/__init__.py b/parts/django/tests/modeltests/m2m_through/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/modeltests/m2m_through/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/modeltests/m2m_through/models.py b/parts/django/tests/modeltests/m2m_through/models.py deleted file mode 100644 index d41fe8d..0000000 --- a/parts/django/tests/modeltests/m2m_through/models.py +++ /dev/null @@ -1,65 +0,0 @@ -from django.db import models -from datetime import datetime - -# M2M described on one of the models -class Person(models.Model): - name = models.CharField(max_length=128) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class Group(models.Model): - name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, through='Membership') - custom_members = models.ManyToManyField(Person, through='CustomMembership', related_name="custom") - nodefaultsnonulls = models.ManyToManyField(Person, through='TestNoDefaultsOrNulls', related_name="testnodefaultsnonulls") - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) - date_joined = models.DateTimeField(default=datetime.now) - invite_reason = models.CharField(max_length=64, null=True) - - class Meta: - ordering = ('date_joined', 'invite_reason', 'group') - - def __unicode__(self): - return "%s is a member of %s" % (self.person.name, self.group.name) - -class CustomMembership(models.Model): - person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name") - group = models.ForeignKey(Group) - weird_fk = models.ForeignKey(Membership, null=True) - date_joined = models.DateTimeField(default=datetime.now) - - def __unicode__(self): - return "%s is a member of %s" % (self.person.name, self.group.name) - - class Meta: - db_table = "test_table" - -class TestNoDefaultsOrNulls(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) - nodefaultnonull = models.CharField(max_length=5) - -class PersonSelfRefM2M(models.Model): - name = models.CharField(max_length=5) - friends = models.ManyToManyField('self', through="Friendship", symmetrical=False) - - def __unicode__(self): - return self.name - -class Friendship(models.Model): - first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set") - second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set") - date_friended = models.DateTimeField() diff --git a/parts/django/tests/modeltests/m2m_through/tests.py b/parts/django/tests/modeltests/m2m_through/tests.py deleted file mode 100644 index 807e952..0000000 --- a/parts/django/tests/modeltests/m2m_through/tests.py +++ /dev/null @@ -1,343 +0,0 @@ -from datetime import datetime -from operator import attrgetter - -from django.test import TestCase - -from models import Person, Group, Membership, CustomMembership, \ - TestNoDefaultsOrNulls, PersonSelfRefM2M, Friendship - - -class M2mThroughTests(TestCase): - def setUp(self): - self.bob = Person.objects.create(name='Bob') - self.jim = Person.objects.create(name='Jim') - self.jane = Person.objects.create(name='Jane') - self.rock = Group.objects.create(name='Rock') - self.roll = Group.objects.create(name='Roll') - - def test_m2m_through(self): - # We start out by making sure that the Group 'rock' has no members. - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) - # To make Jim a member of Group Rock, simply create a Membership object. - m1 = Membership.objects.create(person=self.jim, group=self.rock) - # We can do the same for Jane and Rock. - m2 = Membership.objects.create(person=self.jane, group=self.rock) - # Let's check to make sure that it worked. Jane and Jim should be members of Rock. - self.assertQuerysetEqual( - self.rock.members.all(), [ - 'Jane', - 'Jim' - ], - attrgetter("name") - ) - # Now we can add a bunch more Membership objects to test with. - m3 = Membership.objects.create(person=self.bob, group=self.roll) - m4 = Membership.objects.create(person=self.jim, group=self.roll) - m5 = Membership.objects.create(person=self.jane, group=self.roll) - # We can get Jim's Group membership as with any ForeignKey. - self.assertQuerysetEqual( - self.jim.group_set.all(), [ - 'Rock', - 'Roll' - ], - attrgetter("name") - ) - # Querying the intermediary model works like normal. - self.assertEqual( - repr(Membership.objects.get(person=self.jane, group=self.rock)), - '<Membership: Jane is a member of Rock>' - ) - # It's not only get that works. Filter works like normal as well. - self.assertQuerysetEqual( - Membership.objects.filter(person=self.jim), [ - '<Membership: Jim is a member of Rock>', - '<Membership: Jim is a member of Roll>' - ] - ) - self.rock.members.clear() - # Now there will be no members of Rock. - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) - - - - def test_forward_descriptors(self): - # Due to complications with adding via an intermediary model, - # the add method is not provided. - self.assertRaises(AttributeError, lambda: self.rock.members.add(self.bob)) - # Create is also disabled as it suffers from the same problems as add. - self.assertRaises(AttributeError, lambda: self.rock.members.create(name='Anne')) - # Remove has similar complications, and is not provided either. - self.assertRaises(AttributeError, lambda: self.rock.members.remove(self.jim)) - - m1 = Membership.objects.create(person=self.jim, group=self.rock) - m2 = Membership.objects.create(person=self.jane, group=self.rock) - - # Here we back up the list of all members of Rock. - backup = list(self.rock.members.all()) - # ...and we verify that it has worked. - self.assertEqual( - [p.name for p in backup], - ['Jane', 'Jim'] - ) - # The clear function should still work. - self.rock.members.clear() - # Now there will be no members of Rock. - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) - - # Assignment should not work with models specifying a through model for many of - # the same reasons as adding. - self.assertRaises(AttributeError, setattr, self.rock, "members", backup) - # Let's re-save those instances that we've cleared. - m1.save() - m2.save() - # Verifying that those instances were re-saved successfully. - self.assertQuerysetEqual( - self.rock.members.all(),[ - 'Jane', - 'Jim' - ], - attrgetter("name") - ) - - def test_reverse_descriptors(self): - # Due to complications with adding via an intermediary model, - # the add method is not provided. - self.assertRaises(AttributeError, lambda: self.bob.group_set.add(self.rock)) - # Create is also disabled as it suffers from the same problems as add. - self.assertRaises(AttributeError, lambda: self.bob.group_set.create(name="funk")) - # Remove has similar complications, and is not provided either. - self.assertRaises(AttributeError, lambda: self.jim.group_set.remove(self.rock)) - - m1 = Membership.objects.create(person=self.jim, group=self.rock) - m2 = Membership.objects.create(person=self.jim, group=self.roll) - - # Here we back up the list of all of Jim's groups. - backup = list(self.jim.group_set.all()) - self.assertEqual( - [g.name for g in backup], - ['Rock', 'Roll'] - ) - # The clear function should still work. - self.jim.group_set.clear() - # Now Jim will be in no groups. - self.assertQuerysetEqual( - self.jim.group_set.all(), - [] - ) - # Assignment should not work with models specifying a through model for many of - # the same reasons as adding. - self.assertRaises(AttributeError, setattr, self.jim, "group_set", backup) - # Let's re-save those instances that we've cleared. - - m1.save() - m2.save() - # Verifying that those instances were re-saved successfully. - self.assertQuerysetEqual( - self.jim.group_set.all(),[ - 'Rock', - 'Roll' - ], - attrgetter("name") - ) - - def test_custom_tests(self): - # Let's see if we can query through our second relationship. - self.assertQuerysetEqual( - self.rock.custom_members.all(), - [] - ) - # We can query in the opposite direction as well. - self.assertQuerysetEqual( - self.bob.custom.all(), - [] - ) - - cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock) - cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock) - - # If we get the number of people in Rock, it should be both Bob and Jim. - self.assertQuerysetEqual( - self.rock.custom_members.all(),[ - 'Bob', - 'Jim' - ], - attrgetter("name") - ) - # Bob should only be in one custom group. - self.assertQuerysetEqual( - self.bob.custom.all(),[ - 'Rock' - ], - attrgetter("name") - ) - # Let's make sure our new descriptors don't conflict with the FK related_name. - self.assertQuerysetEqual( - self.bob.custom_person_related_name.all(),[ - '<CustomMembership: Bob is a member of Rock>' - ] - ) - - def test_self_referential_tests(self): - # Let's first create a person who has no friends. - tony = PersonSelfRefM2M.objects.create(name="Tony") - self.assertQuerysetEqual( - tony.friends.all(), - [] - ) - - chris = PersonSelfRefM2M.objects.create(name="Chris") - f = Friendship.objects.create(first=tony, second=chris, date_friended=datetime.now()) - - # Tony should now show that Chris is his friend. - self.assertQuerysetEqual( - tony.friends.all(),[ - 'Chris' - ], - attrgetter("name") - ) - # But we haven't established that Chris is Tony's Friend. - self.assertQuerysetEqual( - chris.friends.all(), - [] - ) - f2 = Friendship.objects.create(first=chris, second=tony, date_friended=datetime.now()) - - # Having added Chris as a friend, let's make sure that his friend set reflects - # that addition. - self.assertQuerysetEqual( - chris.friends.all(),[ - 'Tony' - ], - attrgetter("name") - ) - - # Chris gets mad and wants to get rid of all of his friends. - chris.friends.clear() - # Now he should not have any more friends. - self.assertQuerysetEqual( - chris.friends.all(), - [] - ) - # Since this isn't a symmetrical relation, Tony's friend link still exists. - self.assertQuerysetEqual( - tony.friends.all(),[ - 'Chris' - ], - attrgetter("name") - ) - - def test_query_tests(self): - m1 = Membership.objects.create(person=self.jim, group=self.rock) - m2 = Membership.objects.create(person=self.jane, group=self.rock) - m3 = Membership.objects.create(person=self.bob, group=self.roll) - m4 = Membership.objects.create(person=self.jim, group=self.roll) - m5 = Membership.objects.create(person=self.jane, group=self.roll) - - m2.invite_reason = "She was just awesome." - m2.date_joined = datetime(2006, 1, 1) - m2.save() - m3.date_joined = datetime(2004, 1, 1) - m3.save() - m5.date_joined = datetime(2004, 1, 1) - m5.save() - - # We can query for the related model by using its attribute name (members, in - # this case). - self.assertQuerysetEqual( - Group.objects.filter(members__name='Bob'),[ - 'Roll' - ], - attrgetter("name") - ) - - # To query through the intermediary model, we specify its model name. - # In this case, membership. - self.assertQuerysetEqual( - Group.objects.filter(membership__invite_reason="She was just awesome."),[ - 'Rock' - ], - attrgetter("name") - ) - - # If we want to query in the reverse direction by the related model, use its - # model name (group, in this case). - self.assertQuerysetEqual( - Person.objects.filter(group__name="Rock"),[ - 'Jane', - 'Jim' - ], - attrgetter("name") - ) - - cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock) - cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock) - # If the m2m field has specified a related_name, using that will work. - self.assertQuerysetEqual( - Person.objects.filter(custom__name="Rock"),[ - 'Bob', - 'Jim' - ], - attrgetter("name") - ) - - # To query through the intermediary model in the reverse direction, we again - # specify its model name (membership, in this case). - self.assertQuerysetEqual( - Person.objects.filter(membership__invite_reason="She was just awesome."),[ - 'Jane' - ], - attrgetter("name") - ) - - # Let's see all of the groups that Jane joined after 1 Jan 2005: - self.assertQuerysetEqual( - Group.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__person=self.jane),[ - 'Rock' - ], - attrgetter("name") - ) - - # Queries also work in the reverse direction: Now let's see all of the people - # that have joined Rock since 1 Jan 2005: - self.assertQuerysetEqual( - Person.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__group=self.rock),[ - 'Jane', - 'Jim' - ], - attrgetter("name") - ) - - # Conceivably, queries through membership could return correct, but non-unique - # querysets. To demonstrate this, we query for all people who have joined a - # group after 2004: - self.assertQuerysetEqual( - Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)),[ - 'Jane', - 'Jim', - 'Jim' - ], - attrgetter("name") - ) - - # Jim showed up twice, because he joined two groups ('Rock', and 'Roll'): - self.assertEqual( - [(m.person.name, m.group.name) for m in Membership.objects.filter(date_joined__gt=datetime(2004, 1, 1))], - [(u'Jane', u'Rock'), (u'Jim', u'Rock'), (u'Jim', u'Roll')] - ) - # QuerySet's distinct() method can correct this problem. - self.assertQuerysetEqual( - Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)).distinct(),[ - 'Jane', - 'Jim' - ], - attrgetter("name") - ) diff --git a/parts/django/tests/modeltests/m2o_recursive/__init__.py b/parts/django/tests/modeltests/m2o_recursive/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/m2o_recursive/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/m2o_recursive/models.py b/parts/django/tests/modeltests/m2o_recursive/models.py deleted file mode 100644 index ed9945a..0000000 --- a/parts/django/tests/modeltests/m2o_recursive/models.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -11. Relating an object to itself, many-to-one - -To define a many-to-one relationship between a model and itself, use -``ForeignKey('self')``. - -In this example, a ``Category`` is related to itself. That is, each -``Category`` has a parent ``Category``. - -Set ``related_name`` to designate what the reverse relationship is called. -""" - -from django.db import models - -class Category(models.Model): - name = models.CharField(max_length=20) - parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set') - - def __unicode__(self): - return self.name - -class Person(models.Model): - full_name = models.CharField(max_length=20) - mother = models.ForeignKey('self', null=True, related_name='mothers_child_set') - father = models.ForeignKey('self', null=True, related_name='fathers_child_set') - - def __unicode__(self): - return self.full_name diff --git a/parts/django/tests/modeltests/m2o_recursive/tests.py b/parts/django/tests/modeltests/m2o_recursive/tests.py deleted file mode 100644 index 79dde8b..0000000 --- a/parts/django/tests/modeltests/m2o_recursive/tests.py +++ /dev/null @@ -1,38 +0,0 @@ -from django.test import TestCase -from models import Category, Person - -class ManyToOneRecursiveTests(TestCase): - - def setUp(self): - self.r = Category(id=None, name='Root category', parent=None) - self.r.save() - self.c = Category(id=None, name='Child category', parent=self.r) - self.c.save() - - def test_m2o_recursive(self): - self.assertQuerysetEqual(self.r.child_set.all(), - ['<Category: Child category>']) - self.assertEqual(self.r.child_set.get(name__startswith='Child').id, self.c.id) - self.assertEqual(self.r.parent, None) - self.assertQuerysetEqual(self.c.child_set.all(), []) - self.assertEqual(self.c.parent.id, self.r.id) - -class MultipleManyToOneRecursiveTests(TestCase): - - def setUp(self): - self.dad = Person(full_name='John Smith Senior', mother=None, father=None) - self.dad.save() - self.mom = Person(full_name='Jane Smith', mother=None, father=None) - self.mom.save() - self.kid = Person(full_name='John Smith Junior', mother=self.mom, father=self.dad) - self.kid.save() - - def test_m2o_recursive2(self): - self.assertEqual(self.kid.mother.id, self.mom.id) - self.assertEqual(self.kid.father.id, self.dad.id) - self.assertQuerysetEqual(self.dad.fathers_child_set.all(), - ['<Person: John Smith Junior>']) - self.assertQuerysetEqual(self.mom.mothers_child_set.all(), - ['<Person: John Smith Junior>']) - self.assertQuerysetEqual(self.kid.mothers_child_set.all(), []) - self.assertQuerysetEqual(self.kid.fathers_child_set.all(), []) diff --git a/parts/django/tests/modeltests/many_to_many/__init__.py b/parts/django/tests/modeltests/many_to_many/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/many_to_many/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/many_to_many/models.py b/parts/django/tests/modeltests/many_to_many/models.py deleted file mode 100644 index 96636da..0000000 --- a/parts/django/tests/modeltests/many_to_many/models.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -5. Many-to-many relationships - -To define a many-to-many relationship, use ``ManyToManyField()``. - -In this example, an ``Article`` can be published in multiple ``Publication`` -objects, and a ``Publication`` has multiple ``Article`` objects. -""" - -from django.db import models - -class Publication(models.Model): - title = models.CharField(max_length=30) - - def __unicode__(self): - return self.title - - class Meta: - ordering = ('title',) - -class Article(models.Model): - headline = models.CharField(max_length=100) - publications = models.ManyToManyField(Publication) - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('headline',) diff --git a/parts/django/tests/modeltests/many_to_many/tests.py b/parts/django/tests/modeltests/many_to_many/tests.py deleted file mode 100644 index 39fe581..0000000 --- a/parts/django/tests/modeltests/many_to_many/tests.py +++ /dev/null @@ -1,384 +0,0 @@ -from django.test import TestCase -from models import Article, Publication - -class ManyToManyTests(TestCase): - - def setUp(self): - # Create a couple of Publications. - self.p1 = Publication.objects.create(id=None, title='The Python Journal') - self.p2 = Publication.objects.create(id=None, title='Science News') - self.p3 = Publication.objects.create(id=None, title='Science Weekly') - self.p4 = Publication.objects.create(title='Highlights for Children') - - self.a1 = Article.objects.create(id=None, headline='Django lets you build Web apps easily') - self.a1.publications.add(self.p1) - - self.a2 = Article.objects.create(id=None, headline='NASA uses Python') - self.a2.publications.add(self.p1, self.p2, self.p3, self.p4) - - self.a3 = Article.objects.create(headline='NASA finds intelligent life on Earth') - self.a3.publications.add(self.p2) - - self.a4 = Article.objects.create(headline='Oxygen-free diet works wonders') - self.a4.publications.add(self.p2) - - def test_add(self): - # Create an Article. - a5 = Article(id=None, headline='Django lets you reate Web apps easily') - # You can't associate it with a Publication until it's been saved. - self.assertRaises(ValueError, getattr, a5, 'publications') - # Save it! - a5.save() - # Associate the Article with a Publication. - a5.publications.add(self.p1) - self.assertQuerysetEqual(a5.publications.all(), - ['<Publication: The Python Journal>']) - # Create another Article, and set it to appear in both Publications. - a6 = Article(id=None, headline='ESA uses Python') - a6.save() - a6.publications.add(self.p1, self.p2) - a6.publications.add(self.p3) - # Adding a second time is OK - a6.publications.add(self.p3) - self.assertQuerysetEqual(a6.publications.all(), - [ - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - - # Adding an object of the wrong type raises TypeError - self.assertRaises(TypeError, a6.publications.add, a5) - # Add a Publication directly via publications.add by using keyword arguments. - p4 = a6.publications.create(title='Highlights for Adults') - self.assertQuerysetEqual(a6.publications.all(), - [ - '<Publication: Highlights for Adults>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - - def test_reverse_add(self): - # Adding via the 'other' end of an m2m - a5 = Article(headline='NASA finds intelligent life on Mars') - a5.save() - self.p2.article_set.add(a5) - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA finds intelligent life on Mars>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(a5.publications.all(), - ['<Publication: Science News>']) - - # Adding via the other end using keywords - new_article = self.p2.article_set.create(headline='Carbon-free diet works wonders') - self.assertQuerysetEqual( - self.p2.article_set.all(), - [ - '<Article: Carbon-free diet works wonders>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA finds intelligent life on Mars>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - a6 = self.p2.article_set.all()[3] - self.assertQuerysetEqual(a6.publications.all(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - - def test_related_sets(self): - # Article objects have access to their related Publication objects. - self.assertQuerysetEqual(self.a1.publications.all(), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual(self.a2.publications.all(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - # Publication objects have access to their related Article objects. - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.p1.article_set.all(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual(Publication.objects.get(id=self.p4.id).article_set.all(), - ['<Article: NASA uses Python>']) - - def test_selects(self): - # We can perform kwarg queries across m2m relationships - self.assertQuerysetEqual( - Article.objects.filter(publications__id__exact=self.p1.id), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications__pk=self.p1.id), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications=self.p1.id), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications=self.p1), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications__title__startswith="Science"), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications__title__startswith="Science").distinct(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - - # The count() function respects distinct() as well. - self.assertEqual(Article.objects.filter(publications__title__startswith="Science").count(), 4) - self.assertEqual(Article.objects.filter(publications__title__startswith="Science").distinct().count(), 3) - self.assertQuerysetEqual( - Article.objects.filter(publications__in=[self.p1.id,self.p2.id]).distinct(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications__in=[self.p1.id,self.p2]).distinct(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual( - Article.objects.filter(publications__in=[self.p1,self.p2]).distinct(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - - # Excluding a related item works as you would expect, too (although the SQL - # involved is a little complex). - self.assertQuerysetEqual(Article.objects.exclude(publications=self.p2), - ['<Article: Django lets you build Web apps easily>']) - - def test_reverse_selects(self): - # Reverse m2m queries are supported (i.e., starting at the table that - # doesn't have a ManyToManyField). - self.assertQuerysetEqual(Publication.objects.filter(id__exact=self.p1.id), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual(Publication.objects.filter(pk=self.p1.id), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual( - Publication.objects.filter(article__headline__startswith="NASA"), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - self.assertQuerysetEqual(Publication.objects.filter(article__id__exact=self.a1.id), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual(Publication.objects.filter(article__pk=self.a1.id), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual(Publication.objects.filter(article=self.a1.id), - ['<Publication: The Python Journal>']) - self.assertQuerysetEqual(Publication.objects.filter(article=self.a1), - ['<Publication: The Python Journal>']) - - self.assertQuerysetEqual( - Publication.objects.filter(article__in=[self.a1.id,self.a2.id]).distinct(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - self.assertQuerysetEqual( - Publication.objects.filter(article__in=[self.a1.id,self.a2]).distinct(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - self.assertQuerysetEqual( - Publication.objects.filter(article__in=[self.a1,self.a2]).distinct(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - '<Publication: The Python Journal>', - ]) - - def test_delete(self): - # If we delete a Publication, its Articles won't be able to access it. - self.p1.delete() - self.assertQuerysetEqual(Publication.objects.all(), - [ - '<Publication: Highlights for Children>', - '<Publication: Science News>', - '<Publication: Science Weekly>', - ]) - self.assertQuerysetEqual(self.a1.publications.all(), []) - # If we delete an Article, its Publications won't be able to access it. - self.a2.delete() - self.assertQuerysetEqual(Article.objects.all(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: Oxygen-free diet works wonders>', - ]) - - def test_bulk_delete(self): - # Bulk delete some Publications - references to deleted publications should go - Publication.objects.filter(title__startswith='Science').delete() - self.assertQuerysetEqual(Publication.objects.all(), - [ - '<Publication: Highlights for Children>', - '<Publication: The Python Journal>', - ]) - self.assertQuerysetEqual(Article.objects.all(), - [ - '<Article: Django lets you build Web apps easily>', - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.a2.publications.all(), - [ - '<Publication: Highlights for Children>', - '<Publication: The Python Journal>', - ]) - - # Bulk delete some articles - references to deleted objects should go - q = Article.objects.filter(headline__startswith='Django') - self.assertQuerysetEqual(q, ['<Article: Django lets you build Web apps easily>']) - q.delete() - # After the delete, the QuerySet cache needs to be cleared, - # and the referenced objects should be gone - self.assertQuerysetEqual(q, []) - self.assertQuerysetEqual(self.p1.article_set.all(), - ['<Article: NASA uses Python>']) - - def test_remove(self): - # Removing publication from an article: - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.a4.publications.remove(self.p2) - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual(self.a4.publications.all(), []) - # And from the other end - self.p2.article_set.remove(self.a3) - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA uses Python>', - ]) - self.assertQuerysetEqual(self.a3.publications.all(), []) - - def test_assign(self): - # Relation sets can be assigned. Assignment clears any existing set members - self.p2.article_set = [self.a4, self.a3] - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.a4.publications.all(), - ['<Publication: Science News>']) - self.a4.publications = [self.p3.id] - self.assertQuerysetEqual(self.p2.article_set.all(), - ['<Article: NASA finds intelligent life on Earth>']) - self.assertQuerysetEqual(self.a4.publications.all(), - ['<Publication: Science Weekly>']) - - # An alternate to calling clear() is to assign the empty set - self.p2.article_set = [] - self.assertQuerysetEqual(self.p2.article_set.all(), []) - self.a4.publications = [] - self.assertQuerysetEqual(self.a4.publications.all(), []) - - def test_assign_ids(self): - # Relation sets can also be set using primary key values - self.p2.article_set = [self.a4.id, self.a3.id] - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.a4.publications.all(), - ['<Publication: Science News>']) - self.a4.publications = [self.p3.id] - self.assertQuerysetEqual(self.p2.article_set.all(), - ['<Article: NASA finds intelligent life on Earth>']) - self.assertQuerysetEqual(self.a4.publications.all(), - ['<Publication: Science Weekly>']) - - def test_clear(self): - # Relation sets can be cleared: - self.p2.article_set.clear() - self.assertQuerysetEqual(self.p2.article_set.all(), []) - self.assertQuerysetEqual(self.a4.publications.all(), []) - - # And you can clear from the other end - self.p2.article_set.add(self.a3, self.a4) - self.assertQuerysetEqual(self.p2.article_set.all(), - [ - '<Article: NASA finds intelligent life on Earth>', - '<Article: Oxygen-free diet works wonders>', - ]) - self.assertQuerysetEqual(self.a4.publications.all(), - [ - '<Publication: Science News>', - ]) - self.a4.publications.clear() - self.assertQuerysetEqual(self.a4.publications.all(), []) - self.assertQuerysetEqual(self.p2.article_set.all(), - ['<Article: NASA finds intelligent life on Earth>']) diff --git a/parts/django/tests/modeltests/many_to_one/__init__.py b/parts/django/tests/modeltests/many_to_one/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/many_to_one/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/many_to_one/models.py b/parts/django/tests/modeltests/many_to_one/models.py deleted file mode 100644 index b4a0f37..0000000 --- a/parts/django/tests/modeltests/many_to_one/models.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -4. Many-to-one relationships - -To define a many-to-one relationship, use ``ForeignKey()``. -""" - -from django.db import models - -class Reporter(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - email = models.EmailField() - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - reporter = models.ForeignKey(Reporter) - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('headline',) diff --git a/parts/django/tests/modeltests/many_to_one/tests.py b/parts/django/tests/modeltests/many_to_one/tests.py deleted file mode 100644 index 53306b7..0000000 --- a/parts/django/tests/modeltests/many_to_one/tests.py +++ /dev/null @@ -1,371 +0,0 @@ -from datetime import datetime -from django.test import TestCase -from django.core.exceptions import FieldError -from models import Article, Reporter - -class ManyToOneTests(TestCase): - - def setUp(self): - # Create a few Reporters. - self.r = Reporter(first_name='John', last_name='Smith', email='john@example.com') - self.r.save() - self.r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com') - self.r2.save() - # Create an Article. - self.a = Article(id=None, headline="This is a test", - pub_date=datetime(2005, 7, 27), reporter=self.r) - self.a.save() - - def test_get(self): - # Article objects have access to their related Reporter objects. - r = self.a.reporter - self.assertEqual(r.id, self.r.id) - # These are strings instead of unicode strings because that's what was used in - # the creation of this reporter (and we haven't refreshed the data from the - # database, which always returns unicode strings). - self.assertEqual((r.first_name, self.r.last_name), ('John', 'Smith')) - - def test_create(self): - # You can also instantiate an Article by passing the Reporter's ID - # instead of a Reporter object. - a3 = Article(id=None, headline="Third article", - pub_date=datetime(2005, 7, 27), reporter_id=self.r.id) - a3.save() - self.assertEqual(a3.reporter.id, self.r.id) - - # Similarly, the reporter ID can be a string. - a4 = Article(id=None, headline="Fourth article", - pub_date=datetime(2005, 7, 27), reporter_id=str(self.r.id)) - a4.save() - self.assertEqual(repr(a4.reporter), "<Reporter: John Smith>") - - def test_add(self): - # Create an Article via the Reporter object. - new_article = self.r.article_set.create(headline="John's second story", - pub_date=datetime(2005, 7, 29)) - self.assertEqual(repr(new_article), "<Article: John's second story>") - self.assertEqual(new_article.reporter.id, self.r.id) - - # Create a new article, and add it to the article set. - new_article2 = Article(headline="Paul's story", pub_date=datetime(2006, 1, 17)) - self.r.article_set.add(new_article2) - self.assertEqual(new_article2.reporter.id, self.r.id) - self.assertQuerysetEqual(self.r.article_set.all(), - [ - "<Article: John's second story>", - "<Article: Paul's story>", - "<Article: This is a test>", - ]) - - # Add the same article to a different article set - check that it moves. - self.r2.article_set.add(new_article2) - self.assertEqual(new_article2.reporter.id, self.r2.id) - self.assertQuerysetEqual(self.r2.article_set.all(), ["<Article: Paul's story>"]) - - # Adding an object of the wrong type raises TypeError. - self.assertRaises(TypeError, self.r.article_set.add, self.r2) - self.assertQuerysetEqual(self.r.article_set.all(), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - - def test_assign(self): - new_article = self.r.article_set.create(headline="John's second story", - pub_date=datetime(2005, 7, 29)) - new_article2 = self.r2.article_set.create(headline="Paul's story", - pub_date=datetime(2006, 1, 17)) - # Assign the article to the reporter directly using the descriptor. - new_article2.reporter = self.r - new_article2.save() - self.assertEqual(repr(new_article2.reporter), "<Reporter: John Smith>") - self.assertEqual(new_article2.reporter.id, self.r.id) - self.assertQuerysetEqual(self.r.article_set.all(), [ - "<Article: John's second story>", - "<Article: Paul's story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual(self.r2.article_set.all(), []) - # Set the article back again using set descriptor. - self.r2.article_set = [new_article, new_article2] - self.assertQuerysetEqual(self.r.article_set.all(), ["<Article: This is a test>"]) - self.assertQuerysetEqual(self.r2.article_set.all(), - [ - "<Article: John's second story>", - "<Article: Paul's story>", - ]) - - # Funny case - assignment notation can only go so far; because the - # ForeignKey cannot be null, existing members of the set must remain. - self.r.article_set = [new_article] - self.assertQuerysetEqual(self.r.article_set.all(), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual(self.r2.article_set.all(), ["<Article: Paul's story>"]) - # Reporter cannot be null - there should not be a clear or remove method - self.assertFalse(hasattr(self.r2.article_set, 'remove')) - self.assertFalse(hasattr(self.r2.article_set, 'clear')) - - def test_selects(self): - new_article = self.r.article_set.create(headline="John's second story", - pub_date=datetime(2005, 7, 29)) - new_article2 = self.r2.article_set.create(headline="Paul's story", - pub_date=datetime(2006, 1, 17)) - # Reporter objects have access to their related Article objects. - self.assertQuerysetEqual(self.r.article_set.all(), [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual(self.r.article_set.filter(headline__startswith='This'), - ["<Article: This is a test>"]) - self.assertEqual(self.r.article_set.count(), 2) - self.assertEqual(self.r2.article_set.count(), 1) - # Get articles by id - self.assertQuerysetEqual(Article.objects.filter(id__exact=self.a.id), - ["<Article: This is a test>"]) - self.assertQuerysetEqual(Article.objects.filter(pk=self.a.id), - ["<Article: This is a test>"]) - # Query on an article property - self.assertQuerysetEqual(Article.objects.filter(headline__startswith='This'), - ["<Article: This is a test>"]) - # The API automatically follows relationships as far as you need. - # Use double underscores to separate relationships. - # This works as many levels deep as you want. There's no limit. - # Find all Articles for any Reporter whose first name is "John". - self.assertQuerysetEqual(Article.objects.filter(reporter__first_name__exact='John'), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - # Check that implied __exact also works - self.assertQuerysetEqual(Article.objects.filter(reporter__first_name='John'), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - # Query twice over the related field. - self.assertQuerysetEqual( - Article.objects.filter(reporter__first_name__exact='John', - reporter__last_name__exact='Smith'), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - # The underlying query only makes one join when a related table is referenced twice. - queryset = Article.objects.filter(reporter__first_name__exact='John', - reporter__last_name__exact='Smith') - self.assertEqual(queryset.query.get_compiler(queryset.db).as_sql()[0].count('INNER JOIN'), 1) - - # The automatically joined table has a predictable name. - self.assertQuerysetEqual( - Article.objects.filter(reporter__first_name__exact='John').extra( - where=["many_to_one_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 forms.Form.cleaned_data - self.assertQuerysetEqual( - Article.objects.filter(reporter__first_name__exact='John' - ).extra(where=["many_to_one_reporter.last_name='%s'" % u'Smith']), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - # Find all Articles for a Reporter. - # Use direct ID check, pk check, and object comparison - self.assertQuerysetEqual( - Article.objects.filter(reporter__id__exact=self.r.id), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual( - Article.objects.filter(reporter__pk=self.r.id), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual( - Article.objects.filter(reporter=self.r.id), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual( - Article.objects.filter(reporter=self.r), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual( - Article.objects.filter(reporter__in=[self.r.id,self.r2.id]).distinct(), - [ - "<Article: John's second story>", - "<Article: Paul's story>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual( - Article.objects.filter(reporter__in=[self.r,self.r2]).distinct(), - [ - "<Article: John's second story>", - "<Article: Paul's story>", - "<Article: This is a test>", - ]) - # You can also use a queryset instead of a literal list of instances. - # The queryset must be reduced to a list of values using values(), - # then converted into a query - self.assertQuerysetEqual( - Article.objects.filter( - reporter__in=Reporter.objects.filter(first_name='John').values('pk').query - ).distinct(), - [ - "<Article: John's second story>", - "<Article: This is a test>", - ]) - # You need two underscores between "reporter" and "id" -- not one. - self.assertRaises(FieldError, Article.objects.filter, reporter_id__exact=self.r.id) - # You need to specify a comparison clause - self.assertRaises(FieldError, Article.objects.filter, reporter_id=self.r.id) - - def test_reverse_selects(self): - a3 = Article.objects.create(id=None, headline="Third article", - pub_date=datetime(2005, 7, 27), reporter_id=self.r.id) - a4 = Article.objects.create(id=None, headline="Fourth article", - pub_date=datetime(2005, 7, 27), reporter_id=str(self.r.id)) - # Reporters can be queried - self.assertQuerysetEqual(Reporter.objects.filter(id__exact=self.r.id), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual(Reporter.objects.filter(pk=self.r.id), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual(Reporter.objects.filter(first_name__startswith='John'), - ["<Reporter: John Smith>"]) - # Reporters can query in opposite direction of ForeignKey definition - self.assertQuerysetEqual(Reporter.objects.filter(article__id__exact=self.a.id), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual(Reporter.objects.filter(article__pk=self.a.id), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual(Reporter.objects.filter(article=self.a.id), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual(Reporter.objects.filter(article=self.a), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__in=[self.a.id,a3.id]).distinct(), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__in=[self.a.id,a3]).distinct(), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__in=[self.a,a3]).distinct(), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__headline__startswith='T'), - ["<Reporter: John Smith>", "<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__headline__startswith='T').distinct(), - ["<Reporter: John Smith>"]) - - # Counting in the opposite direction works in conjunction with distinct() - self.assertEqual( - Reporter.objects.filter(article__headline__startswith='T').count(), 2) - self.assertEqual( - Reporter.objects.filter(article__headline__startswith='T').distinct().count(), 1) - - # Queries can go round in circles. - self.assertQuerysetEqual( - Reporter.objects.filter(article__reporter__first_name__startswith='John'), - [ - "<Reporter: John Smith>", - "<Reporter: John Smith>", - "<Reporter: John Smith>", - ]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct(), - ["<Reporter: John Smith>"]) - self.assertQuerysetEqual( - Reporter.objects.filter(article__reporter__exact=self.r).distinct(), - ["<Reporter: John Smith>"]) - - # Check that implied __exact also works. - self.assertQuerysetEqual( - Reporter.objects.filter(article__reporter=self.r).distinct(), - ["<Reporter: John Smith>"]) - - # It's possible to use values() calls across many-to-one relations. - # (Note, too, that we clear the ordering here so as not to drag the - # 'headline' field into the columns being used to determine uniqueness) - d = {'reporter__first_name': u'John', 'reporter__last_name': u'Smith'} - self.assertEqual([d], - list(Article.objects.filter(reporter=self.r).distinct().order_by() - .values('reporter__first_name', 'reporter__last_name'))) - - def test_select_related(self): - # Check that Article.objects.select_related().dates() works properly when - # there are multiple Articles with the same date but different foreign-key - # objects (Reporters). - r1 = Reporter.objects.create(first_name='Mike', last_name='Royko', email='royko@suntimes.com') - r2 = Reporter.objects.create(first_name='John', last_name='Kass', email='jkass@tribune.com') - a1 = Article.objects.create(headline='First', pub_date=datetime(1980, 4, 23), reporter=r1) - a2 = Article.objects.create(headline='Second', pub_date=datetime(1980, 4, 23), reporter=r2) - self.assertEqual(list(Article.objects.select_related().dates('pub_date', 'day')), - [ - datetime(1980, 4, 23, 0, 0), - datetime(2005, 7, 27, 0, 0), - ]) - self.assertEqual(list(Article.objects.select_related().dates('pub_date', 'month')), - [ - datetime(1980, 4, 1, 0, 0), - datetime(2005, 7, 1, 0, 0), - ]) - self.assertEqual(list(Article.objects.select_related().dates('pub_date', 'year')), - [ - datetime(1980, 1, 1, 0, 0), - datetime(2005, 1, 1, 0, 0), - ]) - - def test_delete(self): - new_article = self.r.article_set.create(headline="John's second story", - pub_date=datetime(2005, 7, 29)) - new_article2 = self.r2.article_set.create(headline="Paul's story", - pub_date=datetime(2006, 1, 17)) - a3 = Article.objects.create(id=None, headline="Third article", - pub_date=datetime(2005, 7, 27), reporter_id=self.r.id) - a4 = Article.objects.create(id=None, headline="Fourth article", - pub_date=datetime(2005, 7, 27), reporter_id=str(self.r.id)) - # If you delete a reporter, his articles will be deleted. - self.assertQuerysetEqual(Article.objects.all(), - [ - "<Article: Fourth article>", - "<Article: John's second story>", - "<Article: Paul's story>", - "<Article: Third article>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual(Reporter.objects.order_by('first_name'), - [ - "<Reporter: John Smith>", - "<Reporter: Paul Jones>", - ]) - self.r2.delete() - self.assertQuerysetEqual(Article.objects.all(), - [ - "<Article: Fourth article>", - "<Article: John's second story>", - "<Article: Third article>", - "<Article: This is a test>", - ]) - self.assertQuerysetEqual(Reporter.objects.order_by('first_name'), - ["<Reporter: John Smith>"]) - # You can delete using a JOIN in the query. - Reporter.objects.filter(article__headline__startswith='This').delete() - self.assertQuerysetEqual(Reporter.objects.all(), []) - self.assertQuerysetEqual(Article.objects.all(), []) - - def test_regression_12876(self): - # Regression for #12876 -- Model methods that include queries that - # recursive don't cause recursion depth problems under deepcopy. - self.r.cached_query = Article.objects.filter(reporter=self.r) - from copy import deepcopy - self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>") diff --git a/parts/django/tests/modeltests/many_to_one_null/__init__.py b/parts/django/tests/modeltests/many_to_one_null/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/many_to_one_null/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/many_to_one_null/models.py b/parts/django/tests/modeltests/many_to_one_null/models.py deleted file mode 100644 index 5f824b4..0000000 --- a/parts/django/tests/modeltests/many_to_one_null/models.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -16. Many-to-one relationships that can be null - -To define a many-to-one relationship that can have a null foreign key, use -``ForeignKey()`` with ``null=True`` . -""" - -from django.db import models - -class Reporter(models.Model): - name = models.CharField(max_length=30) - - def __unicode__(self): - return self.name - -class Article(models.Model): - headline = models.CharField(max_length=100) - reporter = models.ForeignKey(Reporter, null=True) - - class Meta: - ordering = ('headline',) - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/many_to_one_null/tests.py b/parts/django/tests/modeltests/many_to_one_null/tests.py deleted file mode 100644 index c78f980..0000000 --- a/parts/django/tests/modeltests/many_to_one_null/tests.py +++ /dev/null @@ -1,84 +0,0 @@ -from django.test import TestCase -from models import Reporter, Article - -class ManyToOneNullTests(TestCase): - - def setUp(self): - # Create a Reporter. - self.r = Reporter(name='John Smith') - self.r.save() - # Create an Article. - self.a = Article(headline="First", reporter=self.r) - self.a.save() - # Create an Article via the Reporter object. - self.a2 = self.r.article_set.create(headline="Second") - # Create an Article with no Reporter by passing "reporter=None". - self.a3 = Article(headline="Third", reporter=None) - self.a3.save() - # Create another article and reporter - self.r2 = Reporter(name='Paul Jones') - self.r2.save() - self.a4 = self.r2.article_set.create(headline='Fourth') - - def test_get_related(self): - self.assertEqual(self.a.reporter.id, self.r.id) - # Article objects have access to their related Reporter objects. - r = self.a.reporter - self.assertEqual(r.id, self.r.id) - - def test_created_via_related_set(self): - self.assertEqual(self.a2.reporter.id, self.r.id) - - def test_related_set(self): - # Reporter objects have access to their related Article objects. - self.assertQuerysetEqual(self.r.article_set.all(), - ['<Article: First>', '<Article: Second>']) - self.assertQuerysetEqual(self.r.article_set.filter(headline__startswith='Fir'), - ['<Article: First>']) - self.assertEqual(self.r.article_set.count(), 2) - - def test_created_without_related(self): - self.assertEqual(self.a3.reporter, None) - # Need to reget a3 to refresh the cache - a3 = Article.objects.get(pk=self.a3.pk) - self.assertRaises(AttributeError, getattr, a3.reporter, 'id') - # Accessing an article's 'reporter' attribute returns None - # if the reporter is set to None. - self.assertEqual(a3.reporter, None) - # To retrieve the articles with no reporters set, use "reporter__isnull=True". - self.assertQuerysetEqual(Article.objects.filter(reporter__isnull=True), - ['<Article: Third>']) - # We can achieve the same thing by filtering for the case where the - # reporter is None. - self.assertQuerysetEqual(Article.objects.filter(reporter=None), - ['<Article: Third>']) - # Set the reporter for the Third article - self.assertQuerysetEqual(self.r.article_set.all(), - ['<Article: First>', '<Article: Second>']) - self.r.article_set.add(a3) - self.assertQuerysetEqual(self.r.article_set.all(), - ['<Article: First>', '<Article: Second>', '<Article: Third>']) - # Remove an article from the set, and check that it was removed. - self.r.article_set.remove(a3) - self.assertQuerysetEqual(self.r.article_set.all(), - ['<Article: First>', '<Article: Second>']) - self.assertQuerysetEqual(Article.objects.filter(reporter__isnull=True), - ['<Article: Third>']) - - def test_remove_from_wrong_set(self): - self.assertQuerysetEqual(self.r2.article_set.all(), ['<Article: Fourth>']) - # Try to remove a4 from a set it does not belong to - self.assertRaises(Reporter.DoesNotExist, self.r.article_set.remove, self.a4) - self.assertQuerysetEqual(self.r2.article_set.all(), ['<Article: Fourth>']) - - def test_assign_clear_related_set(self): - # Use descriptor assignment to allocate ForeignKey. Null is legal, so - # existing members of set that are not in the assignment set are set null - self.r2.article_set = [self.a2, self.a3] - self.assertQuerysetEqual(self.r2.article_set.all(), - ['<Article: Second>', '<Article: Third>']) - # Clear the rest of the set - self.r.article_set.clear() - self.assertQuerysetEqual(self.r.article_set.all(), []) - self.assertQuerysetEqual(Article.objects.filter(reporter__isnull=True), - ['<Article: First>', '<Article: Fourth>']) diff --git a/parts/django/tests/modeltests/model_forms/__init__.py b/parts/django/tests/modeltests/model_forms/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/model_forms/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/model_forms/mforms.py b/parts/django/tests/modeltests/model_forms/mforms.py deleted file mode 100644 index aef763e..0000000 --- a/parts/django/tests/modeltests/model_forms/mforms.py +++ /dev/null @@ -1,39 +0,0 @@ -from django import forms -from django.forms import ModelForm - -from models import Product, Price, Book, DerivedBook, ExplicitPK, Post, DerivedPost, Writer - -class ProductForm(ModelForm): - class Meta: - model = Product - -class PriceForm(ModelForm): - class Meta: - model = Price - -class BookForm(ModelForm): - class Meta: - model = Book - -class DerivedBookForm(ModelForm): - class Meta: - model = DerivedBook - -class ExplicitPKForm(ModelForm): - class Meta: - model = ExplicitPK - fields = ('key', 'desc',) - -class PostForm(ModelForm): - class Meta: - model = Post - -class DerivedPostForm(ModelForm): - class Meta: - model = DerivedPost - -class CustomWriterForm(ModelForm): - name = forms.CharField(required=False) - - class Meta: - model = Writer diff --git a/parts/django/tests/modeltests/model_forms/models.py b/parts/django/tests/modeltests/model_forms/models.py deleted file mode 100644 index 1087cf8..0000000 --- a/parts/django/tests/modeltests/model_forms/models.py +++ /dev/null @@ -1,1575 +0,0 @@ -""" -XX. Generating HTML forms from models - -This is mostly just a reworking of the ``form_for_model``/``form_for_instance`` -tests to use ``ModelForm``. As such, the text may not make sense in all cases, -and the examples are probably a poor fit for the ``ModelForm`` syntax. In other -words, most of these tests should be rewritten. -""" - -import os -import tempfile - -from django.db import models -from django.core.files.storage import FileSystemStorage - -temp_storage_dir = tempfile.mkdtemp() -temp_storage = FileSystemStorage(temp_storage_dir) - -ARTICLE_STATUS = ( - (1, 'Draft'), - (2, 'Pending'), - (3, 'Live'), -) - -ARTICLE_STATUS_CHAR = ( - ('d', 'Draft'), - ('p', 'Pending'), - ('l', 'Live'), -) - -class Category(models.Model): - name = models.CharField(max_length=20) - slug = models.SlugField(max_length=20) - url = models.CharField('The URL', max_length=40) - - def __unicode__(self): - return self.name - -class Writer(models.Model): - name = models.CharField(max_length=50, help_text='Use both first and last names.') - - def __unicode__(self): - return self.name - -class Article(models.Model): - headline = models.CharField(max_length=50) - slug = models.SlugField() - pub_date = models.DateField() - created = models.DateField(editable=False) - writer = models.ForeignKey(Writer) - article = models.TextField() - categories = models.ManyToManyField(Category, blank=True) - status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True) - - def save(self): - import datetime - if not self.id: - self.created = datetime.date.today() - return super(Article, self).save() - - def __unicode__(self): - return self.headline - -class ImprovedArticle(models.Model): - article = models.OneToOneField(Article) - -class ImprovedArticleWithParentLink(models.Model): - article = models.OneToOneField(Article, parent_link=True) - -class BetterWriter(Writer): - score = models.IntegerField() - -class WriterProfile(models.Model): - writer = models.OneToOneField(Writer, primary_key=True) - age = models.PositiveIntegerField() - - def __unicode__(self): - return "%s is %s" % (self.writer, self.age) - -from django.contrib.localflavor.us.models import PhoneNumberField -class PhoneNumber(models.Model): - phone = PhoneNumberField() - description = models.CharField(max_length=20) - - def __unicode__(self): - return self.phone - -class TextFile(models.Model): - description = models.CharField(max_length=20) - file = models.FileField(storage=temp_storage, upload_to='tests', max_length=15) - - def __unicode__(self): - return self.description - -try: - # If PIL is available, try testing ImageFields. Checking for the existence - # of Image is enough for CPython, but for PyPy, you need to check for the - # underlying modules If PIL is not available, ImageField tests are omitted. - # Try to import PIL in either of the two ways it can end up installed. - try: - from PIL import Image, _imaging - except ImportError: - import Image, _imaging - - test_images = True - - class ImageFile(models.Model): - def custom_upload_path(self, filename): - path = self.path or 'tests' - return '%s/%s' % (path, filename) - - description = models.CharField(max_length=20) - - # Deliberately put the image field *after* the width/height fields to - # trigger the bug in #10404 with width/height not getting assigned. - width = models.IntegerField(editable=False) - height = models.IntegerField(editable=False) - image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path, - width_field='width', height_field='height') - path = models.CharField(max_length=16, blank=True, default='') - - def __unicode__(self): - return self.description - - class OptionalImageFile(models.Model): - def custom_upload_path(self, filename): - path = self.path or 'tests' - return '%s/%s' % (path, filename) - - description = models.CharField(max_length=20) - image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path, - width_field='width', height_field='height', - blank=True, null=True) - width = models.IntegerField(editable=False, null=True) - height = models.IntegerField(editable=False, null=True) - path = models.CharField(max_length=16, blank=True, default='') - - def __unicode__(self): - return self.description -except ImportError: - test_images = False - -class CommaSeparatedInteger(models.Model): - field = models.CommaSeparatedIntegerField(max_length=20) - - def __unicode__(self): - return self.field - -class Product(models.Model): - slug = models.SlugField(unique=True) - - def __unicode__(self): - return self.slug - -class Price(models.Model): - price = models.DecimalField(max_digits=10, decimal_places=2) - quantity = models.PositiveIntegerField() - - def __unicode__(self): - return u"%s for %s" % (self.quantity, self.price) - - class Meta: - unique_together = (('price', 'quantity'),) - -class ArticleStatus(models.Model): - status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) - -class Inventory(models.Model): - barcode = models.PositiveIntegerField(unique=True) - parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) - name = models.CharField(blank=False, max_length=20) - - def __unicode__(self): - return self.name - -class Book(models.Model): - title = models.CharField(max_length=40) - author = models.ForeignKey(Writer, blank=True, null=True) - special_id = models.IntegerField(blank=True, null=True, unique=True) - - class Meta: - unique_together = ('title', 'author') - -class BookXtra(models.Model): - isbn = models.CharField(max_length=16, unique=True) - suffix1 = models.IntegerField(blank=True, default=0) - suffix2 = models.IntegerField(blank=True, default=0) - - class Meta: - unique_together = (('suffix1', 'suffix2')) - abstract = True - -class DerivedBook(Book, BookXtra): - pass - -class ExplicitPK(models.Model): - key = models.CharField(max_length=20, primary_key=True) - desc = models.CharField(max_length=20, blank=True, unique=True) - class Meta: - unique_together = ('key', 'desc') - - def __unicode__(self): - return self.key - -class Post(models.Model): - title = models.CharField(max_length=50, unique_for_date='posted', blank=True) - slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) - subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) - posted = models.DateField() - - def __unicode__(self): - return self.name - -class DerivedPost(Post): - pass - -class BigInt(models.Model): - biggie = models.BigIntegerField() - - def __unicode__(self): - return unicode(self.biggie) - -class MarkupField(models.CharField): - def __init__(self, *args, **kwargs): - kwargs["max_length"] = 20 - super(MarkupField, self).__init__(*args, **kwargs) - - def formfield(self, **kwargs): - # don't allow this field to be used in form (real use-case might be - # that you know the markup will always be X, but it is among an app - # that allows the user to say it could be something else) - # regressed at r10062 - return None - -class CustomFieldForExclusionModel(models.Model): - name = models.CharField(max_length=10) - markup = MarkupField() - -__test__ = {'API_TESTS': """ ->>> from django import forms ->>> from django.forms.models import ModelForm, model_to_dict ->>> from django.core.files.uploadedfile import SimpleUploadedFile - -The bare bones, absolutely nothing custom, basic case. - ->>> class CategoryForm(ModelForm): -... class Meta: -... model = Category ->>> CategoryForm.base_fields.keys() -['name', 'slug', 'url'] - - -Extra fields. - ->>> class CategoryForm(ModelForm): -... some_extra_field = forms.BooleanField() -... -... class Meta: -... model = Category - ->>> CategoryForm.base_fields.keys() -['name', 'slug', 'url', 'some_extra_field'] - -Extra field that has a name collision with a related object accessor. - ->>> class WriterForm(ModelForm): -... book = forms.CharField(required=False) -... -... class Meta: -... model = Writer - ->>> wf = WriterForm({'name': 'Richard Lockridge'}) ->>> wf.is_valid() -True - -Replacing a field. - ->>> class CategoryForm(ModelForm): -... url = forms.BooleanField() -... -... class Meta: -... model = Category - ->>> CategoryForm.base_fields['url'].__class__ -<class 'django.forms.fields.BooleanField'> - - -Using 'fields'. - ->>> class CategoryForm(ModelForm): -... -... class Meta: -... model = Category -... fields = ['url'] - ->>> CategoryForm.base_fields.keys() -['url'] - - -Using 'exclude' - ->>> class CategoryForm(ModelForm): -... -... class Meta: -... model = Category -... exclude = ['url'] - ->>> CategoryForm.base_fields.keys() -['name', 'slug'] - - -Using 'fields' *and* 'exclude'. Not sure why you'd want to do this, but uh, -"be liberal in what you accept" and all. - ->>> class CategoryForm(ModelForm): -... -... class Meta: -... model = Category -... fields = ['name', 'url'] -... exclude = ['url'] - ->>> CategoryForm.base_fields.keys() -['name'] - -Using 'widgets' - ->>> class CategoryForm(ModelForm): -... -... class Meta: -... model = Category -... fields = ['name', 'url', 'slug'] -... widgets = { -... 'name': forms.Textarea, -... 'url': forms.TextInput(attrs={'class': 'url'}) -... } - ->>> str(CategoryForm()['name']) -'<textarea id="id_name" rows="10" cols="40" name="name"></textarea>' - ->>> str(CategoryForm()['url']) -'<input id="id_url" type="text" class="url" name="url" maxlength="40" />' - ->>> str(CategoryForm()['slug']) -'<input id="id_slug" type="text" name="slug" maxlength="20" />' - -Don't allow more than one 'model' definition in the inheritance hierarchy. -Technically, it would generate a valid form, but the fact that the resulting -save method won't deal with multiple objects is likely to trip up people not -familiar with the mechanics. - ->>> class CategoryForm(ModelForm): -... class Meta: -... model = Category - ->>> class OddForm(CategoryForm): -... class Meta: -... model = Article - -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 ->>> OddForm.base_fields.keys() -['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] - -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> - -# test using fields to provide ordering to the fields ->>> class CategoryForm(ModelForm): -... class Meta: -... model = Category -... fields = ['url', 'name'] - ->>> CategoryForm.base_fields.keys() -['url', 'name'] - - ->>> print CategoryForm() -<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> -<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr> - ->>> class CategoryForm(ModelForm): -... class Meta: -... model = Category -... fields = ['slug', 'url', 'name'] -... exclude = ['url'] - ->>> CategoryForm.base_fields.keys() -['slug', 'name'] - -# Old form_for_x tests ####################################################### - ->>> from django.forms import ModelForm, CharField ->>> import datetime - ->>> Category.objects.all() -[] - ->>> class CategoryForm(ModelForm): -... class Meta: -... model = Category ->>> f = CategoryForm() ->>> print f -<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_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> ->>> print f.as_ul() -<li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="20" /></li> -<li><label for="id_slug">Slug:</label> <input id="id_slug" type="text" name="slug" maxlength="20" /></li> -<li><label for="id_url">The URL:</label> <input id="id_url" type="text" name="url" maxlength="40" /></li> ->>> print f['name'] -<input id="id_name" type="text" name="name" maxlength="20" /> - ->>> f = CategoryForm(auto_id=False) ->>> print f.as_ul() -<li>Name: <input type="text" name="name" maxlength="20" /></li> -<li>Slug: <input type="text" name="slug" maxlength="20" /></li> -<li>The URL: <input type="text" name="url" maxlength="40" /></li> - ->>> f = CategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'}) ->>> f.is_valid() -True ->>> f.cleaned_data['url'] -u'entertainment' ->>> f.cleaned_data['name'] -u'Entertainment' ->>> f.cleaned_data['slug'] -u'entertainment' ->>> obj = f.save() ->>> obj -<Category: Entertainment> ->>> Category.objects.all() -[<Category: Entertainment>] - ->>> f = CategoryForm({'name': "It's a test", 'slug': 'its-test', 'url': 'test'}) ->>> f.is_valid() -True ->>> f.cleaned_data['url'] -u'test' ->>> f.cleaned_data['name'] -u"It's a test" ->>> f.cleaned_data['slug'] -u'its-test' ->>> obj = f.save() ->>> obj -<Category: It's a test> ->>> Category.objects.order_by('name') -[<Category: Entertainment>, <Category: It's a test>] - -If you call save() with commit=False, then it will return an object that -hasn't yet been saved to the database. In this case, it's up to you to call -save() on the resulting model instance. ->>> f = CategoryForm({'name': 'Third test', 'slug': 'third-test', 'url': 'third'}) ->>> f.is_valid() -True ->>> f.cleaned_data['url'] -u'third' ->>> f.cleaned_data['name'] -u'Third test' ->>> f.cleaned_data['slug'] -u'third-test' ->>> obj = f.save(commit=False) ->>> obj -<Category: Third test> ->>> Category.objects.order_by('name') -[<Category: Entertainment>, <Category: It's a test>] ->>> obj.save() ->>> Category.objects.order_by('name') -[<Category: Entertainment>, <Category: It's a test>, <Category: Third test>] - -If you call save() with invalid data, you'll get a ValueError. ->>> f = CategoryForm({'name': '', 'slug': 'not a slug!', 'url': 'foo'}) ->>> f.errors['name'] -[u'This field is required.'] ->>> f.errors['slug'] -[u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."] ->>> f.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'CategoryForm' object has no attribute 'cleaned_data' ->>> f.save() -Traceback (most recent call last): -... -ValueError: The Category could not be created because the data didn't validate. ->>> f = CategoryForm({'name': '', 'slug': '', 'url': 'foo'}) ->>> f.save() -Traceback (most recent call last): -... -ValueError: The Category could not be created because the data didn't validate. - -Create a couple of Writers. ->>> w_royko = Writer(name='Mike Royko') ->>> w_royko.save() ->>> w_woodward = Writer(name='Bob Woodward') ->>> w_woodward.save() - -ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any -fields with the 'choices' attribute are represented by a ChoiceField. ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm(auto_id=False) ->>> print f -<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> -<tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr> -<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> -<tr><th>Writer:</th><td><select name="writer"> -<option value="" selected="selected">---------</option> -<option value="...">Mike Royko</option> -<option value="...">Bob Woodward</option> -</select></td></tr> -<tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr> -<tr><th>Status:</th><td><select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></td></tr> -<tr><th>Categories:</th><td><select multiple="multiple" name="categories"> -<option value="1">Entertainment</option> -<option value="2">It's a test</option> -<option value="3">Third test</option> -</select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr> - -You can restrict a form to a subset of the complete list of fields -by providing a 'fields' argument. If you try to save a -model created with such a form, you need to ensure that the fields -that are _not_ on the form have default values, or are allowed to have -a value of None. If a field isn't specified on a form, the object created -from the form can't provide a value for that field! ->>> class PartialArticleForm(ModelForm): -... class Meta: -... model = Article -... fields = ('headline','pub_date') ->>> f = PartialArticleForm(auto_id=False) ->>> print f -<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> -<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> - -When the ModelForm is passed an instance, that instance's current values are -inserted as 'initial' data in each Field. ->>> w = Writer.objects.get(name='Mike Royko') ->>> class RoykoForm(ModelForm): -... class Meta: -... model = Writer ->>> f = RoykoForm(auto_id=False, instance=w) ->>> print f -<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br />Use both first and last names.</td></tr> - ->>> art = Article(headline='Test article', slug='test-article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.') ->>> art.save() ->>> art.id -1 ->>> class TestArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = TestArticleForm(auto_id=False, instance=art) ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" value="test-article" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> -<li>Writer: <select name="writer"> -<option value="">---------</option> -<option value="..." selected="selected">Mike Royko</option> -<option value="...">Bob Woodward</option> -</select></li> -<li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> -<li>Status: <select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></li> -<li>Categories: <select multiple="multiple" name="categories"> -<option value="1">Entertainment</option> -<option value="2">It's a test</option> -<option value="3">Third test</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> ->>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': unicode(w_royko.pk), 'article': 'Hello.'}, instance=art) ->>> f.errors -{} ->>> f.is_valid() -True ->>> test_art = f.save() ->>> test_art.id -1 ->>> test_art = Article.objects.get(id=1) ->>> test_art.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. ->>> class PartialArticleForm(ModelForm): -... class Meta: -... model = Article -... fields=('headline', 'slug', 'pub_date') ->>> f = PartialArticleForm({'headline': u'New headline', 'slug': 'new-headline', 'pub_date': u'1988-01-04'}, auto_id=False, instance=art) ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> ->>> f.is_valid() -True ->>> new_art = f.save() ->>> new_art.id -1 ->>> new_art = Article.objects.get(id=1) ->>> new_art.headline -u'New headline' - -Add some categories and test the many-to-many form output. ->>> new_art.categories.all() -[] ->>> new_art.categories.add(Category.objects.get(name='Entertainment')) ->>> new_art.categories.all() -[<Category: Entertainment>] ->>> class TestArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = TestArticleForm(auto_id=False, instance=new_art) ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li> -<li>Writer: <select name="writer"> -<option value="">---------</option> -<option value="..." selected="selected">Mike Royko</option> -<option value="...">Bob Woodward</option> -</select></li> -<li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> -<li>Status: <select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></li> -<li>Categories: <select multiple="multiple" name="categories"> -<option value="1" selected="selected">Entertainment</option> -<option value="2">It's a test</option> -<option value="3">Third test</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> - -Initial values can be provided for model forms ->>> f = TestArticleForm(auto_id=False, initial={'headline': 'Your headline here', 'categories': ['1','2']}) ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" value="Your headline here" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" /></li> -<li>Writer: <select name="writer"> -<option value="" selected="selected">---------</option> -<option value="...">Mike Royko</option> -<option value="...">Bob Woodward</option> -</select></li> -<li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> -<li>Status: <select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></li> -<li>Categories: <select multiple="multiple" name="categories"> -<option value="1" selected="selected">Entertainment</option> -<option value="2" selected="selected">It's a test</option> -<option value="3">Third test</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> - ->>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', -... 'writer': unicode(w_royko.pk), 'article': u'Hello.', 'categories': [u'1', u'2']}, instance=new_art) ->>> new_art = f.save() ->>> new_art.id -1 ->>> new_art = Article.objects.get(id=1) ->>> new_art.categories.order_by('name') -[<Category: Entertainment>, <Category: It's a test>] - -Now, submit form data with no categories. This deletes the existing categories. ->>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', -... 'writer': unicode(w_royko.pk), 'article': u'Hello.'}, instance=new_art) ->>> new_art = f.save() ->>> new_art.id -1 ->>> new_art = Article.objects.get(id=1) ->>> new_art.categories.all() -[] - -Create a new article, with categories, via the form. ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01', -... 'writer': unicode(w_royko.pk), 'article': u'Test.', 'categories': [u'1', u'2']}) ->>> new_art = f.save() ->>> new_art.id -2 ->>> new_art = Article.objects.get(id=2) ->>> new_art.categories.order_by('name') -[<Category: Entertainment>, <Category: It's a test>] - -Create a new article, with no categories, via the form. ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': u'walrus-was-paul', 'pub_date': u'1967-11-01', -... 'writer': unicode(w_royko.pk), 'article': u'Test.'}) ->>> new_art = f.save() ->>> new_art.id -3 ->>> new_art = Article.objects.get(id=3) ->>> new_art.categories.all() -[] - -Create a new article, with categories, via the form, but use commit=False. -The m2m data won't be saved until save_m2m() is invoked on the form. ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm({'headline': u'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': u'1967-11-01', -... 'writer': unicode(w_royko.pk), 'article': u'Test.', 'categories': [u'1', u'2']}) ->>> new_art = f.save(commit=False) - -# Manually save the instance ->>> new_art.save() ->>> new_art.id -4 - -# The instance doesn't have m2m data yet ->>> new_art = Article.objects.get(id=4) ->>> new_art.categories.all() -[] - -# Save the m2m data on the form ->>> f.save_m2m() ->>> new_art.categories.order_by('name') -[<Category: Entertainment>, <Category: It's a test>] - -Here, we define a custom ModelForm. Because it happens to have the same fields as -the Category model, we can just call the form's save() to apply its changes to an -existing Category instance. ->>> class ShortCategory(ModelForm): -... name = CharField(max_length=5) -... slug = CharField(max_length=5) -... url = CharField(max_length=3) ->>> cat = Category.objects.get(name='Third test') ->>> cat -<Category: Third test> ->>> cat.id -3 ->>> form = ShortCategory({'name': 'Third', 'slug': 'third', 'url': '3rd'}, instance=cat) ->>> form.save() -<Category: Third> ->>> Category.objects.get(id=3) -<Category: Third> - -Here, we demonstrate that choices for a ForeignKey ChoiceField are determined -at runtime, based on the data in the database when the form is displayed, not -the data in the database when the form is instantiated. ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm(auto_id=False) ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" /></li> -<li>Writer: <select name="writer"> -<option value="" selected="selected">---------</option> -<option value="...">Mike Royko</option> -<option value="...">Bob Woodward</option> -</select></li> -<li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> -<li>Status: <select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></li> -<li>Categories: <select multiple="multiple" name="categories"> -<option value="1">Entertainment</option> -<option value="2">It's a test</option> -<option value="3">Third</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> ->>> Category.objects.create(name='Fourth', url='4th') -<Category: Fourth> ->>> Writer.objects.create(name='Carl Bernstein') -<Writer: Carl Bernstein> ->>> print f.as_ul() -<li>Headline: <input type="text" name="headline" maxlength="50" /></li> -<li>Slug: <input type="text" name="slug" maxlength="50" /></li> -<li>Pub date: <input type="text" name="pub_date" /></li> -<li>Writer: <select name="writer"> -<option value="" selected="selected">---------</option> -<option value="...">Mike Royko</option> -<option value="...">Bob Woodward</option> -<option value="...">Carl Bernstein</option> -</select></li> -<li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> -<li>Status: <select name="status"> -<option value="" selected="selected">---------</option> -<option value="1">Draft</option> -<option value="2">Pending</option> -<option value="3">Live</option> -</select></li> -<li>Categories: <select multiple="multiple" name="categories"> -<option value="1">Entertainment</option> -<option value="2">It's a test</option> -<option value="3">Third</option> -<option value="4">Fourth</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> - -# ModelChoiceField ############################################################ - ->>> from django.forms import ModelChoiceField, ModelMultipleChoiceField - ->>> f = ModelChoiceField(Category.objects.all()) ->>> list(f.choices) -[(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')] ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] ->>> f.clean(None) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] ->>> f.clean(0) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] ->>> f.clean(3) -<Category: Third> ->>> f.clean(2) -<Category: It's a test> - -# Add a Category object *after* the ModelChoiceField has already been -# instantiated. This proves clean() checks the database during clean() rather -# than caching it at time of instantiation. ->>> Category.objects.create(name='Fifth', url='5th') -<Category: Fifth> ->>> f.clean(5) -<Category: Fifth> - -# Delete a Category object *after* the ModelChoiceField has already been -# instantiated. This proves clean() checks the database during clean() rather -# than caching it at time of instantiation. ->>> Category.objects.get(url='5th').delete() ->>> f.clean(5) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] - ->>> f = ModelChoiceField(Category.objects.filter(pk=1), required=False) ->>> print f.clean('') -None ->>> f.clean('') ->>> f.clean('1') -<Category: Entertainment> ->>> f.clean('100') -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] - -# queryset can be changed after the field is created. ->>> f.queryset = Category.objects.exclude(name='Fourth') ->>> list(f.choices) -[(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')] ->>> f.clean(3) -<Category: Third> ->>> f.clean(4) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] - -# check that we can safely iterate choices repeatedly ->>> gen_one = list(f.choices) ->>> gen_two = f.choices ->>> gen_one[2] -(2L, u"It's a test") ->>> list(gen_two) -[(u'', u'---------'), (1L, u'Entertainment'), (2L, u"It's a test"), (3L, u'Third')] - -# check that we can override the label_from_instance method to print custom labels (#4620) ->>> f.queryset = Category.objects.all() ->>> f.label_from_instance = lambda obj: "category " + str(obj) ->>> list(f.choices) -[(u'', u'---------'), (1L, 'category Entertainment'), (2L, "category It's a test"), (3L, 'category Third'), (4L, 'category Fourth')] - -# ModelMultipleChoiceField #################################################### - ->>> f = ModelMultipleChoiceField(Category.objects.all()) ->>> list(f.choices) -[(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')] ->>> f.clean(None) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] ->>> f.clean([]) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] ->>> f.clean([1]) -[<Category: Entertainment>] ->>> f.clean([2]) -[<Category: It's a test>] ->>> f.clean(['1']) -[<Category: Entertainment>] ->>> f.clean(['1', '2']) -[<Category: Entertainment>, <Category: It's a test>] ->>> f.clean([1, '2']) -[<Category: Entertainment>, <Category: It's a test>] ->>> f.clean((1, '2')) -[<Category: Entertainment>, <Category: It's a test>] ->>> f.clean(['100']) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 100 is not one of the available choices.'] ->>> f.clean('hello') -Traceback (most recent call last): -... -ValidationError: [u'Enter a list of values.'] ->>> f.clean(['fail']) -Traceback (most recent call last): -... -ValidationError: [u'"fail" is not a valid value for a primary key.'] - -# Add a Category object *after* the ModelMultipleChoiceField has already been -# instantiated. This proves clean() checks the database during clean() rather -# than caching it at time of instantiation. ->>> Category.objects.create(id=6, name='Sixth', url='6th') -<Category: Sixth> ->>> f.clean([6]) -[<Category: Sixth>] - -# Delete a Category object *after* the ModelMultipleChoiceField has already been -# instantiated. This proves clean() checks the database during clean() rather -# than caching it at time of instantiation. ->>> Category.objects.get(url='6th').delete() ->>> f.clean([6]) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 6 is not one of the available choices.'] - ->>> f = ModelMultipleChoiceField(Category.objects.all(), required=False) ->>> f.clean([]) -[] ->>> f.clean(()) -[] ->>> f.clean(['10']) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] ->>> f.clean(['3', '10']) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] ->>> f.clean(['1', '10']) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] - -# queryset can be changed after the field is created. ->>> f.queryset = Category.objects.exclude(name='Fourth') ->>> list(f.choices) -[(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')] ->>> f.clean([3]) -[<Category: Third>] ->>> f.clean([4]) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] ->>> f.clean(['3', '4']) -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] - ->>> f.queryset = Category.objects.all() ->>> f.label_from_instance = lambda obj: "multicategory " + str(obj) ->>> list(f.choices) -[(1L, 'multicategory Entertainment'), (2L, "multicategory It's a test"), (3L, 'multicategory Third'), (4L, 'multicategory Fourth')] - -# OneToOneField ############################################################### - ->>> class ImprovedArticleForm(ModelForm): -... class Meta: -... model = ImprovedArticle ->>> ImprovedArticleForm.base_fields.keys() -['article'] - ->>> class ImprovedArticleWithParentLinkForm(ModelForm): -... class Meta: -... model = ImprovedArticleWithParentLink ->>> ImprovedArticleWithParentLinkForm.base_fields.keys() -[] - ->>> bw = BetterWriter(name=u'Joe Better', score=10) ->>> bw.save() ->>> sorted(model_to_dict(bw).keys()) -['id', 'name', 'score', 'writer_ptr'] - ->>> class BetterWriterForm(ModelForm): -... class Meta: -... model = BetterWriter ->>> form = BetterWriterForm({'name': 'Some Name', 'score': 12}) ->>> form.is_valid() -True ->>> bw2 = form.save() ->>> bw2.delete() - - ->>> class WriterProfileForm(ModelForm): -... class Meta: -... model = WriterProfile ->>> form = WriterProfileForm() ->>> print form.as_p() -<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer"> -<option value="" selected="selected">---------</option> -<option value="...">Mike Royko</option> -<option value="...">Bob Woodward</option> -<option value="...">Carl Bernstein</option> -<option value="...">Joe Better</option> -</select></p> -<p><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></p> - ->>> data = { -... 'writer': unicode(w_woodward.pk), -... 'age': u'65', -... } ->>> form = WriterProfileForm(data) ->>> instance = form.save() ->>> instance -<WriterProfile: Bob Woodward is 65> - ->>> form = WriterProfileForm(instance=instance) ->>> print form.as_p() -<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer"> -<option value="">---------</option> -<option value="...">Mike Royko</option> -<option value="..." selected="selected">Bob Woodward</option> -<option value="...">Carl Bernstein</option> -<option value="...">Joe Better</option> -</select></p> -<p><label for="id_age">Age:</label> <input type="text" name="age" value="65" id="id_age" /></p> - -# PhoneNumberField ############################################################ - ->>> class PhoneNumberForm(ModelForm): -... class Meta: -... model = PhoneNumber ->>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'}) ->>> f.is_valid() -True ->>> f.cleaned_data['phone'] -u'312-555-1212' ->>> f.cleaned_data['description'] -u'Assistance' - -# FileField ################################################################### - -# File forms. - ->>> class TextFileForm(ModelForm): -... class Meta: -... model = TextFile - -# Test conditions when files is either not given or empty. - ->>> f = TextFileForm(data={'description': u'Assistance'}) ->>> f.is_valid() -False ->>> f = TextFileForm(data={'description': u'Assistance'}, files={}) ->>> f.is_valid() -False - -# Upload a file and ensure it all works as expected. - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test1.txt', 'hello world')}) ->>> f.is_valid() -True ->>> type(f.cleaned_data['file']) -<class 'django.core.files.uploadedfile.SimpleUploadedFile'> ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test1.txt> - ->>> instance.file.delete() - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test1.txt', 'hello world')}) ->>> f.is_valid() -True ->>> type(f.cleaned_data['file']) -<class 'django.core.files.uploadedfile.SimpleUploadedFile'> ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test1.txt> - -# Check if the max_length attribute has been inherited from the model. ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test-maxlength.txt', 'hello world')}) ->>> f.is_valid() -False - -# Edit an instance that already has the file defined in the model. This will not -# save the file again, but leave it exactly as it is. - ->>> f = TextFileForm(data={'description': u'Assistance'}, instance=instance) ->>> f.is_valid() -True ->>> f.cleaned_data['file'] -<FieldFile: tests/test1.txt> ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test1.txt> - -# Delete the current file since this is not done by Django. ->>> instance.file.delete() - -# Override the file by uploading a new one. - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test2.txt', 'hello world')}, instance=instance) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test2.txt> - -# Delete the current file since this is not done by Django. ->>> instance.file.delete() - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test2.txt', 'hello world')}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test2.txt> - -# Delete the current file since this is not done by Django. ->>> instance.file.delete() - ->>> instance.delete() - -# Test the non-required FileField ->>> f = TextFileForm(data={'description': u'Assistance'}) ->>> f.fields['file'].required = False ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.file -<FieldFile: None> - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test3.txt', 'hello world')}, instance=instance) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test3.txt> - -# Instance can be edited w/out re-uploading the file and existing file should be preserved. - ->>> f = TextFileForm(data={'description': u'New Description'}, instance=instance) ->>> f.fields['file'].required = False ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.description -u'New Description' ->>> instance.file -<FieldFile: tests/test3.txt> - -# Delete the current file since this is not done by Django. ->>> instance.file.delete() ->>> instance.delete() - ->>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test3.txt', 'hello world')}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.file -<FieldFile: tests/test3.txt> - -# Delete the current file since this is not done by Django. ->>> instance.file.delete() ->>> instance.delete() - -# BigIntegerField ################################################################ ->>> class BigIntForm(forms.ModelForm): -... class Meta: -... model = BigInt -... ->>> bif = BigIntForm({'biggie': '-9223372036854775808'}) ->>> bif.is_valid() -True ->>> bif = BigIntForm({'biggie': '-9223372036854775809'}) ->>> bif.is_valid() -False ->>> bif.errors -{'biggie': [u'Ensure this value is greater than or equal to -9223372036854775808.']} ->>> bif = BigIntForm({'biggie': '9223372036854775807'}) ->>> bif.is_valid() -True ->>> bif = BigIntForm({'biggie': '9223372036854775808'}) ->>> bif.is_valid() -False ->>> bif.errors -{'biggie': [u'Ensure this value is less than or equal to 9223372036854775807.']} -"""} - -if test_images: - __test__['API_TESTS'] += """ -# ImageField ################################################################### - -# ImageField and FileField are nearly identical, but they differ slighty when -# it comes to validation. This specifically tests that #6302 is fixed for -# both file fields and image fields. - ->>> class ImageFileForm(ModelForm): -... class Meta: -... model = ImageFile - ->>> image_data = open(os.path.join(os.path.dirname(__file__), "test.png"), 'rb').read() ->>> image_data2 = open(os.path.join(os.path.dirname(__file__), "test2.png"), 'rb').read() - ->>> f = ImageFileForm(data={'description': u'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)}) ->>> f.is_valid() -True ->>> type(f.cleaned_data['image']) -<class 'django.core.files.uploadedfile.SimpleUploadedFile'> ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test.png> ->>> instance.width -16 ->>> instance.height -16 - -# Delete the current file since this is not done by Django, but don't save -# because the dimension fields are not null=True. ->>> instance.image.delete(save=False) - ->>> f = ImageFileForm(data={'description': u'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)}) ->>> f.is_valid() -True ->>> type(f.cleaned_data['image']) -<class 'django.core.files.uploadedfile.SimpleUploadedFile'> ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test.png> ->>> instance.width -16 ->>> instance.height -16 - -# Edit an instance that already has the (required) image defined in the model. This will not -# save the image again, but leave it exactly as it is. - ->>> f = ImageFileForm(data={'description': u'Look, it changed'}, instance=instance) ->>> f.is_valid() -True ->>> f.cleaned_data['image'] -<...FieldFile: tests/test.png> ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test.png> ->>> instance.height -16 ->>> instance.width -16 - -# Delete the current file since this is not done by Django, but don't save -# because the dimension fields are not null=True. ->>> instance.image.delete(save=False) - -# Override the file by uploading a new one. - ->>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)}, instance=instance) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test2.png> ->>> instance.height -32 ->>> instance.width -48 - -# Delete the current file since this is not done by Django, but don't save -# because the dimension fields are not null=True. ->>> instance.image.delete(save=False) ->>> instance.delete() - ->>> f = ImageFileForm(data={'description': u'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test2.png> ->>> instance.height -32 ->>> instance.width -48 - -# Delete the current file since this is not done by Django, but don't save -# because the dimension fields are not null=True. ->>> instance.image.delete(save=False) ->>> instance.delete() - -# Test the non-required ImageField - ->>> class OptionalImageFileForm(ModelForm): -... class Meta: -... model = OptionalImageFile - ->>> f = OptionalImageFileForm(data={'description': u'Test'}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: None> ->>> instance.width ->>> instance.height - ->>> f = OptionalImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test3.png', image_data)}, instance=instance) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test3.png> ->>> instance.width -16 ->>> instance.height -16 - -# Editing the instance without re-uploading the image should not affect the image or its width/height properties ->>> f = OptionalImageFileForm(data={'description': u'New Description'}, instance=instance) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.description -u'New Description' ->>> instance.image -<...FieldFile: tests/test3.png> ->>> instance.width -16 ->>> instance.height -16 - -# Delete the current file since this is not done by Django. ->>> instance.image.delete() ->>> instance.delete() - ->>> f = OptionalImageFileForm(data={'description': u'And a final one'}, files={'image': SimpleUploadedFile('test4.png', image_data2)}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: tests/test4.png> ->>> instance.width -48 ->>> instance.height -32 ->>> instance.delete() - -# Test callable upload_to behavior that's dependent on the value of another field in the model ->>> f = ImageFileForm(data={'description': u'And a final one', 'path': 'foo'}, files={'image': SimpleUploadedFile('test4.png', image_data)}) ->>> f.is_valid() -True ->>> instance = f.save() ->>> instance.image -<...FieldFile: foo/test4.png> ->>> instance.delete() -""" - -__test__['API_TESTS'] += """ - -# Media on a ModelForm ######################################################## - -# Similar to a regular Form class you can define custom media to be used on -# the ModelForm. - ->>> class ModelFormWithMedia(ModelForm): -... class Media: -... js = ('/some/form/javascript',) -... css = { -... 'all': ('/some/form/css',) -... } -... class Meta: -... model = PhoneNumber ->>> f = ModelFormWithMedia() ->>> print f.media -<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/some/form/javascript"></script> - ->>> class CommaSeparatedIntegerForm(ModelForm): -... class Meta: -... model = CommaSeparatedInteger - ->>> f = CommaSeparatedIntegerForm({'field': '1,2,3'}) ->>> f.is_valid() -True ->>> f.cleaned_data -{'field': u'1,2,3'} ->>> f = CommaSeparatedIntegerForm({'field': '1a,2'}) ->>> f.errors -{'field': [u'Enter only digits separated by commas.']} ->>> f = CommaSeparatedIntegerForm({'field': ',,,,'}) ->>> f.is_valid() -True ->>> f.cleaned_data -{'field': u',,,,'} ->>> f = CommaSeparatedIntegerForm({'field': '1.2'}) ->>> f.errors -{'field': [u'Enter only digits separated by commas.']} ->>> f = CommaSeparatedIntegerForm({'field': '1,a,2'}) ->>> f.errors -{'field': [u'Enter only digits separated by commas.']} ->>> f = CommaSeparatedIntegerForm({'field': '1,,2'}) ->>> f.is_valid() -True ->>> f.cleaned_data -{'field': u'1,,2'} ->>> f = CommaSeparatedIntegerForm({'field': '1'}) ->>> f.is_valid() -True ->>> f.cleaned_data -{'field': u'1'} - -This Price instance generated by this form is not valid because the quantity -field is required, but the form is valid because the field is excluded from -the form. This is for backwards compatibility. - ->>> class PriceForm(ModelForm): -... class Meta: -... model = Price -... exclude = ('quantity',) ->>> form = PriceForm({'price': '6.00'}) ->>> form.is_valid() -True ->>> price = form.save(commit=False) ->>> price.full_clean() -Traceback (most recent call last): - ... -ValidationError: {'quantity': [u'This field cannot be null.']} - -The form should not validate fields that it doesn't contain even if they are -specified using 'fields', not 'exclude'. -... class Meta: -... model = Price -... fields = ('price',) ->>> form = PriceForm({'price': '6.00'}) ->>> form.is_valid() -True - -The form should still have an instance of a model that is not complete and -not saved into a DB yet. - ->>> form.instance.price -Decimal('6.00') ->>> form.instance.quantity is None -True ->>> form.instance.pk is None -True - -# Choices on CharField and IntegerField ->>> class ArticleForm(ModelForm): -... class Meta: -... model = Article ->>> f = ArticleForm() ->>> f.fields['status'].clean('42') -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. 42 is not one of the available choices.'] - ->>> class ArticleStatusForm(ModelForm): -... class Meta: -... model = ArticleStatus ->>> f = ArticleStatusForm() ->>> f.fields['status'].clean('z') -Traceback (most recent call last): -... -ValidationError: [u'Select a valid choice. z is not one of the available choices.'] - -# Foreign keys which use to_field ############################################# - ->>> apple = Inventory.objects.create(barcode=86, name='Apple') ->>> pear = Inventory.objects.create(barcode=22, name='Pear') ->>> core = Inventory.objects.create(barcode=87, name='Core', parent=apple) - ->>> field = ModelChoiceField(Inventory.objects.all(), to_field_name='barcode') ->>> for choice in field.choices: -... print choice -(u'', u'---------') -(86, u'Apple') -(22, u'Pear') -(87, u'Core') - ->>> class InventoryForm(ModelForm): -... class Meta: -... model = Inventory ->>> form = InventoryForm(instance=core) ->>> print form['parent'] -<select name="parent" id="id_parent"> -<option value="">---------</option> -<option value="86" selected="selected">Apple</option> -<option value="22">Pear</option> -<option value="87">Core</option> -</select> - ->>> data = model_to_dict(core) ->>> data['parent'] = '22' ->>> form = InventoryForm(data=data, instance=core) ->>> core = form.save() ->>> core.parent -<Inventory: Pear> - ->>> class CategoryForm(ModelForm): -... description = forms.CharField() -... class Meta: -... model = Category -... fields = ['description', 'url'] - ->>> CategoryForm.base_fields.keys() -['description', 'url'] - ->>> print CategoryForm() -<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr> -<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> - -# Model field that returns None to exclude itself with explicit fields ######## - ->>> class CustomFieldForExclusionForm(ModelForm): -... class Meta: -... model = CustomFieldForExclusionModel -... fields = ['name', 'markup'] - ->>> CustomFieldForExclusionForm.base_fields.keys() -['name'] - ->>> print CustomFieldForExclusionForm() -<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr> - -# Clean up ->>> import shutil ->>> shutil.rmtree(temp_storage_dir) -""" diff --git a/parts/django/tests/modeltests/model_forms/test.png b/parts/django/tests/modeltests/model_forms/test.png Binary files differdeleted file mode 100644 index 4f17cd0..0000000 --- a/parts/django/tests/modeltests/model_forms/test.png +++ /dev/null diff --git a/parts/django/tests/modeltests/model_forms/test2.png b/parts/django/tests/modeltests/model_forms/test2.png Binary files differdeleted file mode 100644 index 10702f7..0000000 --- a/parts/django/tests/modeltests/model_forms/test2.png +++ /dev/null diff --git a/parts/django/tests/modeltests/model_forms/tests.py b/parts/django/tests/modeltests/model_forms/tests.py deleted file mode 100644 index c5647c7..0000000 --- a/parts/django/tests/modeltests/model_forms/tests.py +++ /dev/null @@ -1,185 +0,0 @@ -import datetime -from django.test import TestCase -from django import forms -from models import Category, Writer, Book, DerivedBook, Post -from mforms import (ProductForm, PriceForm, BookForm, DerivedBookForm, - ExplicitPKForm, PostForm, DerivedPostForm, CustomWriterForm) - - -class IncompleteCategoryFormWithFields(forms.ModelForm): - """ - A form that replaces the model's url field with a custom one. This should - prevent the model field's validation from being called. - """ - url = forms.CharField(required=False) - - class Meta: - fields = ('name', 'slug') - model = Category - -class IncompleteCategoryFormWithExclude(forms.ModelForm): - """ - A form that replaces the model's url field with a custom one. This should - prevent the model field's validation from being called. - """ - url = forms.CharField(required=False) - - class Meta: - exclude = ['url'] - model = Category - - -class ValidationTest(TestCase): - def test_validates_with_replaced_field_not_specified(self): - form = IncompleteCategoryFormWithFields(data={'name': 'some name', 'slug': 'some-slug'}) - assert form.is_valid() - - def test_validates_with_replaced_field_excluded(self): - form = IncompleteCategoryFormWithExclude(data={'name': 'some name', 'slug': 'some-slug'}) - assert form.is_valid() - - def test_notrequired_overrides_notblank(self): - form = CustomWriterForm({}) - assert form.is_valid() - -# unique/unique_together validation -class UniqueTest(TestCase): - def setUp(self): - self.writer = Writer.objects.create(name='Mike Royko') - - def test_simple_unique(self): - form = ProductForm({'slug': 'teddy-bear-blue'}) - self.assertTrue(form.is_valid()) - obj = form.save() - form = ProductForm({'slug': 'teddy-bear-blue'}) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['slug'], [u'Product with this Slug already exists.']) - form = ProductForm({'slug': 'teddy-bear-blue'}, instance=obj) - self.assertTrue(form.is_valid()) - - def test_unique_together(self): - """ModelForm test of unique_together constraint""" - form = PriceForm({'price': '6.00', 'quantity': '1'}) - self.assertTrue(form.is_valid()) - form.save() - form = PriceForm({'price': '6.00', 'quantity': '1'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['__all__'], [u'Price with this Price and Quantity already exists.']) - - def test_unique_null(self): - title = 'I May Be Wrong But I Doubt It' - form = BookForm({'title': title, 'author': self.writer.pk}) - self.assertTrue(form.is_valid()) - form.save() - form = BookForm({'title': title, 'author': self.writer.pk}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['__all__'], [u'Book with this Title and Author already exists.']) - form = BookForm({'title': title}) - self.assertTrue(form.is_valid()) - form.save() - form = BookForm({'title': title}) - self.assertTrue(form.is_valid()) - - def test_inherited_unique(self): - title = 'Boss' - Book.objects.create(title=title, author=self.writer, special_id=1) - form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'special_id': u'1', 'isbn': '12345'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['special_id'], [u'Book with this Special id already exists.']) - - def test_inherited_unique_together(self): - title = 'Boss' - form = BookForm({'title': title, 'author': self.writer.pk}) - self.assertTrue(form.is_valid()) - form.save() - form = DerivedBookForm({'title': title, 'author': self.writer.pk, 'isbn': '12345'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['__all__'], [u'Book with this Title and Author already exists.']) - - def test_abstract_inherited_unique(self): - title = 'Boss' - isbn = '12345' - dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) - form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'isbn': isbn}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['isbn'], [u'Derived book with this Isbn already exists.']) - - def test_abstract_inherited_unique_together(self): - title = 'Boss' - isbn = '12345' - dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) - form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'isbn': '9876', 'suffix1': u'0', 'suffix2': u'0'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['__all__'], [u'Derived book with this Suffix1 and Suffix2 already exists.']) - - def test_explicitpk_unspecified(self): - """Test for primary_key being in the form and failing validation.""" - form = ExplicitPKForm({'key': u'', 'desc': u'' }) - self.assertFalse(form.is_valid()) - - def test_explicitpk_unique(self): - """Ensure keys and blank character strings are tested for uniqueness.""" - form = ExplicitPKForm({'key': u'key1', 'desc': u''}) - self.assertTrue(form.is_valid()) - form.save() - form = ExplicitPKForm({'key': u'key1', 'desc': u''}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 3) - self.assertEqual(form.errors['__all__'], [u'Explicit pk with this Key and Desc already exists.']) - self.assertEqual(form.errors['desc'], [u'Explicit pk with this Desc already exists.']) - self.assertEqual(form.errors['key'], [u'Explicit pk with this Key already exists.']) - - def test_unique_for_date(self): - p = Post.objects.create(title="Django 1.0 is released", - slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) - form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['title'], [u'Title must be unique for Posted date.']) - form = PostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) - self.assertTrue(form.is_valid()) - form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) - self.assertTrue(form.is_valid()) - form = PostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['slug'], [u'Slug must be unique for Posted year.']) - form = PostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors['subtitle'], [u'Subtitle must be unique for Posted month.']) - form = PostForm({'subtitle': "Finally", "title": "Django 1.0 is released", - "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) - self.assertTrue(form.is_valid()) - form = PostForm({'title': "Django 1.0 is released"}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['posted'], [u'This field is required.']) - - def test_inherited_unique_for_date(self): - p = Post.objects.create(title="Django 1.0 is released", - slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) - form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['title'], [u'Title must be unique for Posted date.']) - form = DerivedPostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) - self.assertTrue(form.is_valid()) - form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) - self.assertTrue(form.is_valid()) - form = DerivedPostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) - self.assertFalse(form.is_valid()) - self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['slug'], [u'Slug must be unique for Posted year.']) - form = DerivedPostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors['subtitle'], [u'Subtitle must be unique for Posted month.']) - form = DerivedPostForm({'subtitle': "Finally", "title": "Django 1.0 is released", - "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) - self.assertTrue(form.is_valid()) - diff --git a/parts/django/tests/modeltests/model_formsets/__init__.py b/parts/django/tests/modeltests/model_formsets/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/model_formsets/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/model_formsets/models.py b/parts/django/tests/modeltests/model_formsets/models.py deleted file mode 100644 index 3eca696..0000000 --- a/parts/django/tests/modeltests/model_formsets/models.py +++ /dev/null @@ -1,193 +0,0 @@ -import datetime -from django.db import models - -class Author(models.Model): - name = models.CharField(max_length=100) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class BetterAuthor(Author): - write_speed = models.IntegerField() - -class Book(models.Model): - author = models.ForeignKey(Author) - title = models.CharField(max_length=100) - - class Meta: - unique_together = ( - ('author', 'title'), - ) - ordering = ['id'] - - def __unicode__(self): - return self.title - -class BookWithCustomPK(models.Model): - my_pk = models.DecimalField(max_digits=5, decimal_places=0, primary_key=True) - author = models.ForeignKey(Author) - title = models.CharField(max_length=100) - - def __unicode__(self): - return u'%s: %s' % (self.my_pk, self.title) - -class Editor(models.Model): - name = models.CharField(max_length=100) - -class BookWithOptionalAltEditor(models.Model): - author = models.ForeignKey(Author) - # Optional secondary author - alt_editor = models.ForeignKey(Editor, blank=True, null=True) - title = models.CharField(max_length=100) - - class Meta: - unique_together = ( - ('author', 'title', 'alt_editor'), - ) - - def __unicode__(self): - return self.title - -class AlternateBook(Book): - notes = models.CharField(max_length=100) - - def __unicode__(self): - return u'%s - %s' % (self.title, self.notes) - -class AuthorMeeting(models.Model): - name = models.CharField(max_length=100) - authors = models.ManyToManyField(Author) - created = models.DateField(editable=False) - - def __unicode__(self): - return self.name - -class CustomPrimaryKey(models.Model): - my_pk = models.CharField(max_length=10, primary_key=True) - some_field = models.CharField(max_length=100) - - -# models for inheritance tests. - -class Place(models.Model): - name = models.CharField(max_length=50) - city = models.CharField(max_length=50) - - def __unicode__(self): - return self.name - -class Owner(models.Model): - auto_id = models.AutoField(primary_key=True) - name = models.CharField(max_length=100) - place = models.ForeignKey(Place) - - def __unicode__(self): - return "%s at %s" % (self.name, self.place) - -class Location(models.Model): - place = models.ForeignKey(Place, unique=True) - # this is purely for testing the data doesn't matter here :) - lat = models.CharField(max_length=100) - lon = models.CharField(max_length=100) - -class OwnerProfile(models.Model): - owner = models.OneToOneField(Owner, primary_key=True) - age = models.PositiveIntegerField() - - def __unicode__(self): - return "%s is %d" % (self.owner.name, self.age) - -class Restaurant(Place): - serves_pizza = models.BooleanField() - - def __unicode__(self): - return self.name - -class Product(models.Model): - slug = models.SlugField(unique=True) - - def __unicode__(self): - return self.slug - -class Price(models.Model): - price = models.DecimalField(max_digits=10, decimal_places=2) - quantity = models.PositiveIntegerField() - - def __unicode__(self): - return u"%s for %s" % (self.quantity, self.price) - - class Meta: - unique_together = (('price', 'quantity'),) - -class MexicanRestaurant(Restaurant): - serves_tacos = models.BooleanField() - -class ClassyMexicanRestaurant(MexicanRestaurant): - restaurant = models.OneToOneField(MexicanRestaurant, parent_link=True, primary_key=True) - tacos_are_yummy = models.BooleanField() - -# models for testing unique_together validation when a fk is involved and -# using inlineformset_factory. -class Repository(models.Model): - name = models.CharField(max_length=25) - - def __unicode__(self): - return self.name - -class Revision(models.Model): - repository = models.ForeignKey(Repository) - revision = models.CharField(max_length=40) - - class Meta: - unique_together = (("repository", "revision"),) - - def __unicode__(self): - return u"%s (%s)" % (self.revision, unicode(self.repository)) - -# models for testing callable defaults (see bug #7975). If you define a model -# with a callable default value, you cannot rely on the initial value in a -# form. -class Person(models.Model): - name = models.CharField(max_length=128) - -class Membership(models.Model): - person = models.ForeignKey(Person) - date_joined = models.DateTimeField(default=datetime.datetime.now) - karma = models.IntegerField() - -# models for testing a null=True fk to a parent -class Team(models.Model): - name = models.CharField(max_length=100) - -class Player(models.Model): - team = models.ForeignKey(Team, null=True) - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -# Models for testing custom ModelForm save methods in formsets and inline formsets -class Poet(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class Poem(models.Model): - poet = models.ForeignKey(Poet) - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class Post(models.Model): - title = models.CharField(max_length=50, unique_for_date='posted', blank=True) - slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) - subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) - posted = models.DateField() - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/model_formsets/tests.py b/parts/django/tests/modeltests/model_formsets/tests.py deleted file mode 100644 index c856a5f..0000000 --- a/parts/django/tests/modeltests/model_formsets/tests.py +++ /dev/null @@ -1,1159 +0,0 @@ -import datetime -import re -from datetime import date -from decimal import Decimal - -from django import forms -from django.db import models -from django.forms.models import (_get_foreign_key, inlineformset_factory, - modelformset_factory, modelformset_factory) -from django.test import TestCase - -from modeltests.model_formsets.models import ( - Author, BetterAuthor, Book, BookWithCustomPK, Editor, - BookWithOptionalAltEditor, AlternateBook, AuthorMeeting, CustomPrimaryKey, - Place, Owner, Location, OwnerProfile, Restaurant, Product, Price, - MexicanRestaurant, ClassyMexicanRestaurant, Repository, Revision, - Person, Membership, Team, Player, Poet, Poem, Post) - -class DeletionTests(TestCase): - def test_deletion(self): - PoetFormSet = modelformset_factory(Poet, can_delete=True) - poet = Poet.objects.create(name='test') - data = { - 'form-TOTAL_FORMS': u'1', - 'form-INITIAL_FORMS': u'1', - 'form-MAX_NUM_FORMS': u'0', - 'form-0-id': str(poet.pk), - 'form-0-name': u'test', - 'form-0-DELETE': u'on', - } - formset = PoetFormSet(data, queryset=Poet.objects.all()) - formset.save() - self.assertTrue(formset.is_valid()) - self.assertEqual(Poet.objects.count(), 0) - - def test_add_form_deletion_when_invalid(self): - """ - Make sure that an add form that is filled out, but marked for deletion - doesn't cause validation errors. - """ - PoetFormSet = modelformset_factory(Poet, can_delete=True) - data = { - 'form-TOTAL_FORMS': u'1', - 'form-INITIAL_FORMS': u'0', - 'form-MAX_NUM_FORMS': u'0', - 'form-0-id': u'', - 'form-0-name': u'x' * 1000, - } - formset = PoetFormSet(data, queryset=Poet.objects.all()) - # Make sure this form doesn't pass validation. - self.assertEqual(formset.is_valid(), False) - self.assertEqual(Poet.objects.count(), 0) - - # Then make sure that it *does* pass validation and delete the object, - # even though the data isn't actually valid. - data['form-0-DELETE'] = 'on' - formset = PoetFormSet(data, queryset=Poet.objects.all()) - self.assertEqual(formset.is_valid(), True) - formset.save() - self.assertEqual(Poet.objects.count(), 0) - - def test_change_form_deletion_when_invalid(self): - """ - Make sure that an add form that is filled out, but marked for deletion - doesn't cause validation errors. - """ - PoetFormSet = modelformset_factory(Poet, can_delete=True) - poet = Poet.objects.create(name='test') - data = { - 'form-TOTAL_FORMS': u'1', - 'form-INITIAL_FORMS': u'1', - 'form-MAX_NUM_FORMS': u'0', - 'form-0-id': u'1', - 'form-0-name': u'x' * 1000, - } - formset = PoetFormSet(data, queryset=Poet.objects.all()) - # Make sure this form doesn't pass validation. - self.assertEqual(formset.is_valid(), False) - self.assertEqual(Poet.objects.count(), 1) - - # Then make sure that it *does* pass validation and delete the object, - # even though the data isn't actually valid. - data['form-0-DELETE'] = 'on' - formset = PoetFormSet(data, queryset=Poet.objects.all()) - self.assertEqual(formset.is_valid(), True) - formset.save() - self.assertEqual(Poet.objects.count(), 0) - -class ModelFormsetTest(TestCase): - def test_simple_save(self): - qs = Author.objects.all() - AuthorFormSet = modelformset_factory(Author, extra=3) - - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /><input type="hidden" name="form-0-id" id="id_form-0-id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" maxlength="100" /><input type="hidden" name="form-1-id" id="id_form-1-id" /></p>') - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" maxlength="100" /><input type="hidden" name="form-2-id" id="id_form-2-id" /></p>') - - data = { - 'form-TOTAL_FORMS': '3', # the number of forms rendered - 'form-INITIAL_FORMS': '0', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-name': 'Charles Baudelaire', - 'form-1-name': 'Arthur Rimbaud', - 'form-2-name': '', - } - - formset = AuthorFormSet(data=data, queryset=qs) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 2) - author1, author2 = saved - self.assertEqual(author1, Author.objects.get(name='Charles Baudelaire')) - self.assertEqual(author2, Author.objects.get(name='Arthur Rimbaud')) - - authors = list(Author.objects.order_by('name')) - self.assertEqual(authors, [author2, author1]) - - # Gah! We forgot Paul Verlaine. Let's create a formset to edit the - # existing authors with an extra form to add him. We *could* pass in a - # queryset to restrict the Author objects we edit, but in this case - # we'll use it to display them in alphabetical order by name. - - qs = Author.objects.order_by('name') - AuthorFormSet = modelformset_factory(Author, extra=1, can_delete=False) - - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Arthur Rimbaud" maxlength="100" /><input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /></p>' % author2.id) - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" value="Charles Baudelaire" maxlength="100" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" /></p>' % author1.id) - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" maxlength="100" /><input type="hidden" name="form-2-id" id="id_form-2-id" /></p>') - - data = { - 'form-TOTAL_FORMS': '3', # the number of forms rendered - 'form-INITIAL_FORMS': '2', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-id': str(author2.id), - 'form-0-name': 'Arthur Rimbaud', - 'form-1-id': str(author1.id), - 'form-1-name': 'Charles Baudelaire', - 'form-2-name': 'Paul Verlaine', - } - - formset = AuthorFormSet(data=data, queryset=qs) - self.assertTrue(formset.is_valid()) - - # Only changed or new objects are returned from formset.save() - saved = formset.save() - self.assertEqual(len(saved), 1) - author3 = saved[0] - self.assertEqual(author3, Author.objects.get(name='Paul Verlaine')) - - authors = list(Author.objects.order_by('name')) - self.assertEqual(authors, [author2, author1, author3]) - - # This probably shouldn't happen, but it will. If an add form was - # marked for deletion, make sure we don't save that form. - - qs = Author.objects.order_by('name') - AuthorFormSet = modelformset_factory(Author, extra=1, can_delete=True) - - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 4) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Arthur Rimbaud" maxlength="100" /></p>\n' - '<p><label for="id_form-0-DELETE">Delete:</label> <input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /><input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /></p>' % author2.id) - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" value="Charles Baudelaire" maxlength="100" /></p>\n' - '<p><label for="id_form-1-DELETE">Delete:</label> <input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" /></p>' % author1.id) - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" value="Paul Verlaine" maxlength="100" /></p>\n' - '<p><label for="id_form-2-DELETE">Delete:</label> <input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /><input type="hidden" name="form-2-id" value="%d" id="id_form-2-id" /></p>' % author3.id) - self.assertEqual(formset.forms[3].as_p(), - '<p><label for="id_form-3-name">Name:</label> <input id="id_form-3-name" type="text" name="form-3-name" maxlength="100" /></p>\n' - '<p><label for="id_form-3-DELETE">Delete:</label> <input type="checkbox" name="form-3-DELETE" id="id_form-3-DELETE" /><input type="hidden" name="form-3-id" id="id_form-3-id" /></p>') - - data = { - 'form-TOTAL_FORMS': '4', # the number of forms rendered - 'form-INITIAL_FORMS': '3', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-id': str(author2.id), - 'form-0-name': 'Arthur Rimbaud', - 'form-1-id': str(author1.id), - 'form-1-name': 'Charles Baudelaire', - 'form-2-id': str(author3.id), - 'form-2-name': 'Paul Verlaine', - 'form-3-name': 'Walt Whitman', - 'form-3-DELETE': 'on', - } - - formset = AuthorFormSet(data=data, queryset=qs) - self.assertTrue(formset.is_valid()) - - # No objects were changed or saved so nothing will come back. - - self.assertEqual(formset.save(), []) - - authors = list(Author.objects.order_by('name')) - self.assertEqual(authors, [author2, author1, author3]) - - # Let's edit a record to ensure save only returns that one record. - - data = { - 'form-TOTAL_FORMS': '4', # the number of forms rendered - 'form-INITIAL_FORMS': '3', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-id': str(author2.id), - 'form-0-name': 'Walt Whitman', - 'form-1-id': str(author1.id), - 'form-1-name': 'Charles Baudelaire', - 'form-2-id': str(author3.id), - 'form-2-name': 'Paul Verlaine', - 'form-3-name': '', - 'form-3-DELETE': '', - } - - formset = AuthorFormSet(data=data, queryset=qs) - self.assertTrue(formset.is_valid()) - - # One record has changed. - - saved = formset.save() - self.assertEqual(len(saved), 1) - self.assertEqual(saved[0], Author.objects.get(name='Walt Whitman')) - - def test_commit_false(self): - # Test the behavior of commit=False and save_m2m - - author1 = Author.objects.create(name='Charles Baudelaire') - author2 = Author.objects.create(name='Paul Verlaine') - author3 = Author.objects.create(name='Walt Whitman') - - meeting = AuthorMeeting.objects.create(created=date.today()) - meeting.authors = Author.objects.all() - - # create an Author instance to add to the meeting. - - author4 = Author.objects.create(name=u'John Steinbeck') - - AuthorMeetingFormSet = modelformset_factory(AuthorMeeting, extra=1, can_delete=True) - data = { - 'form-TOTAL_FORMS': '2', # the number of forms rendered - 'form-INITIAL_FORMS': '1', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-id': '1', - 'form-0-name': '2nd Tuesday of the Week Meeting', - 'form-0-authors': [2, 1, 3, 4], - 'form-1-name': '', - 'form-1-authors': '', - 'form-1-DELETE': '', - } - formset = AuthorMeetingFormSet(data=data, queryset=AuthorMeeting.objects.all()) - self.assertTrue(formset.is_valid()) - - instances = formset.save(commit=False) - for instance in instances: - instance.created = date.today() - instance.save() - formset.save_m2m() - self.assertQuerysetEqual(instances[0].authors.all(), [ - '<Author: Charles Baudelaire>', - '<Author: John Steinbeck>', - '<Author: Paul Verlaine>', - '<Author: Walt Whitman>', - ]) - - def test_max_num(self): - # Test the behavior of max_num with model formsets. It should allow - # all existing related objects/inlines for a given object to be - # displayed, but not allow the creation of new inlines beyond max_num. - - author1 = Author.objects.create(name='Charles Baudelaire') - author2 = Author.objects.create(name='Paul Verlaine') - author3 = Author.objects.create(name='Walt Whitman') - - qs = Author.objects.order_by('name') - - AuthorFormSet = modelformset_factory(Author, max_num=None, extra=3) - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 6) - self.assertEqual(len(formset.extra_forms), 3) - - AuthorFormSet = modelformset_factory(Author, max_num=4, extra=3) - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 4) - self.assertEqual(len(formset.extra_forms), 1) - - AuthorFormSet = modelformset_factory(Author, max_num=0, extra=3) - formset = AuthorFormSet(queryset=qs) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(len(formset.extra_forms), 0) - - AuthorFormSet = modelformset_factory(Author, max_num=None) - formset = AuthorFormSet(queryset=qs) - self.assertQuerysetEqual(formset.get_queryset(), [ - '<Author: Charles Baudelaire>', - '<Author: Paul Verlaine>', - '<Author: Walt Whitman>', - ]) - - AuthorFormSet = modelformset_factory(Author, max_num=0) - formset = AuthorFormSet(queryset=qs) - self.assertQuerysetEqual(formset.get_queryset(), [ - '<Author: Charles Baudelaire>', - '<Author: Paul Verlaine>', - '<Author: Walt Whitman>', - ]) - - AuthorFormSet = modelformset_factory(Author, max_num=4) - formset = AuthorFormSet(queryset=qs) - self.assertQuerysetEqual(formset.get_queryset(), [ - '<Author: Charles Baudelaire>', - '<Author: Paul Verlaine>', - '<Author: Walt Whitman>', - ]) - - def test_custom_save_method(self): - class PoetForm(forms.ModelForm): - def save(self, commit=True): - # change the name to "Vladimir Mayakovsky" just to be a jerk. - author = super(PoetForm, self).save(commit=False) - author.name = u"Vladimir Mayakovsky" - if commit: - author.save() - return author - - PoetFormSet = modelformset_factory(Poet, form=PoetForm) - - data = { - 'form-TOTAL_FORMS': '3', # the number of forms rendered - 'form-INITIAL_FORMS': '0', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-name': 'Walt Whitman', - 'form-1-name': 'Charles Baudelaire', - 'form-2-name': '', - } - - qs = Poet.objects.all() - formset = PoetFormSet(data=data, queryset=qs) - self.assertTrue(formset.is_valid()) - - poets = formset.save() - self.assertEqual(len(poets), 2) - poet1, poet2 = poets - self.assertEqual(poet1.name, 'Vladimir Mayakovsky') - self.assertEqual(poet2.name, 'Vladimir Mayakovsky') - - def test_model_inheritance(self): - BetterAuthorFormSet = modelformset_factory(BetterAuthor) - formset = BetterAuthorFormSet() - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /></p>\n' - '<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" name="form-0-write_speed" id="id_form-0-write_speed" /><input type="hidden" name="form-0-author_ptr" id="id_form-0-author_ptr" /></p>') - - data = { - 'form-TOTAL_FORMS': '1', # the number of forms rendered - 'form-INITIAL_FORMS': '0', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-author_ptr': '', - 'form-0-name': 'Ernest Hemingway', - 'form-0-write_speed': '10', - } - - formset = BetterAuthorFormSet(data) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - author1, = saved - self.assertEqual(author1, BetterAuthor.objects.get(name='Ernest Hemingway')) - hemingway_id = BetterAuthor.objects.get(name="Ernest Hemingway").pk - - formset = BetterAuthorFormSet() - self.assertEqual(len(formset.forms), 2) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Ernest Hemingway" maxlength="100" /></p>\n' - '<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" name="form-0-write_speed" value="10" id="id_form-0-write_speed" /><input type="hidden" name="form-0-author_ptr" value="%d" id="id_form-0-author_ptr" /></p>' % hemingway_id) - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" maxlength="100" /></p>\n' - '<p><label for="id_form-1-write_speed">Write speed:</label> <input type="text" name="form-1-write_speed" id="id_form-1-write_speed" /><input type="hidden" name="form-1-author_ptr" id="id_form-1-author_ptr" /></p>') - - data = { - 'form-TOTAL_FORMS': '2', # the number of forms rendered - 'form-INITIAL_FORMS': '1', # the number of forms with initial data - 'form-MAX_NUM_FORMS': '', # the max number of forms - 'form-0-author_ptr': hemingway_id, - 'form-0-name': 'Ernest Hemingway', - 'form-0-write_speed': '10', - 'form-1-author_ptr': '', - 'form-1-name': '', - 'form-1-write_speed': '', - } - - formset = BetterAuthorFormSet(data) - self.assertTrue(formset.is_valid()) - self.assertEqual(formset.save(), []) - - def test_inline_formsets(self): - # We can also create a formset that is tied to a parent model. This is - # how the admin system's edit inline functionality works. - - AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=3) - author = Author.objects.create(name='Charles Baudelaire') - - formset = AuthorBooksFormSet(instance=author) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" maxlength="100" /><input type="hidden" name="book_set-0-author" value="%d" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" id="id_book_set-0-id" /></p>' % author.id) - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="%d" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>' % author.id) - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="%d" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>' % author.id) - - data = { - 'book_set-TOTAL_FORMS': '3', # the number of forms rendered - 'book_set-INITIAL_FORMS': '0', # the number of forms with initial data - 'book_set-MAX_NUM_FORMS': '', # the max number of forms - 'book_set-0-title': 'Les Fleurs du Mal', - 'book_set-1-title': '', - 'book_set-2-title': '', - } - - formset = AuthorBooksFormSet(data, instance=author) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 1) - book1, = saved - self.assertEqual(book1, Book.objects.get(title='Les Fleurs du Mal')) - self.assertQuerysetEqual(author.book_set.all(), ['<Book: Les Fleurs du Mal>']) - - # Now that we've added a book to Charles Baudelaire, let's try adding - # another one. This time though, an edit form will be available for - # every existing book. - - AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2) - author = Author.objects.get(name='Charles Baudelaire') - - formset = AuthorBooksFormSet(instance=author) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-0-author" value="%d" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="%d" id="id_book_set-0-id" /></p>' % (author.id, book1.id)) - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="%d" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>' % author.id) - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="%d" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>' % author.id) - - data = { - 'book_set-TOTAL_FORMS': '3', # the number of forms rendered - 'book_set-INITIAL_FORMS': '1', # the number of forms with initial data - 'book_set-MAX_NUM_FORMS': '', # the max number of forms - 'book_set-0-id': '1', - 'book_set-0-title': 'Les Fleurs du Mal', - 'book_set-1-title': 'Les Paradis Artificiels', - 'book_set-2-title': '', - } - - formset = AuthorBooksFormSet(data, instance=author) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 1) - book2, = saved - self.assertEqual(book2, Book.objects.get(title='Les Paradis Artificiels')) - - # As you can see, 'Les Paradis Artificiels' is now a book belonging to - # Charles Baudelaire. - self.assertQuerysetEqual(author.book_set.order_by('title'), [ - '<Book: Les Fleurs du Mal>', - '<Book: Les Paradis Artificiels>', - ]) - - def test_inline_formsets_save_as_new(self): - # The save_as_new parameter lets you re-associate the data to a new - # instance. This is used in the admin for save_as functionality. - AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2) - author = Author.objects.create(name='Charles Baudelaire') - - data = { - 'book_set-TOTAL_FORMS': '3', # the number of forms rendered - 'book_set-INITIAL_FORMS': '2', # the number of forms with initial data - 'book_set-MAX_NUM_FORMS': '', # the max number of forms - 'book_set-0-id': '1', - 'book_set-0-title': 'Les Fleurs du Mal', - 'book_set-1-id': '2', - 'book_set-1-title': 'Les Paradis Artificiels', - 'book_set-2-title': '', - } - - formset = AuthorBooksFormSet(data, instance=Author(), save_as_new=True) - self.assertTrue(formset.is_valid()) - - new_author = Author.objects.create(name='Charles Baudelaire') - formset = AuthorBooksFormSet(data, instance=new_author, save_as_new=True) - saved = formset.save() - self.assertEqual(len(saved), 2) - book1, book2 = saved - self.assertEqual(book1.title, 'Les Fleurs du Mal') - self.assertEqual(book2.title, 'Les Paradis Artificiels') - - # Test using a custom prefix on an inline formset. - - formset = AuthorBooksFormSet(prefix="test") - self.assertEqual(len(formset.forms), 2) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_test-0-title">Title:</label> <input id="id_test-0-title" type="text" name="test-0-title" maxlength="100" /><input type="hidden" name="test-0-author" id="id_test-0-author" /><input type="hidden" name="test-0-id" id="id_test-0-id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_test-1-title">Title:</label> <input id="id_test-1-title" type="text" name="test-1-title" maxlength="100" /><input type="hidden" name="test-1-author" id="id_test-1-author" /><input type="hidden" name="test-1-id" id="id_test-1-id" /></p>') - - def test_inline_formsets_with_custom_pk(self): - # Test inline formsets where the inline-edited object has a custom - # primary key that is not the fk to the parent object. - - AuthorBooksFormSet2 = inlineformset_factory(Author, BookWithCustomPK, can_delete=False, extra=1) - author = Author.objects.create(pk=1, name='Charles Baudelaire') - - formset = AuthorBooksFormSet2(instance=author) - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_bookwithcustompk_set-0-my_pk">My pk:</label> <input type="text" name="bookwithcustompk_set-0-my_pk" id="id_bookwithcustompk_set-0-my_pk" /></p>\n' - '<p><label for="id_bookwithcustompk_set-0-title">Title:</label> <input id="id_bookwithcustompk_set-0-title" type="text" name="bookwithcustompk_set-0-title" maxlength="100" /><input type="hidden" name="bookwithcustompk_set-0-author" value="1" id="id_bookwithcustompk_set-0-author" /></p>') - - data = { - 'bookwithcustompk_set-TOTAL_FORMS': '1', # the number of forms rendered - 'bookwithcustompk_set-INITIAL_FORMS': '0', # the number of forms with initial data - 'bookwithcustompk_set-MAX_NUM_FORMS': '', # the max number of forms - 'bookwithcustompk_set-0-my_pk': '77777', - 'bookwithcustompk_set-0-title': 'Les Fleurs du Mal', - } - - formset = AuthorBooksFormSet2(data, instance=author) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 1) - book1, = saved - self.assertEqual(book1.pk, 77777) - - book1 = author.bookwithcustompk_set.get() - self.assertEqual(book1.title, 'Les Fleurs du Mal') - - def test_inline_formsets_with_multi_table_inheritance(self): - # Test inline formsets where the inline-edited object uses multi-table - # inheritance, thus has a non AutoField yet auto-created primary key. - - AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1) - author = Author.objects.create(pk=1, name='Charles Baudelaire') - - formset = AuthorBooksFormSet3(instance=author) - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_alternatebook_set-0-title">Title:</label> <input id="id_alternatebook_set-0-title" type="text" name="alternatebook_set-0-title" maxlength="100" /></p>\n' - '<p><label for="id_alternatebook_set-0-notes">Notes:</label> <input id="id_alternatebook_set-0-notes" type="text" name="alternatebook_set-0-notes" maxlength="100" /><input type="hidden" name="alternatebook_set-0-author" value="1" id="id_alternatebook_set-0-author" /><input type="hidden" name="alternatebook_set-0-book_ptr" id="id_alternatebook_set-0-book_ptr" /></p>') - - data = { - 'alternatebook_set-TOTAL_FORMS': '1', # the number of forms rendered - 'alternatebook_set-INITIAL_FORMS': '0', # the number of forms with initial data - 'alternatebook_set-MAX_NUM_FORMS': '', # the max number of forms - 'alternatebook_set-0-title': 'Flowers of Evil', - 'alternatebook_set-0-notes': 'English translation of Les Fleurs du Mal' - } - - formset = AuthorBooksFormSet3(data, instance=author) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 1) - book1, = saved - self.assertEqual(book1.title, 'Flowers of Evil') - self.assertEqual(book1.notes, 'English translation of Les Fleurs du Mal') - - # Test inline formsets where the inline-edited object has a - # unique_together constraint with a nullable member - - AuthorBooksFormSet4 = inlineformset_factory(Author, BookWithOptionalAltEditor, can_delete=False, extra=2) - - data = { - 'bookwithoptionalalteditor_set-TOTAL_FORMS': '2', # the number of forms rendered - 'bookwithoptionalalteditor_set-INITIAL_FORMS': '0', # the number of forms with initial data - 'bookwithoptionalalteditor_set-MAX_NUM_FORMS': '', # the max number of forms - 'bookwithoptionalalteditor_set-0-author': '1', - 'bookwithoptionalalteditor_set-0-title': 'Les Fleurs du Mal', - 'bookwithoptionalalteditor_set-1-author': '1', - 'bookwithoptionalalteditor_set-1-title': 'Les Fleurs du Mal', - } - formset = AuthorBooksFormSet4(data, instance=author) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 2) - book1, book2 = saved - self.assertEqual(book1.author_id, 1) - self.assertEqual(book1.title, 'Les Fleurs du Mal') - self.assertEqual(book2.author_id, 1) - self.assertEqual(book2.title, 'Les Fleurs du Mal') - - def test_inline_formsets_with_custom_save_method(self): - AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2) - author = Author.objects.create(pk=1, name='Charles Baudelaire') - book1 = Book.objects.create(pk=1, author=author, title='Les Paradis Artificiels') - book2 = Book.objects.create(pk=2, author=author, title='Les Fleurs du Mal') - book3 = Book.objects.create(pk=3, author=author, title='Flowers of Evil') - - class PoemForm(forms.ModelForm): - def save(self, commit=True): - # change the name to "Brooklyn Bridge" just to be a jerk. - poem = super(PoemForm, self).save(commit=False) - poem.name = u"Brooklyn Bridge" - if commit: - poem.save() - return poem - - PoemFormSet = inlineformset_factory(Poet, Poem, form=PoemForm) - - data = { - 'poem_set-TOTAL_FORMS': '3', # the number of forms rendered - 'poem_set-INITIAL_FORMS': '0', # the number of forms with initial data - 'poem_set-MAX_NUM_FORMS': '', # the max number of forms - 'poem_set-0-name': 'The Cloud in Trousers', - 'poem_set-1-name': 'I', - 'poem_set-2-name': '', - } - - poet = Poet.objects.create(name='Vladimir Mayakovsky') - formset = PoemFormSet(data=data, instance=poet) - self.assertTrue(formset.is_valid()) - - saved = formset.save() - self.assertEqual(len(saved), 2) - poem1, poem2 = saved - self.assertEqual(poem1.name, 'Brooklyn Bridge') - self.assertEqual(poem2.name, 'Brooklyn Bridge') - - # We can provide a custom queryset to our InlineFormSet: - - custom_qs = Book.objects.order_by('-title') - formset = AuthorBooksFormSet(instance=author, queryset=custom_qs) - self.assertEqual(len(formset.forms), 5) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Paradis Artificiels" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="1" id="id_book_set-0-id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" value="2" id="id_book_set-1-id" /></p>') - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" value="Flowers of Evil" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" value="3" id="id_book_set-2-id" /></p>') - self.assertEqual(formset.forms[3].as_p(), - '<p><label for="id_book_set-3-title">Title:</label> <input id="id_book_set-3-title" type="text" name="book_set-3-title" maxlength="100" /><input type="hidden" name="book_set-3-author" value="1" id="id_book_set-3-author" /><input type="hidden" name="book_set-3-id" id="id_book_set-3-id" /></p>') - self.assertEqual(formset.forms[4].as_p(), - '<p><label for="id_book_set-4-title">Title:</label> <input id="id_book_set-4-title" type="text" name="book_set-4-title" maxlength="100" /><input type="hidden" name="book_set-4-author" value="1" id="id_book_set-4-author" /><input type="hidden" name="book_set-4-id" id="id_book_set-4-id" /></p>') - - data = { - 'book_set-TOTAL_FORMS': '5', # the number of forms rendered - 'book_set-INITIAL_FORMS': '3', # the number of forms with initial data - 'book_set-MAX_NUM_FORMS': '', # the max number of forms - 'book_set-0-id': str(book1.id), - 'book_set-0-title': 'Les Paradis Artificiels', - 'book_set-1-id': str(book2.id), - 'book_set-1-title': 'Les Fleurs du Mal', - 'book_set-2-id': str(book3.id), - 'book_set-2-title': 'Flowers of Evil', - 'book_set-3-title': 'Revue des deux mondes', - 'book_set-4-title': '', - } - formset = AuthorBooksFormSet(data, instance=author, queryset=custom_qs) - self.assertTrue(formset.is_valid()) - - custom_qs = Book.objects.filter(title__startswith='F') - formset = AuthorBooksFormSet(instance=author, queryset=custom_qs) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Flowers of Evil" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="3" id="id_book_set-0-id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>') - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>') - - data = { - 'book_set-TOTAL_FORMS': '3', # the number of forms rendered - 'book_set-INITIAL_FORMS': '1', # the number of forms with initial data - 'book_set-MAX_NUM_FORMS': '', # the max number of forms - 'book_set-0-id': str(book3.id), - 'book_set-0-title': 'Flowers of Evil', - 'book_set-1-title': 'Revue des deux mondes', - 'book_set-2-title': '', - } - formset = AuthorBooksFormSet(data, instance=author, queryset=custom_qs) - self.assertTrue(formset.is_valid()) - - def test_custom_pk(self): - # We need to ensure that it is displayed - - CustomPrimaryKeyFormSet = modelformset_factory(CustomPrimaryKey) - formset = CustomPrimaryKeyFormSet() - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-my_pk">My pk:</label> <input id="id_form-0-my_pk" type="text" name="form-0-my_pk" maxlength="10" /></p>\n' - '<p><label for="id_form-0-some_field">Some field:</label> <input id="id_form-0-some_field" type="text" name="form-0-some_field" maxlength="100" /></p>') - - # Custom primary keys with ForeignKey, OneToOneField and AutoField ############ - - place = Place.objects.create(pk=1, name=u'Giordanos', city=u'Chicago') - - FormSet = inlineformset_factory(Place, Owner, extra=2, can_delete=False) - formset = FormSet(instance=place) - self.assertEqual(len(formset.forms), 2) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" id="id_owner_set-0-auto_id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p>') - - data = { - 'owner_set-TOTAL_FORMS': '2', - 'owner_set-INITIAL_FORMS': '0', - 'owner_set-MAX_NUM_FORMS': '', - 'owner_set-0-auto_id': '', - 'owner_set-0-name': u'Joe Perry', - 'owner_set-1-auto_id': '', - 'owner_set-1-name': '', - } - formset = FormSet(data, instance=place) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - owner, = saved - self.assertEqual(owner.name, 'Joe Perry') - self.assertEqual(owner.place.name, 'Giordanos') - - formset = FormSet(instance=place) - self.assertEqual(len(formset.forms), 3) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" value="Joe Perry" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" value="1" id="id_owner_set-0-auto_id" /></p>') - self.assertEqual(formset.forms[1].as_p(), - '<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p>') - self.assertEqual(formset.forms[2].as_p(), - '<p><label for="id_owner_set-2-name">Name:</label> <input id="id_owner_set-2-name" type="text" name="owner_set-2-name" maxlength="100" /><input type="hidden" name="owner_set-2-place" value="1" id="id_owner_set-2-place" /><input type="hidden" name="owner_set-2-auto_id" id="id_owner_set-2-auto_id" /></p>') - - data = { - 'owner_set-TOTAL_FORMS': '3', - 'owner_set-INITIAL_FORMS': '1', - 'owner_set-MAX_NUM_FORMS': '', - 'owner_set-0-auto_id': u'1', - 'owner_set-0-name': u'Joe Perry', - 'owner_set-1-auto_id': '', - 'owner_set-1-name': u'Jack Berry', - 'owner_set-2-auto_id': '', - 'owner_set-2-name': '', - } - formset = FormSet(data, instance=place) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - owner, = saved - self.assertEqual(owner.name, 'Jack Berry') - self.assertEqual(owner.place.name, 'Giordanos') - - # Ensure a custom primary key that is a ForeignKey or OneToOneField get rendered for the user to choose. - - FormSet = modelformset_factory(OwnerProfile) - formset = FormSet() - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_form-0-owner">Owner:</label> <select name="form-0-owner" id="id_form-0-owner">\n' - '<option value="" selected="selected">---------</option>\n' - '<option value="1">Joe Perry at Giordanos</option>\n' - '<option value="2">Jack Berry at Giordanos</option>\n' - '</select></p>\n' - '<p><label for="id_form-0-age">Age:</label> <input type="text" name="form-0-age" id="id_form-0-age" /></p>') - - owner = Owner.objects.get(name=u'Joe Perry') - FormSet = inlineformset_factory(Owner, OwnerProfile, max_num=1, can_delete=False) - self.assertEqual(FormSet.max_num, 1) - - formset = FormSet(instance=owner) - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" value="1" id="id_ownerprofile-0-owner" /></p>') - - data = { - 'ownerprofile-TOTAL_FORMS': '1', - 'ownerprofile-INITIAL_FORMS': '0', - 'ownerprofile-MAX_NUM_FORMS': '1', - 'ownerprofile-0-owner': '', - 'ownerprofile-0-age': u'54', - } - formset = FormSet(data, instance=owner) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - profile1, = saved - self.assertEqual(profile1.owner, owner) - self.assertEqual(profile1.age, 54) - - formset = FormSet(instance=owner) - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" value="54" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" value="1" id="id_ownerprofile-0-owner" /></p>') - - data = { - 'ownerprofile-TOTAL_FORMS': '1', - 'ownerprofile-INITIAL_FORMS': '1', - 'ownerprofile-MAX_NUM_FORMS': '1', - 'ownerprofile-0-owner': u'1', - 'ownerprofile-0-age': u'55', - } - formset = FormSet(data, instance=owner) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - profile1, = saved - self.assertEqual(profile1.owner, owner) - self.assertEqual(profile1.age, 55) - - def test_unique_true_enforces_max_num_one(self): - # ForeignKey with unique=True should enforce max_num=1 - - place = Place.objects.create(pk=1, name=u'Giordanos', city=u'Chicago') - - FormSet = inlineformset_factory(Place, Location, can_delete=False) - self.assertEqual(FormSet.max_num, 1) - - formset = FormSet(instance=place) - self.assertEqual(len(formset.forms), 1) - self.assertEqual(formset.forms[0].as_p(), - '<p><label for="id_location_set-0-lat">Lat:</label> <input id="id_location_set-0-lat" type="text" name="location_set-0-lat" maxlength="100" /></p>\n' - '<p><label for="id_location_set-0-lon">Lon:</label> <input id="id_location_set-0-lon" type="text" name="location_set-0-lon" maxlength="100" /><input type="hidden" name="location_set-0-place" value="1" id="id_location_set-0-place" /><input type="hidden" name="location_set-0-id" id="id_location_set-0-id" /></p>') - - def test_foreign_keys_in_parents(self): - self.assertEqual(type(_get_foreign_key(Restaurant, Owner)), models.ForeignKey) - self.assertEqual(type(_get_foreign_key(MexicanRestaurant, Owner)), models.ForeignKey) - - def test_unique_validation(self): - FormSet = modelformset_factory(Product, extra=1) - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-slug': 'car-red', - } - formset = FormSet(data) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - product1, = saved - self.assertEqual(product1.slug, 'car-red') - - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-slug': 'car-red', - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{'slug': [u'Product with this Slug already exists.']}]) - - def test_unique_together_validation(self): - FormSet = modelformset_factory(Price, extra=1) - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-price': u'12.00', - 'form-0-quantity': '1', - } - formset = FormSet(data) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - price1, = saved - self.assertEqual(price1.price, Decimal('12.00')) - self.assertEqual(price1.quantity, 1) - - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-price': u'12.00', - 'form-0-quantity': '1', - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{'__all__': [u'Price with this Price and Quantity already exists.']}]) - - def test_unique_together_with_inlineformset_factory(self): - # Also see bug #8882. - - repository = Repository.objects.create(name=u'Test Repo') - FormSet = inlineformset_factory(Repository, Revision, extra=1) - data = { - 'revision_set-TOTAL_FORMS': '1', - 'revision_set-INITIAL_FORMS': '0', - 'revision_set-MAX_NUM_FORMS': '', - 'revision_set-0-repository': repository.pk, - 'revision_set-0-revision': '146239817507f148d448db38840db7c3cbf47c76', - 'revision_set-0-DELETE': '', - } - formset = FormSet(data, instance=repository) - self.assertTrue(formset.is_valid()) - saved = formset.save() - self.assertEqual(len(saved), 1) - revision1, = saved - self.assertEqual(revision1.repository, repository) - self.assertEqual(revision1.revision, '146239817507f148d448db38840db7c3cbf47c76') - - # attempt to save the same revision against against the same repo. - data = { - 'revision_set-TOTAL_FORMS': '1', - 'revision_set-INITIAL_FORMS': '0', - 'revision_set-MAX_NUM_FORMS': '', - 'revision_set-0-repository': repository.pk, - 'revision_set-0-revision': '146239817507f148d448db38840db7c3cbf47c76', - 'revision_set-0-DELETE': '', - } - formset = FormSet(data, instance=repository) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{'__all__': [u'Revision with this Repository and Revision already exists.']}]) - - # unique_together with inlineformset_factory with overridden form fields - # Also see #9494 - - FormSet = inlineformset_factory(Repository, Revision, fields=('revision',), extra=1) - data = { - 'revision_set-TOTAL_FORMS': '1', - 'revision_set-INITIAL_FORMS': '0', - 'revision_set-MAX_NUM_FORMS': '', - 'revision_set-0-repository': repository.pk, - 'revision_set-0-revision': '146239817507f148d448db38840db7c3cbf47c76', - 'revision_set-0-DELETE': '', - } - formset = FormSet(data, instance=repository) - self.assertFalse(formset.is_valid()) - - def test_callable_defaults(self): - # Use of callable defaults (see bug #7975). - - person = Person.objects.create(name='Ringo') - FormSet = inlineformset_factory(Person, Membership, can_delete=False, extra=1) - formset = FormSet(instance=person) - - # Django will render a hidden field for model fields that have a callable - # default. This is required to ensure the value is tested for change correctly - # when determine what extra forms have changed to save. - - self.assertEquals(len(formset.forms), 1) # this formset only has one form - form = formset.forms[0] - now = form.fields['date_joined'].initial() - result = form.as_p() - result = re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?', '__DATETIME__', result) - self.assertEqual(result, - '<p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="__DATETIME__" id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="__DATETIME__" id="initial-membership_set-0-id_membership_set-0-date_joined" /></p>\n' - '<p><label for="id_membership_set-0-karma">Karma:</label> <input type="text" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="1" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p>') - - # test for validation with callable defaults. Validations rely on hidden fields - - data = { - 'membership_set-TOTAL_FORMS': '1', - 'membership_set-INITIAL_FORMS': '0', - 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), - 'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), - 'membership_set-0-karma': '', - } - formset = FormSet(data, instance=person) - self.assertTrue(formset.is_valid()) - - # now test for when the data changes - - one_day_later = now + datetime.timedelta(days=1) - filled_data = { - 'membership_set-TOTAL_FORMS': '1', - 'membership_set-INITIAL_FORMS': '0', - 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined': unicode(one_day_later.strftime('%Y-%m-%d %H:%M:%S')), - 'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), - 'membership_set-0-karma': '', - } - formset = FormSet(filled_data, instance=person) - self.assertFalse(formset.is_valid()) - - # now test with split datetime fields - - class MembershipForm(forms.ModelForm): - date_joined = forms.SplitDateTimeField(initial=now) - class Meta: - model = Membership - def __init__(self, **kwargs): - super(MembershipForm, self).__init__(**kwargs) - self.fields['date_joined'].widget = forms.SplitDateTimeWidget() - - FormSet = inlineformset_factory(Person, Membership, form=MembershipForm, can_delete=False, extra=1) - data = { - 'membership_set-TOTAL_FORMS': '1', - 'membership_set-INITIAL_FORMS': '0', - 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined_0': unicode(now.strftime('%Y-%m-%d')), - 'membership_set-0-date_joined_1': unicode(now.strftime('%H:%M:%S')), - 'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), - 'membership_set-0-karma': '', - } - formset = FormSet(data, instance=person) - self.assertTrue(formset.is_valid()) - - def test_inlineformset_factory_with_null_fk(self): - # inlineformset_factory tests with fk having null=True. see #9462. - # create some data that will exbit the issue - team = Team.objects.create(name=u"Red Vipers") - Player(name="Timmy").save() - Player(name="Bobby", team=team).save() - - PlayerInlineFormSet = inlineformset_factory(Team, Player) - formset = PlayerInlineFormSet() - self.assertQuerysetEqual(formset.get_queryset(), []) - - formset = PlayerInlineFormSet(instance=team) - players = formset.get_queryset() - self.assertEqual(len(players), 1) - player1, = players - self.assertEqual(player1.team, team) - self.assertEqual(player1.name, 'Bobby') - - def test_model_formset_with_custom_pk(self): - # a formset for a Model that has a custom primary key that still needs to be - # added to the formset automatically - FormSet = modelformset_factory(ClassyMexicanRestaurant, fields=["tacos_are_yummy"]) - self.assertEqual(sorted(FormSet().forms[0].fields.keys()), ['restaurant', 'tacos_are_yummy']) - - def test_prevent_duplicates_from_with_the_same_formset(self): - FormSet = modelformset_factory(Product, extra=2) - data = { - 'form-TOTAL_FORMS': 2, - 'form-INITIAL_FORMS': 0, - 'form-MAX_NUM_FORMS': '', - 'form-0-slug': 'red_car', - 'form-1-slug': 'red_car', - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for slug.']) - - FormSet = modelformset_factory(Price, extra=2) - data = { - 'form-TOTAL_FORMS': 2, - 'form-INITIAL_FORMS': 0, - 'form-MAX_NUM_FORMS': '', - 'form-0-price': '25', - 'form-0-quantity': '7', - 'form-1-price': '25', - 'form-1-quantity': '7', - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for price and quantity, which must be unique.']) - - # Only the price field is specified, this should skip any unique checks since - # the unique_together is not fulfilled. This will fail with a KeyError if broken. - FormSet = modelformset_factory(Price, fields=("price",), extra=2) - data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-price': '24', - 'form-1-price': '24', - } - formset = FormSet(data) - self.assertTrue(formset.is_valid()) - - FormSet = inlineformset_factory(Author, Book, extra=0) - author = Author.objects.create(pk=1, name='Charles Baudelaire') - book1 = Book.objects.create(pk=1, author=author, title='Les Paradis Artificiels') - book2 = Book.objects.create(pk=2, author=author, title='Les Fleurs du Mal') - book3 = Book.objects.create(pk=3, author=author, title='Flowers of Evil') - - book_ids = author.book_set.order_by('id').values_list('id', flat=True) - data = { - 'book_set-TOTAL_FORMS': '2', - 'book_set-INITIAL_FORMS': '2', - 'book_set-MAX_NUM_FORMS': '', - - 'book_set-0-title': 'The 2008 Election', - 'book_set-0-author': str(author.id), - 'book_set-0-id': str(book_ids[0]), - - 'book_set-1-title': 'The 2008 Election', - 'book_set-1-author': str(author.id), - 'book_set-1-id': str(book_ids[1]), - } - formset = FormSet(data=data, instance=author) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for title.']) - self.assertEqual(formset.errors, - [{}, {'__all__': u'Please correct the duplicate values below.'}]) - - FormSet = modelformset_factory(Post, extra=2) - data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - - 'form-0-title': 'blah', - 'form-0-slug': 'Morning', - 'form-0-subtitle': 'foo', - 'form-0-posted': '2009-01-01', - 'form-1-title': 'blah', - 'form-1-slug': 'Morning in Prague', - 'form-1-subtitle': 'rawr', - 'form-1-posted': '2009-01-01' - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for title which must be unique for the date in posted.']) - self.assertEqual(formset.errors, - [{}, {'__all__': u'Please correct the duplicate values below.'}]) - - data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - - 'form-0-title': 'foo', - 'form-0-slug': 'Morning in Prague', - 'form-0-subtitle': 'foo', - 'form-0-posted': '2009-01-01', - 'form-1-title': 'blah', - 'form-1-slug': 'Morning in Prague', - 'form-1-subtitle': 'rawr', - 'form-1-posted': '2009-08-02' - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for slug which must be unique for the year in posted.']) - - data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - - 'form-0-title': 'foo', - 'form-0-slug': 'Morning in Prague', - 'form-0-subtitle': 'rawr', - 'form-0-posted': '2008-08-01', - 'form-1-title': 'blah', - 'form-1-slug': 'Prague', - 'form-1-subtitle': 'rawr', - 'form-1-posted': '2009-08-02' - } - formset = FormSet(data) - self.assertFalse(formset.is_valid()) - self.assertEqual(formset._non_form_errors, - [u'Please correct the duplicate data for subtitle which must be unique for the month in posted.']) diff --git a/parts/django/tests/modeltests/model_inheritance/__init__.py b/parts/django/tests/modeltests/model_inheritance/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/model_inheritance/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/model_inheritance/models.py b/parts/django/tests/modeltests/model_inheritance/models.py deleted file mode 100644 index 6cee512..0000000 --- a/parts/django/tests/modeltests/model_inheritance/models.py +++ /dev/null @@ -1,145 +0,0 @@ -""" -XX. Model inheritance - -Model inheritance exists in two varieties: - - abstract base classes which are a way of specifying common - information inherited by the subclasses. They don't exist as a separate - model. - - non-abstract base classes (the default), which are models in their own - right with their own database tables and everything. Their subclasses - have references back to them, created automatically. - -Both styles are demonstrated here. -""" - -from django.db import models - -# -# Abstract base classes -# - -class CommonInfo(models.Model): - name = models.CharField(max_length=50) - age = models.PositiveIntegerField() - - class Meta: - abstract = True - ordering = ['name'] - - def __unicode__(self): - return u'%s %s' % (self.__class__.__name__, self.name) - -class Worker(CommonInfo): - job = models.CharField(max_length=50) - -class Student(CommonInfo): - school_class = models.CharField(max_length=10) - - class Meta: - pass - -class StudentWorker(Student, Worker): - pass - -# -# Abstract base classes with related models -# - -class Post(models.Model): - title = models.CharField(max_length=50) - -class Attachment(models.Model): - post = models.ForeignKey(Post, related_name='attached_%(class)s_set') - content = models.TextField() - - class Meta: - abstract = True - - def __unicode__(self): - return self.content - -class Comment(Attachment): - is_spam = models.BooleanField() - -class Link(Attachment): - url = models.URLField() - -# -# Multi-table inheritance -# - -class Chef(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return u"%s the chef" % self.name - -class Place(models.Model): - name = models.CharField(max_length=50) - address = models.CharField(max_length=80) - - def __unicode__(self): - return u"%s the place" % self.name - -class Rating(models.Model): - rating = models.IntegerField(null=True, blank=True) - - class Meta: - abstract = True - ordering = ['-rating'] - -class Restaurant(Place, Rating): - serves_hot_dogs = models.BooleanField() - serves_pizza = models.BooleanField() - chef = models.ForeignKey(Chef, null=True, blank=True) - - class Meta(Rating.Meta): - db_table = 'my_restaurant' - - def __unicode__(self): - return u"%s the restaurant" % self.name - -class ItalianRestaurant(Restaurant): - serves_gnocchi = models.BooleanField() - - def __unicode__(self): - return u"%s the italian restaurant" % self.name - -class Supplier(Place): - customers = models.ManyToManyField(Restaurant, related_name='provider') - - def __unicode__(self): - return u"%s the supplier" % self.name - -class ParkingLot(Place): - # An explicit link to the parent (we can control the attribute name). - parent = models.OneToOneField(Place, primary_key=True, parent_link=True) - main_site = models.ForeignKey(Place, related_name='lot') - - def __unicode__(self): - return u"%s the parking lot" % self.name - -# -# Abstract base classes with related models where the sub-class has the -# same name in a different app and inherits from the same abstract base -# class. -# NOTE: The actual API tests for the following classes are in -# model_inheritance_same_model_name/models.py - They are defined -# here in order to have the name conflict between apps -# - -class Title(models.Model): - title = models.CharField(max_length=50) - -class NamedURL(models.Model): - title = models.ForeignKey(Title, related_name='attached_%(app_label)s_%(class)s_set') - url = models.URLField() - - class Meta: - abstract = True - -class Copy(NamedURL): - content = models.TextField() - - def __unicode__(self): - return self.content diff --git a/parts/django/tests/modeltests/model_inheritance/tests.py b/parts/django/tests/modeltests/model_inheritance/tests.py deleted file mode 100644 index 80dd0de..0000000 --- a/parts/django/tests/modeltests/model_inheritance/tests.py +++ /dev/null @@ -1,281 +0,0 @@ -from operator import attrgetter - -from django.conf import settings -from django.core.exceptions import FieldError -from django.db import connection -from django.test import TestCase - -from models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, - Post, Restaurant, Student, StudentWorker, Supplier, Worker) - - -class ModelInheritanceTests(TestCase): - def test_abstract(self): - # The Student and Worker models both have 'name' and 'age' fields on - # them and inherit the __unicode__() method, just as with normal Python - # subclassing. This is useful if you want to factor out common - # information for programming purposes, but still completely - # independent separate models at the database level. - w1 = Worker.objects.create(name="Fred", age=35, job="Quarry worker") - w2 = Worker.objects.create(name="Barney", age=34, job="Quarry worker") - - s = Student.objects.create(name="Pebbles", age=5, school_class="1B") - - self.assertEqual(unicode(w1), "Worker Fred") - self.assertEqual(unicode(s), "Student Pebbles") - - # The children inherit the Meta class of their parents (if they don't - # specify their own). - self.assertQuerysetEqual( - Worker.objects.values("name"), [ - {"name": "Barney"}, - {"name": "Fred"}, - ], - lambda o: o - ) - - # Since Student does not subclass CommonInfo's Meta, it has the effect - # of completely overriding it. So ordering by name doesn't take place - # for Students. - self.assertEqual(Student._meta.ordering, []) - - # However, the CommonInfo class cannot be used as a normal model (it - # doesn't exist as a model). - self.assertRaises(AttributeError, lambda: CommonInfo.objects.all()) - - # A StudentWorker which does not exist is both a Student and Worker - # which does not exist. - self.assertRaises(Student.DoesNotExist, - StudentWorker.objects.get, pk=12321321 - ) - self.assertRaises(Worker.DoesNotExist, - StudentWorker.objects.get, pk=12321321 - ) - - # MultipleObjectsReturned is also inherited. - # This is written out "long form", rather than using __init__/create() - # because of a bug with diamond inheritance (#10808) - sw1 = StudentWorker() - sw1.name = "Wilma" - sw1.age = 35 - sw1.save() - sw2 = StudentWorker() - sw2.name = "Betty" - sw2.age = 24 - sw2.save() - - self.assertRaises(Student.MultipleObjectsReturned, - StudentWorker.objects.get, pk__lt=sw2.pk + 100 - ) - self.assertRaises(Worker.MultipleObjectsReturned, - StudentWorker.objects.get, pk__lt=sw2.pk + 100 - ) - - def test_multiple_table(self): - post = Post.objects.create(title="Lorem Ipsum") - # The Post model has distinct accessors for the Comment and Link models. - post.attached_comment_set.create(content="Save $ on V1agr@", is_spam=True) - post.attached_link_set.create( - content="The Web framework for perfections with deadlines.", - url="http://www.djangoproject.com/" - ) - - # The Post model doesn't have an attribute called - # 'attached_%(class)s_set'. - self.assertRaises(AttributeError, - getattr, post, "attached_%(class)s_set" - ) - - # The Place/Restaurant/ItalianRestaurant models all exist as - # independent models. However, the subclasses also have transparent - # access to the fields of their ancestors. - # Create a couple of Places. - p1 = Place.objects.create(name="Master Shakes", address="666 W. Jersey") - p2 = Place.objects.create(name="Ace Harware", address="1013 N. Ashland") - - # Test constructor for Restaurant. - r = Restaurant.objects.create( - name="Demon Dogs", - address="944 W. Fullerton", - serves_hot_dogs=True, - serves_pizza=False, - rating=2 - ) - # Test the constructor for ItalianRestaurant. - c = Chef.objects.create(name="Albert") - ir = ItalianRestaurant.objects.create( - name="Ristorante Miron", - address="1234 W. Ash", - serves_hot_dogs=False, - serves_pizza=False, - serves_gnocchi=True, - rating=4, - chef=c - ) - self.assertQuerysetEqual( - ItalianRestaurant.objects.filter(address="1234 W. Ash"), [ - "Ristorante Miron", - ], - attrgetter("name") - ) - ir.address = "1234 W. Elm" - ir.save() - self.assertQuerysetEqual( - ItalianRestaurant.objects.filter(address="1234 W. Elm"), [ - "Ristorante Miron", - ], - attrgetter("name") - ) - - # Make sure Restaurant and ItalianRestaurant have the right fields in - # the right order. - self.assertEqual( - [f.name for f in Restaurant._meta.fields], - ["id", "name", "address", "place_ptr", "rating", "serves_hot_dogs", "serves_pizza", "chef"] - ) - self.assertEqual( - [f.name for f in ItalianRestaurant._meta.fields], - ["id", "name", "address", "place_ptr", "rating", "serves_hot_dogs", "serves_pizza", "chef", "restaurant_ptr", "serves_gnocchi"], - ) - self.assertEqual(Restaurant._meta.ordering, ["-rating"]) - - # Even though p.supplier for a Place 'p' (a parent of a Supplier), a - # Restaurant object cannot access that reverse relation, since it's not - # part of the Place-Supplier Hierarchy. - self.assertQuerysetEqual(Place.objects.filter(supplier__name="foo"), []) - self.assertRaises(FieldError, - Restaurant.objects.filter, supplier__name="foo" - ) - - # Parent fields can be used directly in filters on the child model. - self.assertQuerysetEqual( - Restaurant.objects.filter(name="Demon Dogs"), [ - "Demon Dogs", - ], - attrgetter("name") - ) - self.assertQuerysetEqual( - ItalianRestaurant.objects.filter(address="1234 W. Elm"), [ - "Ristorante Miron", - ], - attrgetter("name") - ) - - # Filters against the parent model return objects of the parent's type. - p = Place.objects.get(name="Demon Dogs") - self.assertTrue(type(p) is Place) - - # Since the parent and child are linked by an automatically created - # OneToOneField, you can get from the parent to the child by using the - # child's name. - self.assertEqual( - p.restaurant, Restaurant.objects.get(name="Demon Dogs") - ) - self.assertEqual( - Place.objects.get(name="Ristorante Miron").restaurant.italianrestaurant, - ItalianRestaurant.objects.get(name="Ristorante Miron") - ) - self.assertEqual( - Restaurant.objects.get(name="Ristorante Miron").italianrestaurant, - ItalianRestaurant.objects.get(name="Ristorante Miron") - ) - - # This won't work because the Demon Dogs restaurant is not an Italian - # restaurant. - self.assertRaises(ItalianRestaurant.DoesNotExist, - lambda: p.restaurant.italianrestaurant - ) - # An ItalianRestaurant which does not exist is also a Place which does - # not exist. - self.assertRaises(Place.DoesNotExist, - ItalianRestaurant.objects.get, name="The Noodle Void" - ) - # MultipleObjectsReturned is also inherited. - self.assertRaises(Place.MultipleObjectsReturned, - Restaurant.objects.get, id__lt=12321 - ) - - # Related objects work just as they normally do. - s1 = Supplier.objects.create(name="Joe's Chickens", address="123 Sesame St") - s1.customers = [r, ir] - s2 = Supplier.objects.create(name="Luigi's Pasta", address="456 Sesame St") - s2.customers = [ir] - - # This won't work because the Place we select is not a Restaurant (it's - # a Supplier). - p = Place.objects.get(name="Joe's Chickens") - self.assertRaises(Restaurant.DoesNotExist, - lambda: p.restaurant - ) - - self.assertEqual(p.supplier, s1) - self.assertQuerysetEqual( - ir.provider.order_by("-name"), [ - "Luigi's Pasta", - "Joe's Chickens" - ], - attrgetter("name") - ) - self.assertQuerysetEqual( - Restaurant.objects.filter(provider__name__contains="Chickens"), [ - "Ristorante Miron", - "Demon Dogs", - ], - attrgetter("name") - ) - self.assertQuerysetEqual( - ItalianRestaurant.objects.filter(provider__name__contains="Chickens"), [ - "Ristorante Miron", - ], - attrgetter("name"), - ) - - park1 = ParkingLot.objects.create( - name="Main St", address="111 Main St", main_site=s1 - ) - park2 = ParkingLot.objects.create( - name="Well Lit", address="124 Sesame St", main_site=ir - ) - - self.assertEqual( - Restaurant.objects.get(lot__name="Well Lit").name, - "Ristorante Miron" - ) - - # The update() command can update fields in parent and child classes at - # once (although it executed multiple SQL queries to do so). - rows = Restaurant.objects.filter( - serves_hot_dogs=True, name__contains="D" - ).update( - name="Demon Puppies", serves_hot_dogs=False - ) - self.assertEqual(rows, 1) - - r1 = Restaurant.objects.get(pk=r.pk) - self.assertFalse(r1.serves_hot_dogs) - self.assertEqual(r1.name, "Demon Puppies") - - # The values() command also works on fields from parent models. - self.assertQuerysetEqual( - ItalianRestaurant.objects.values("name", "rating"), [ - {"rating": 4, "name": "Ristorante Miron"} - ], - lambda o: o - ) - - # select_related works with fields from the parent object as if they - # were a normal part of the model. - old_DEBUG = settings.DEBUG - try: - settings.DEBUG = True - starting_queries = len(connection.queries) - ItalianRestaurant.objects.all()[0].chef - self.assertEqual(len(connection.queries) - starting_queries, 2) - - starting_queries = len(connection.queries) - ItalianRestaurant.objects.select_related("chef")[0].chef - self.assertEqual(len(connection.queries) - starting_queries, 1) - finally: - settings.DEBUG = old_DEBUG - - diff --git a/parts/django/tests/modeltests/model_inheritance_same_model_name/__init__.py b/parts/django/tests/modeltests/model_inheritance_same_model_name/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/model_inheritance_same_model_name/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/model_inheritance_same_model_name/models.py b/parts/django/tests/modeltests/model_inheritance_same_model_name/models.py deleted file mode 100644 index 40de027..0000000 --- a/parts/django/tests/modeltests/model_inheritance_same_model_name/models.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -XX. Model inheritance - -Model inheritance across apps can result in models with the same name resulting -in the need for an %(app_label)s format string. This app specifically tests -this feature by redefining the Copy model from model_inheritance/models.py -""" - -from django.db import models -from modeltests.model_inheritance.models import NamedURL - -# -# Abstract base classes with related models -# -class Copy(NamedURL): - content = models.TextField() - - def __unicode__(self): - return self.content diff --git a/parts/django/tests/modeltests/model_inheritance_same_model_name/tests.py b/parts/django/tests/modeltests/model_inheritance_same_model_name/tests.py deleted file mode 100644 index 3f1e345..0000000 --- a/parts/django/tests/modeltests/model_inheritance_same_model_name/tests.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.test import TestCase -from modeltests.model_inheritance.models import Title - -class InheritanceSameModelNameTests(TestCase): - - def setUp(self): - # The Title model has distinct accessors for both - # model_inheritance.Copy and model_inheritance_same_model_name.Copy - # models. - self.title = Title.objects.create(title='Lorem Ipsum') - - def test_inheritance_related_name(self): - from modeltests.model_inheritance.models import Copy - self.assertEquals( - self.title.attached_model_inheritance_copy_set.create( - content='Save $ on V1agr@', - url='http://v1agra.com/', - title='V1agra is spam', - ), Copy.objects.get(content='Save $ on V1agr@')) - - def test_inheritance_with_same_model_name(self): - from modeltests.model_inheritance_same_model_name.models import Copy - self.assertEquals( - self.title.attached_model_inheritance_same_model_name_copy_set.create( - content='The Web framework for perfectionists with deadlines.', - url='http://www.djangoproject.com/', - title='Django Rocks' - ), Copy.objects.get(content='The Web framework for perfectionists with deadlines.')) - - def test_related_name_attribute_exists(self): - # The Post model doesn't have an attribute called 'attached_%(app_label)s_%(class)s_set'. - self.assertEqual(hasattr(self.title, 'attached_%(app_label)s_%(class)s_set'), False) diff --git a/parts/django/tests/modeltests/model_package/__init__.py b/parts/django/tests/modeltests/model_package/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/modeltests/model_package/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/modeltests/model_package/models/__init__.py b/parts/django/tests/modeltests/model_package/models/__init__.py deleted file mode 100644 index 91e1b02..0000000 --- a/parts/django/tests/modeltests/model_package/models/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Import all the models from subpackages -from article import Article -from publication import Publication diff --git a/parts/django/tests/modeltests/model_package/models/article.py b/parts/django/tests/modeltests/model_package/models/article.py deleted file mode 100644 index c8fae1c..0000000 --- a/parts/django/tests/modeltests/model_package/models/article.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.db import models -from django.contrib.sites.models import Site - -class Article(models.Model): - sites = models.ManyToManyField(Site) - headline = models.CharField(max_length=100) - publications = models.ManyToManyField("model_package.Publication", null=True, blank=True,) - - class Meta: - app_label = 'model_package' diff --git a/parts/django/tests/modeltests/model_package/models/publication.py b/parts/django/tests/modeltests/model_package/models/publication.py deleted file mode 100644 index 4dc2d6a..0000000 --- a/parts/django/tests/modeltests/model_package/models/publication.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.db import models - -class Publication(models.Model): - title = models.CharField(max_length=30) - - class Meta: - app_label = 'model_package' diff --git a/parts/django/tests/modeltests/model_package/tests.py b/parts/django/tests/modeltests/model_package/tests.py deleted file mode 100644 index e63e2e6..0000000 --- a/parts/django/tests/modeltests/model_package/tests.py +++ /dev/null @@ -1,72 +0,0 @@ -from django.contrib.sites.models import Site -from django.db import models -from django.test import TestCase - -from models.publication import Publication -from models.article import Article - - -class Advertisment(models.Model): - customer = models.CharField(max_length=100) - publications = models.ManyToManyField( - "model_package.Publication", null=True, blank=True - ) - - class Meta: - app_label = 'model_package' - - -class ModelPackageTests(TestCase): - def test_model_packages(self): - p = Publication.objects.create(title="FooBar") - - current_site = Site.objects.get_current() - self.assertEqual(current_site.domain, "example.com") - - # Regression for #12168: models split into subpackages still get M2M - # tables - a = Article.objects.create(headline="a foo headline") - a.publications.add(p) - a.sites.add(current_site) - - a = Article.objects.get(id=a.pk) - self.assertEqual(a.id, a.pk) - self.assertEqual(a.sites.count(), 1) - - # Regression for #12245 - Models can exist in the test package, too - ad = Advertisment.objects.create(customer="Lawrence Journal-World") - ad.publications.add(p) - - ad = Advertisment.objects.get(id=ad.pk) - self.assertEqual(ad.publications.count(), 1) - - # Regression for #12386 - field names on the autogenerated intermediate - # class that are specified as dotted strings don't retain any path - # component for the field or column name - self.assertEqual( - Article.publications.through._meta.fields[1].name, 'article' - ) - self.assertEqual( - Article.publications.through._meta.fields[1].get_attname_column(), - ('article_id', 'article_id') - ) - self.assertEqual( - Article.publications.through._meta.fields[2].name, 'publication' - ) - self.assertEqual( - Article.publications.through._meta.fields[2].get_attname_column(), - ('publication_id', 'publication_id') - ) - - # The oracle backend truncates the name to 'model_package_article_publ233f'. - self.assertTrue( - Article._meta.get_field('publications').m2m_db_table() in ('model_package_article_publications', 'model_package_article_publ233f') - ) - - self.assertEqual( - Article._meta.get_field('publications').m2m_column_name(), 'article_id' - ) - self.assertEqual( - Article._meta.get_field('publications').m2m_reverse_name(), - 'publication_id' - ) diff --git a/parts/django/tests/modeltests/mutually_referential/__init__.py b/parts/django/tests/modeltests/mutually_referential/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/mutually_referential/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/mutually_referential/models.py b/parts/django/tests/modeltests/mutually_referential/models.py deleted file mode 100644 index db05cbc..0000000 --- a/parts/django/tests/modeltests/mutually_referential/models.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -24. Mutually referential many-to-one relationships - -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) - - # Use a simple string for forward declarations. - bestchild = ForeignKey("Child", null=True, related_name="favoured_by") - -class Child(Model): - name = CharField(max_length=100) - - # You can also explicitally specify the related app. - parent = ForeignKey("mutually_referential.Parent") diff --git a/parts/django/tests/modeltests/mutually_referential/tests.py b/parts/django/tests/modeltests/mutually_referential/tests.py deleted file mode 100644 index 101d67c..0000000 --- a/parts/django/tests/modeltests/mutually_referential/tests.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.test import TestCase -from models import Parent, Child - -class MutuallyReferentialTests(TestCase): - - def test_mutually_referential(self): - # Create a Parent - q = Parent(name='Elizabeth') - q.save() - - # Create some children - c = q.child_set.create(name='Charles') - e = q.child_set.create(name='Edward') - - # Set the best child - # No assertion require here; if basic assignment and - # deletion works, the test passes. - q.bestchild = c - q.save() - q.delete() diff --git a/parts/django/tests/modeltests/one_to_one/__init__.py b/parts/django/tests/modeltests/one_to_one/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/one_to_one/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/one_to_one/models.py b/parts/django/tests/modeltests/one_to_one/models.py deleted file mode 100644 index f263735..0000000 --- a/parts/django/tests/modeltests/one_to_one/models.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -10. One-to-one relationships - -To define a one-to-one relationship, use ``OneToOneField()``. - -In this example, a ``Place`` optionally can be a ``Restaurant``. -""" - -from django.db import models, transaction, IntegrityError - -class Place(models.Model): - name = models.CharField(max_length=50) - address = models.CharField(max_length=80) - - def __unicode__(self): - return u"%s the place" % self.name - -class Restaurant(models.Model): - place = models.OneToOneField(Place, primary_key=True) - serves_hot_dogs = models.BooleanField() - serves_pizza = models.BooleanField() - - def __unicode__(self): - return u"%s the restaurant" % self.place.name - -class Waiter(models.Model): - restaurant = models.ForeignKey(Restaurant) - name = models.CharField(max_length=50) - - def __unicode__(self): - return u"%s the waiter at %s" % (self.name, self.restaurant) - -class ManualPrimaryKey(models.Model): - primary_key = models.CharField(max_length=10, primary_key=True) - name = models.CharField(max_length = 50) - -class RelatedModel(models.Model): - link = models.OneToOneField(ManualPrimaryKey) - name = models.CharField(max_length = 50) - -class MultiModel(models.Model): - link1 = models.OneToOneField(Place) - link2 = models.OneToOneField(ManualPrimaryKey) - name = models.CharField(max_length=50) - - def __unicode__(self): - return u"Multimodel %s" % self.name diff --git a/parts/django/tests/modeltests/one_to_one/tests.py b/parts/django/tests/modeltests/one_to_one/tests.py deleted file mode 100644 index c3e1704..0000000 --- a/parts/django/tests/modeltests/one_to_one/tests.py +++ /dev/null @@ -1,119 +0,0 @@ -from django.test import TestCase -from django.db import transaction, IntegrityError -from models import Place, Restaurant, Waiter, ManualPrimaryKey, RelatedModel, MultiModel - -class OneToOneTests(TestCase): - - def setUp(self): - self.p1 = Place(name='Demon Dogs', address='944 W. Fullerton') - self.p1.save() - self.p2 = Place(name='Ace Hardware', address='1013 N. Ashland') - self.p2.save() - self.r = Restaurant(place=self.p1, serves_hot_dogs=True, serves_pizza=False) - self.r.save() - - def test_getter(self): - # A Restaurant can access its place. - self.assertEqual(repr(self.r.place), '<Place: Demon Dogs the place>') - # A Place can access its restaurant, if available. - self.assertEqual(repr(self.p1.restaurant), '<Restaurant: Demon Dogs the restaurant>') - # p2 doesn't have an associated restaurant. - self.assertRaises(Restaurant.DoesNotExist, getattr, self.p2, 'restaurant') - - def test_setter(self): - # Set the place using assignment notation. Because place is the primary - # key on Restaurant, the save will create a new restaurant - self.r.place = self.p2 - self.r.save() - self.assertEqual(repr(self.p2.restaurant), '<Restaurant: Ace Hardware the restaurant>') - self.assertEqual(repr(self.r.place), '<Place: Ace Hardware the place>') - self.assertEqual(self.p2.pk, self.r.pk) - # Set the place back again, using assignment in the reverse direction. - self.p1.restaurant = self.r - self.assertEqual(repr(self.p1.restaurant), '<Restaurant: Demon Dogs the restaurant>') - r = Restaurant.objects.get(pk=self.p1.id) - self.assertEqual(repr(r.place), '<Place: Demon Dogs the place>') - - def test_manager_all(self): - # Restaurant.objects.all() just returns the Restaurants, not the Places. - self.assertQuerysetEqual(Restaurant.objects.all(), [ - '<Restaurant: Demon Dogs the restaurant>', - ]) - # Place.objects.all() returns all Places, regardless of whether they - # have Restaurants. - self.assertQuerysetEqual(Place.objects.order_by('name'), [ - '<Place: Ace Hardware the place>', - '<Place: Demon Dogs the place>', - ]) - - def test_manager_get(self): - def assert_get_restaurant(**params): - self.assertEqual(repr(Restaurant.objects.get(**params)), - '<Restaurant: Demon Dogs the restaurant>') - assert_get_restaurant(place__id__exact=self.p1.pk) - assert_get_restaurant(place__id=self.p1.pk) - assert_get_restaurant(place__exact=self.p1.pk) - assert_get_restaurant(place__exact=self.p1) - assert_get_restaurant(place=self.p1.pk) - assert_get_restaurant(place=self.p1) - assert_get_restaurant(pk=self.p1.pk) - assert_get_restaurant(place__pk__exact=self.p1.pk) - assert_get_restaurant(place__pk=self.p1.pk) - assert_get_restaurant(place__name__startswith="Demon") - - def assert_get_place(**params): - self.assertEqual(repr(Place.objects.get(**params)), - '<Place: Demon Dogs the place>') - assert_get_place(restaurant__place__exact=self.p1.pk) - assert_get_place(restaurant__place__exact=self.p1) - assert_get_place(restaurant__place__pk=self.p1.pk) - assert_get_place(restaurant__exact=self.p1.pk) - assert_get_place(restaurant__exact=self.r) - assert_get_place(restaurant__pk=self.p1.pk) - assert_get_place(restaurant=self.p1.pk) - assert_get_place(restaurant=self.r) - assert_get_place(id__exact=self.p1.pk) - assert_get_place(pk=self.p1.pk) - - def test_foreign_key(self): - # Add a Waiter to the Restaurant. - w = self.r.waiter_set.create(name='Joe') - w.save() - self.assertEqual(repr(w), '<Waiter: Joe the waiter at Demon Dogs the restaurant>') - # Query the waiters - def assert_filter_waiters(**params): - self.assertQuerysetEqual(Waiter.objects.filter(**params), [ - '<Waiter: Joe the waiter at Demon Dogs the restaurant>' - ]) - assert_filter_waiters(restaurant__place__exact=self.p1.pk) - assert_filter_waiters(restaurant__place__exact=self.p1) - assert_filter_waiters(restaurant__place__pk=self.p1.pk) - assert_filter_waiters(restaurant__exact=self.p1.pk) - assert_filter_waiters(restaurant__exact=self.p1) - assert_filter_waiters(restaurant__pk=self.p1.pk) - assert_filter_waiters(restaurant=self.p1.pk) - assert_filter_waiters(restaurant=self.r) - assert_filter_waiters(id__exact=self.p1.pk) - assert_filter_waiters(pk=self.p1.pk) - # Delete the restaurant; the waiter should also be removed - r = Restaurant.objects.get(pk=self.p1.pk) - r.delete() - self.assertEqual(Waiter.objects.count(), 0) - - def test_multiple_o2o(self): - # One-to-one fields still work if you create your own primary key - o1 = ManualPrimaryKey(primary_key="abc123", name="primary") - o1.save() - o2 = RelatedModel(link=o1, name="secondary") - o2.save() - - # You can have multiple one-to-one fields on a model, too. - x1 = MultiModel(link1=self.p1, link2=o1, name="x1") - x1.save() - self.assertEqual(repr(o1.multimodel), '<MultiModel: Multimodel x1>') - # This will fail because each one-to-one field must be unique (and - # link2=o1 was used for x1, above). - sid = transaction.savepoint() - mm = MultiModel(link1=self.p2, link2=o1, name="x1") - self.assertRaises(IntegrityError, mm.save) - transaction.savepoint_rollback(sid) diff --git a/parts/django/tests/modeltests/or_lookups/__init__.py b/parts/django/tests/modeltests/or_lookups/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/or_lookups/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/or_lookups/models.py b/parts/django/tests/modeltests/or_lookups/models.py deleted file mode 100644 index 7f14ba5..0000000 --- a/parts/django/tests/modeltests/or_lookups/models.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -19. OR lookups - -To perform an OR lookup, or a lookup that combines ANDs and ORs, combine -``QuerySet`` objects using ``&`` and ``|`` operators. - -Alternatively, use positional arguments, and pass one or more expressions of -clauses using the variable ``django.db.models.Q`` (or any object with an -``add_to_query`` method). -""" - -from django.db import models - -class Article(models.Model): - headline = models.CharField(max_length=50) - pub_date = models.DateTimeField() - - class Meta: - ordering = ('pub_date',) - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/or_lookups/tests.py b/parts/django/tests/modeltests/or_lookups/tests.py deleted file mode 100644 index ad218cd..0000000 --- a/parts/django/tests/modeltests/or_lookups/tests.py +++ /dev/null @@ -1,232 +0,0 @@ -from datetime import datetime -from operator import attrgetter - -from django.db.models import Q -from django.test import TestCase - -from models import Article - - -class OrLookupsTests(TestCase): - - def setUp(self): - self.a1 = Article.objects.create( - headline='Hello', pub_date=datetime(2005, 11, 27) - ).pk - self.a2 = Article.objects.create( - headline='Goodbye', pub_date=datetime(2005, 11, 28) - ).pk - self.a3 = Article.objects.create( - headline='Hello and goodbye', pub_date=datetime(2005, 11, 29) - ).pk - - def test_filter_or(self): - self.assertQuerysetEqual( - Article.objects.filter(headline__startswith='Hello') | Article.objects.filter(headline__startswith='Goodbye'), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - self.assertQuerysetEqual( - Article.objects.filter(headline__contains='Hello') | Article.objects.filter(headline__contains='bye'), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - self.assertQuerysetEqual( - Article.objects.filter(headline__iexact='Hello') | Article.objects.filter(headline__contains='ood'), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - self.assertQuerysetEqual( - Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__startswith='Goodbye')), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - - def test_stages(self): - # You can shorten this syntax with code like the following, which is - # especially useful if building the query in stages: - articles = Article.objects.all() - self.assertQuerysetEqual( - articles.filter(headline__startswith='Hello') & articles.filter(headline__startswith='Goodbye'), - [] - ) - self.assertQuerysetEqual( - articles.filter(headline__startswith='Hello') & articles.filter(headline__contains='bye'), [ - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - def test_pk_q(self): - self.assertQuerysetEqual( - Article.objects.filter(Q(pk=self.a1) | Q(pk=self.a2)), [ - 'Hello', - 'Goodbye' - ], - attrgetter("headline") - ) - - self.assertQuerysetEqual( - Article.objects.filter(Q(pk=self.a1) | Q(pk=self.a2) | Q(pk=self.a3)), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - def test_pk_in(self): - self.assertQuerysetEqual( - Article.objects.filter(pk__in=[self.a1, self.a2, self.a3]), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - self.assertQuerysetEqual( - Article.objects.filter(pk__in=(self.a1, self.a2, self.a3)), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - self.assertQuerysetEqual( - Article.objects.filter(pk__in=[self.a1, self.a2, self.a3, 40000]), [ - 'Hello', - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - def test_q_negated(self): - # Q objects can be negated - self.assertQuerysetEqual( - Article.objects.filter(Q(pk=self.a1) | ~Q(pk=self.a2)), [ - 'Hello', - 'Hello and goodbye' - ], - attrgetter("headline") - ) - - self.assertQuerysetEqual( - Article.objects.filter(~Q(pk=self.a1) & ~Q(pk=self.a2)), [ - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - # This allows for more complex queries than filter() and exclude() - # alone would allow - self.assertQuerysetEqual( - Article.objects.filter(Q(pk=self.a1) & (~Q(pk=self.a2) | Q(pk=self.a3))), [ - 'Hello' - ], - attrgetter("headline"), - ) - - def test_complex_filter(self): - # The 'complex_filter' method supports framework features such as - # 'limit_choices_to' which normally take a single dictionary of lookup - # arguments but need to support arbitrary queries via Q objects too. - self.assertQuerysetEqual( - Article.objects.complex_filter({'pk': self.a1}), [ - 'Hello' - ], - attrgetter("headline"), - ) - - self.assertQuerysetEqual( - Article.objects.complex_filter(Q(pk=self.a1) | Q(pk=self.a2)), [ - 'Hello', - 'Goodbye' - ], - attrgetter("headline"), - ) - - def test_empty_in(self): - # Passing "in" an empty list returns no results ... - self.assertQuerysetEqual( - Article.objects.filter(pk__in=[]), - [] - ) - # ... but can return results if we OR it with another query. - self.assertQuerysetEqual( - Article.objects.filter(Q(pk__in=[]) | Q(headline__icontains='goodbye')), [ - 'Goodbye', - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - def test_q_and(self): - # Q arg objects are ANDed - self.assertQuerysetEqual( - Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')), [ - 'Hello and goodbye' - ], - attrgetter("headline") - ) - # Q arg AND order is irrelevant - self.assertQuerysetEqual( - Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello'), [ - 'Hello and goodbye' - ], - attrgetter("headline"), - ) - - self.assertQuerysetEqual( - Article.objects.filter(Q(headline__startswith='Hello') & Q(headline__startswith='Goodbye')), - [] - ) - - def test_q_exclude(self): - self.assertQuerysetEqual( - Article.objects.exclude(Q(headline__startswith='Hello')), [ - 'Goodbye' - ], - attrgetter("headline") - ) - - def test_other_arg_queries(self): - # Try some arg queries with operations other than filter. - self.assertEqual( - Article.objects.get(Q(headline__startswith='Hello'), Q(headline__contains='bye')).headline, - 'Hello and goodbye' - ) - - self.assertEqual( - Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__contains='bye')).count(), - 3 - ) - - self.assertQuerysetEqual( - Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')).values(), [ - {"headline": "Hello and goodbye", "id": self.a3, "pub_date": datetime(2005, 11, 29)}, - ], - lambda o: o, - ) - - self.assertEqual( - Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([self.a1, self.a2]), - {self.a1: Article.objects.get(pk=self.a1)} - ) diff --git a/parts/django/tests/modeltests/order_with_respect_to/__init__.py b/parts/django/tests/modeltests/order_with_respect_to/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/order_with_respect_to/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/order_with_respect_to/models.py b/parts/django/tests/modeltests/order_with_respect_to/models.py deleted file mode 100644 index 59f01d4..0000000 --- a/parts/django/tests/modeltests/order_with_respect_to/models.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -Tests for the order_with_respect_to Meta attribute. -""" - -from django.db import models - - -class Question(models.Model): - text = models.CharField(max_length=200) - -class Answer(models.Model): - text = models.CharField(max_length=200) - question = models.ForeignKey(Question) - - class Meta: - order_with_respect_to = 'question' - - def __unicode__(self): - return unicode(self.text) - -class Post(models.Model): - title = models.CharField(max_length=200) - parent = models.ForeignKey("self", related_name="children", null=True) - - class Meta: - order_with_respect_to = "parent" - - def __unicode__(self): - return self.title diff --git a/parts/django/tests/modeltests/order_with_respect_to/tests.py b/parts/django/tests/modeltests/order_with_respect_to/tests.py deleted file mode 100644 index 328d968..0000000 --- a/parts/django/tests/modeltests/order_with_respect_to/tests.py +++ /dev/null @@ -1,71 +0,0 @@ -from operator import attrgetter - -from django.test import TestCase - -from models import Post, Question, Answer - - -class OrderWithRespectToTests(TestCase): - def test_basic(self): - q1 = Question.objects.create(text="Which Beatle starts with the letter 'R'?") - q2 = Question.objects.create(text="What is your name?") - - Answer.objects.create(text="John", question=q1) - Answer.objects.create(text="Jonno", question=q2) - Answer.objects.create(text="Paul", question=q1) - Answer.objects.create(text="Paulo", question=q2) - Answer.objects.create(text="George", question=q1) - Answer.objects.create(text="Ringo", question=q1) - - # The answers will always be ordered in the order they were inserted. - self.assertQuerysetEqual( - q1.answer_set.all(), [ - "John", "Paul", "George", "Ringo", - ], - attrgetter("text"), - ) - - # We can retrieve the answers related to a particular object, in the - # order they were created, once we have a particular object. - a1 = Answer.objects.filter(question=q1)[0] - self.assertEqual(a1.text, "John") - a2 = a1.get_next_in_order() - self.assertEqual(a2.text, "Paul") - a4 = list(Answer.objects.filter(question=q1))[-1] - self.assertEqual(a4.text, "Ringo") - self.assertEqual(a4.get_previous_in_order().text, "George") - - # Determining (and setting) the ordering for a particular item is also - # possible. - id_list = [o.pk for o in q1.answer_set.all()] - self.assertEqual(a2.question.get_answer_order(), id_list) - - a5 = Answer.objects.create(text="Number five", question=q1) - - # It doesn't matter which answer we use to check the order, it will - # always be the same. - self.assertEqual( - a2.question.get_answer_order(), a5.question.get_answer_order() - ) - - # The ordering can be altered: - id_list = [o.pk for o in q1.answer_set.all()] - x = id_list.pop() - id_list.insert(-1, x) - self.assertNotEqual(a5.question.get_answer_order(), id_list) - a5.question.set_answer_order(id_list) - self.assertQuerysetEqual( - q1.answer_set.all(), [ - "John", "Paul", "George", "Number five", "Ringo" - ], - attrgetter("text") - ) - - def test_recursive_ordering(self): - p1 = Post.objects.create(title='1') - p2 = Post.objects.create(title='2') - p1_1 = Post.objects.create(title="1.1", parent=p1) - p1_2 = Post.objects.create(title="1.2", parent=p1) - p2_1 = Post.objects.create(title="2.1", parent=p2) - p1_3 = Post.objects.create(title="1.3", parent=p1) - self.assertEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk]) diff --git a/parts/django/tests/modeltests/ordering/__init__.py b/parts/django/tests/modeltests/ordering/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/ordering/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/ordering/models.py b/parts/django/tests/modeltests/ordering/models.py deleted file mode 100644 index 25d3c2c..0000000 --- a/parts/django/tests/modeltests/ordering/models.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -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 -``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. -The special-case field name ``"?"`` specifies random order. - -The ordering attribute is not required. If you leave it off, ordering will be -undefined -- not random, just undefined. -""" - -from django.db import models - - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateTimeField() - class Meta: - ordering = ('-pub_date', 'headline') - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/ordering/tests.py b/parts/django/tests/modeltests/ordering/tests.py deleted file mode 100644 index 77862c5..0000000 --- a/parts/django/tests/modeltests/ordering/tests.py +++ /dev/null @@ -1,137 +0,0 @@ -from datetime import datetime -from operator import attrgetter - -from django.test import TestCase - -from models import Article - - -class OrderingTests(TestCase): - def test_basic(self): - a1 = Article.objects.create( - headline="Article 1", pub_date=datetime(2005, 7, 26) - ) - a2 = Article.objects.create( - headline="Article 2", pub_date=datetime(2005, 7, 27) - ) - a3 = Article.objects.create( - headline="Article 3", pub_date=datetime(2005, 7, 27) - ) - a4 = Article.objects.create( - headline="Article 4", pub_date=datetime(2005, 7, 28) - ) - - # By default, Article.objects.all() orders by pub_date descending, then - # headline ascending. - self.assertQuerysetEqual( - Article.objects.all(), [ - "Article 4", - "Article 2", - "Article 3", - "Article 1", - ], - attrgetter("headline") - ) - - # Override ordering with order_by, which is in the same format as the - # ordering attribute in models. - self.assertQuerysetEqual( - Article.objects.order_by("headline"), [ - "Article 1", - "Article 2", - "Article 3", - "Article 4", - ], - attrgetter("headline") - ) - self.assertQuerysetEqual( - Article.objects.order_by("pub_date", "-headline"), [ - "Article 1", - "Article 3", - "Article 2", - "Article 4", - ], - attrgetter("headline") - ) - - # Only the last order_by has any effect (since they each override any - # previous ordering). - self.assertQuerysetEqual( - Article.objects.order_by("id"), [ - "Article 1", - "Article 2", - "Article 3", - "Article 4", - ], - attrgetter("headline") - ) - self.assertQuerysetEqual( - Article.objects.order_by("id").order_by("-headline"), [ - "Article 4", - "Article 3", - "Article 2", - "Article 1", - ], - attrgetter("headline") - ) - - # Use the 'stop' part of slicing notation to limit the results. - self.assertQuerysetEqual( - Article.objects.order_by("headline")[:2], [ - "Article 1", - "Article 2", - ], - attrgetter("headline") - ) - - # Use the 'stop' and 'start' parts of slicing notation to offset the - # result list. - self.assertQuerysetEqual( - Article.objects.order_by("headline")[1:3], [ - "Article 2", - "Article 3", - ], - attrgetter("headline") - ) - - # Getting a single item should work too: - self.assertEqual(Article.objects.all()[0], a4) - - # Use '?' to order randomly. - self.assertEqual( - len(list(Article.objects.order_by("?"))), 4 - ) - - # Ordering can be reversed using the reverse() method on a queryset. - # This allows you to extract things like "the last two items" (reverse - # and then take the first two). - self.assertQuerysetEqual( - Article.objects.all().reverse()[:2], [ - "Article 1", - "Article 3", - ], - attrgetter("headline") - ) - - # Ordering can be based on fields included from an 'extra' clause - self.assertQuerysetEqual( - Article.objects.extra(select={"foo": "pub_date"}, order_by=["foo", "headline"]), [ - "Article 1", - "Article 2", - "Article 3", - "Article 4", - ], - attrgetter("headline") - ) - - # If the extra clause uses an SQL keyword for a name, it will be - # protected by quoting. - self.assertQuerysetEqual( - Article.objects.extra(select={"order": "pub_date"}, order_by=["order", "headline"]), [ - "Article 1", - "Article 2", - "Article 3", - "Article 4", - ], - attrgetter("headline") - ) diff --git a/parts/django/tests/modeltests/pagination/__init__.py b/parts/django/tests/modeltests/pagination/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/pagination/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/pagination/models.py b/parts/django/tests/modeltests/pagination/models.py deleted file mode 100644 index 48484dd..0000000 --- a/parts/django/tests/modeltests/pagination/models.py +++ /dev/null @@ -1,17 +0,0 @@ -""" -30. Object pagination - -Django provides a framework for paginating a list of objects in a few lines -of code. This is often useful for dividing search results or long lists of -objects into easily readable pages. -""" - -from django.db import models - - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/modeltests/pagination/tests.py b/parts/django/tests/modeltests/pagination/tests.py deleted file mode 100644 index eaee466..0000000 --- a/parts/django/tests/modeltests/pagination/tests.py +++ /dev/null @@ -1,132 +0,0 @@ -from datetime import datetime -from operator import attrgetter - -from django.core.paginator import Paginator, InvalidPage, EmptyPage -from django.test import TestCase - -from models import Article - - -class CountContainer(object): - def count(self): - return 42 - -class LenContainer(object): - def __len__(self): - return 42 - -class PaginationTests(TestCase): - def setUp(self): - # Prepare a list of objects for pagination. - for x in range(1, 10): - a = Article(headline='Article %s' % x, pub_date=datetime(2005, 7, 29)) - a.save() - - def test_paginator(self): - paginator = Paginator(Article.objects.all(), 5) - self.assertEqual(9, paginator.count) - self.assertEqual(2, paginator.num_pages) - self.assertEqual([1, 2], paginator.page_range) - - def test_first_page(self): - paginator = Paginator(Article.objects.all(), 5) - p = paginator.page(1) - self.assertEqual(u"<Page 1 of 2>", unicode(p)) - self.assertQuerysetEqual(p.object_list, [ - "<Article: Article 1>", - "<Article: Article 2>", - "<Article: Article 3>", - "<Article: Article 4>", - "<Article: Article 5>" - ] - ) - self.assertTrue(p.has_next()) - self.assertFalse(p.has_previous()) - self.assertTrue(p.has_other_pages()) - self.assertEqual(2, p.next_page_number()) - self.assertEqual(0, p.previous_page_number()) - self.assertEqual(1, p.start_index()) - self.assertEqual(5, p.end_index()) - - def test_last_page(self): - paginator = Paginator(Article.objects.all(), 5) - p = paginator.page(2) - self.assertEqual(u"<Page 2 of 2>", unicode(p)) - self.assertQuerysetEqual(p.object_list, [ - "<Article: Article 6>", - "<Article: Article 7>", - "<Article: Article 8>", - "<Article: Article 9>" - ] - ) - self.assertFalse(p.has_next()) - self.assertTrue(p.has_previous()) - self.assertTrue(p.has_other_pages()) - self.assertEqual(3, p.next_page_number()) - self.assertEqual(1, p.previous_page_number()) - self.assertEqual(6, p.start_index()) - self.assertEqual(9, p.end_index()) - - def test_empty_page(self): - paginator = Paginator(Article.objects.all(), 5) - self.assertRaises(EmptyPage, paginator.page, 0) - self.assertRaises(EmptyPage, paginator.page, 3) - - # Empty paginators with allow_empty_first_page=True. - paginator = Paginator(Article.objects.filter(id=0), 5, allow_empty_first_page=True) - self.assertEqual(0, paginator.count) - self.assertEqual(1, paginator.num_pages) - self.assertEqual([1], paginator.page_range) - - # Empty paginators with allow_empty_first_page=False. - paginator = Paginator(Article.objects.filter(id=0), 5, allow_empty_first_page=False) - self.assertEqual(0, paginator.count) - self.assertEqual(0, paginator.num_pages) - self.assertEqual([], paginator.page_range) - - def test_invalid_page(self): - paginator = Paginator(Article.objects.all(), 5) - self.assertRaises(InvalidPage, paginator.page, 7) - - def test_orphans(self): - # Add a few more records to test out the orphans feature. - for x in range(10, 13): - Article(headline="Article %s" % x, pub_date=datetime(2006, 10, 6)).save() - - # With orphans set to 3 and 10 items per page, we should get all 12 items on a single page. - paginator = Paginator(Article.objects.all(), 10, orphans=3) - self.assertEqual(1, paginator.num_pages) - - # With orphans only set to 1, we should get two pages. - paginator = Paginator(Article.objects.all(), 10, orphans=1) - self.assertEqual(2, paginator.num_pages) - - def test_paginate_list(self): - # Paginators work with regular lists/tuples, too -- not just with QuerySets. - paginator = Paginator([1, 2, 3, 4, 5, 6, 7, 8, 9], 5) - self.assertEqual(9, paginator.count) - self.assertEqual(2, paginator.num_pages) - self.assertEqual([1, 2], paginator.page_range) - p = paginator.page(1) - self.assertEqual(u"<Page 1 of 2>", unicode(p)) - self.assertEqual([1, 2, 3, 4, 5], p.object_list) - self.assertTrue(p.has_next()) - self.assertFalse(p.has_previous()) - self.assertTrue(p.has_other_pages()) - self.assertEqual(2, p.next_page_number()) - self.assertEqual(0, p.previous_page_number()) - self.assertEqual(1, p.start_index()) - self.assertEqual(5, p.end_index()) - - def test_paginate_misc_classes(self): - # Paginator can be passed other objects with a count() method. - paginator = Paginator(CountContainer(), 10) - self.assertEqual(42, paginator.count) - self.assertEqual(5, paginator.num_pages) - self.assertEqual([1, 2, 3, 4, 5], paginator.page_range) - - # Paginator can be passed other objects that implement __len__. - paginator = Paginator(LenContainer(), 10) - self.assertEqual(42, paginator.count) - self.assertEqual(5, paginator.num_pages) - self.assertEqual([1, 2, 3, 4, 5], paginator.page_range) diff --git a/parts/django/tests/modeltests/properties/__init__.py b/parts/django/tests/modeltests/properties/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/properties/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/properties/models.py b/parts/django/tests/modeltests/properties/models.py deleted file mode 100644 index 390efe3..0000000 --- a/parts/django/tests/modeltests/properties/models.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -22. Using properties on models - -Use properties on models just like on any other Python object. -""" - -from django.db import models - -class Person(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - - def _get_full_name(self): - return "%s %s" % (self.first_name, self.last_name) - - def _set_full_name(self, combined_name): - self.first_name, self.last_name = combined_name.split(' ', 1) - - full_name = property(_get_full_name) - - full_name_2 = property(_get_full_name, _set_full_name) diff --git a/parts/django/tests/modeltests/properties/tests.py b/parts/django/tests/modeltests/properties/tests.py deleted file mode 100644 index e31ac58..0000000 --- a/parts/django/tests/modeltests/properties/tests.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.test import TestCase -from models import Person - -class PropertyTests(TestCase): - - def setUp(self): - self.a = Person(first_name='John', last_name='Lennon') - self.a.save() - - def test_getter(self): - self.assertEqual(self.a.full_name, 'John Lennon') - - def test_setter(self): - # The "full_name" property hasn't provided a "set" method. - self.assertRaises(AttributeError, setattr, self.a, 'full_name', 'Paul McCartney') - - # But "full_name_2" has, and it can be used to initialise the class. - a2 = Person(full_name_2 = 'Paul McCartney') - a2.save() - self.assertEqual(a2.first_name, 'Paul') diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/__init__.py b/parts/django/tests/modeltests/proxy_model_inheritance/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/app1/__init__.py b/parts/django/tests/modeltests/proxy_model_inheritance/app1/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/app1/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/app1/models.py b/parts/django/tests/modeltests/proxy_model_inheritance/app1/models.py deleted file mode 100644 index 59a9ac7..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/app1/models.py +++ /dev/null @@ -1,5 +0,0 @@ -from app2.models import NiceModel - -class ProxyModel(NiceModel): - class Meta: - proxy = True diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/app2/__init__.py b/parts/django/tests/modeltests/proxy_model_inheritance/app2/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/app2/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/app2/models.py b/parts/django/tests/modeltests/proxy_model_inheritance/app2/models.py deleted file mode 100644 index 549cd07..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/app2/models.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.db import models - -class NiceModel(models.Model): - pass diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/models.py b/parts/django/tests/modeltests/proxy_model_inheritance/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/models.py +++ /dev/null diff --git a/parts/django/tests/modeltests/proxy_model_inheritance/tests.py b/parts/django/tests/modeltests/proxy_model_inheritance/tests.py deleted file mode 100644 index b682851..0000000 --- a/parts/django/tests/modeltests/proxy_model_inheritance/tests.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -XX. Proxy model inheritance - -Proxy model inheritance across apps can result in syncdb not creating the table -for the proxied model (as described in #12286). This test creates two dummy -apps and calls syncdb, then verifies that the table has been created. -""" - -import os -import sys - -from django.conf import settings, Settings -from django.core.management import call_command -from django.db.models.loading import load_app -from django.test import TransactionTestCase - -class ProxyModelInheritanceTests(TransactionTestCase): - - def setUp(self): - self.old_sys_path = sys.path[:] - sys.path.append(os.path.dirname(os.path.abspath(__file__))) - self.old_installed_apps = settings.INSTALLED_APPS - settings.INSTALLED_APPS = ('app1', 'app2') - map(load_app, settings.INSTALLED_APPS) - call_command('syncdb', verbosity=0) - global ProxyModel, NiceModel - from app1.models import ProxyModel - from app2.models import NiceModel - - def tearDown(self): - settings.INSTALLED_APPS = self.old_installed_apps - sys.path = self.old_sys_path - - def test_table_exists(self): - self.assertEquals(NiceModel.objects.all().count(), 0) - self.assertEquals(ProxyModel.objects.all().count(), 0) diff --git a/parts/django/tests/modeltests/proxy_models/__init__.py b/parts/django/tests/modeltests/proxy_models/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/proxy_models/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/proxy_models/fixtures/mypeople.json b/parts/django/tests/modeltests/proxy_models/fixtures/mypeople.json deleted file mode 100644 index d20c8f2..0000000 --- a/parts/django/tests/modeltests/proxy_models/fixtures/mypeople.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "pk": 100, - "model": "proxy_models.myperson", - "fields": { - "name": "Elvis Presley" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/proxy_models/models.py b/parts/django/tests/modeltests/proxy_models/models.py deleted file mode 100644 index 90d54d9..0000000 --- a/parts/django/tests/modeltests/proxy_models/models.py +++ /dev/null @@ -1,164 +0,0 @@ -""" -By specifying the 'proxy' Meta attribute, model subclasses can specify that -they will take data directly from the table of their base class table rather -than using a new table of their own. This allows them to act as simple proxies, -providing a modified interface to the data from the base class. -""" - -from django.contrib.contenttypes.models import ContentType -from django.db import models - - -# A couple of managers for testing managing overriding in proxy model cases. - -class PersonManager(models.Manager): - def get_query_set(self): - return super(PersonManager, self).get_query_set().exclude(name="fred") - -class SubManager(models.Manager): - def get_query_set(self): - return super(SubManager, self).get_query_set().exclude(name="wilma") - -class Person(models.Model): - """ - A simple concrete base class. - """ - name = models.CharField(max_length=50) - - objects = PersonManager() - - def __unicode__(self): - return self.name - -class Abstract(models.Model): - """ - A simple abstract base class, to be used for error checking. - """ - data = models.CharField(max_length=10) - - class Meta: - abstract = True - -class MyPerson(Person): - """ - A proxy subclass, this should not get a new table. Overrides the default - manager. - """ - class Meta: - proxy = True - ordering = ["name"] - - objects = SubManager() - other = PersonManager() - - def has_special_name(self): - return self.name.lower() == "special" - -class ManagerMixin(models.Model): - excluder = SubManager() - - class Meta: - abstract = True - -class OtherPerson(Person, ManagerMixin): - """ - A class with the default manager from Person, plus an secondary manager. - """ - class Meta: - proxy = True - ordering = ["name"] - -class StatusPerson(MyPerson): - """ - A non-proxy subclass of a proxy, it should get a new table. - """ - status = models.CharField(max_length=80) - -# We can even have proxies of proxies (and subclass of those). -class MyPersonProxy(MyPerson): - class Meta: - proxy = True - -class LowerStatusPerson(MyPersonProxy): - status = models.CharField(max_length=80) - -class User(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class UserProxy(User): - class Meta: - proxy = True - -class UserProxyProxy(UserProxy): - class Meta: - proxy = True - -# We can still use `select_related()` to include related models in our querysets. -class Country(models.Model): - name = models.CharField(max_length=50) - -class State(models.Model): - name = models.CharField(max_length=50) - country = models.ForeignKey(Country) - - def __unicode__(self): - return self.name - -class StateProxy(State): - class Meta: - proxy = True - -# Proxy models still works with filters (on related fields) -# and select_related, even when mixed with model inheritance -class BaseUser(models.Model): - name = models.CharField(max_length=255) - -class TrackerUser(BaseUser): - status = models.CharField(max_length=50) - -class ProxyTrackerUser(TrackerUser): - class Meta: - proxy = True - - -class Issue(models.Model): - summary = models.CharField(max_length=255) - assignee = models.ForeignKey(TrackerUser) - - def __unicode__(self): - return ':'.join((self.__class__.__name__,self.summary,)) - -class Bug(Issue): - version = models.CharField(max_length=50) - reporter = models.ForeignKey(BaseUser) - -class ProxyBug(Bug): - """ - Proxy of an inherited class - """ - class Meta: - proxy = True - - -class ProxyProxyBug(ProxyBug): - """ - A proxy of proxy model with related field - """ - class Meta: - proxy = True - -class Improvement(Issue): - """ - A model that has relation to a proxy model - or to a proxy of proxy model - """ - version = models.CharField(max_length=50) - reporter = models.ForeignKey(ProxyTrackerUser) - associated_bug = models.ForeignKey(ProxyProxyBug) - -class ProxyImprovement(Improvement): - class Meta: - proxy = True
\ No newline at end of file diff --git a/parts/django/tests/modeltests/proxy_models/tests.py b/parts/django/tests/modeltests/proxy_models/tests.py deleted file mode 100644 index 346a2a3..0000000 --- a/parts/django/tests/modeltests/proxy_models/tests.py +++ /dev/null @@ -1,314 +0,0 @@ -from django.test import TestCase -from django.db import models, DEFAULT_DB_ALIAS -from django.db.models import signals -from django.core import management -from django.core.exceptions import FieldError - -from django.contrib.contenttypes.models import ContentType - -from models import MyPerson, Person, StatusPerson, LowerStatusPerson -from models import MyPersonProxy, Abstract, OtherPerson, User, UserProxy -from models import UserProxyProxy, Country, State, StateProxy, TrackerUser -from models import BaseUser, Bug, ProxyTrackerUser, Improvement, ProxyProxyBug -from models import ProxyBug, ProxyImprovement - -class ProxyModelTests(TestCase): - def test_same_manager_queries(self): - """ - The MyPerson model should be generating the same database queries as - the Person model (when the same manager is used in each case). - """ - my_person_sql = MyPerson.other.all().query.get_compiler( - DEFAULT_DB_ALIAS).as_sql() - person_sql = Person.objects.order_by("name").query.get_compiler( - DEFAULT_DB_ALIAS).as_sql() - self.assertEqual(my_person_sql, person_sql) - - def test_inheretance_new_table(self): - """ - The StatusPerson models should have its own table (it's using ORM-level - inheritance). - """ - sp_sql = StatusPerson.objects.all().query.get_compiler( - DEFAULT_DB_ALIAS).as_sql() - p_sql = Person.objects.all().query.get_compiler( - DEFAULT_DB_ALIAS).as_sql() - self.assertNotEqual(sp_sql, p_sql) - - def test_basic_proxy(self): - """ - Creating a Person makes them accessible through the MyPerson proxy. - """ - Person.objects.create(name="Foo McBar") - self.assertEqual(len(Person.objects.all()), 1) - self.assertEqual(len(MyPerson.objects.all()), 1) - self.assertEqual(MyPerson.objects.get(name="Foo McBar").id, 1) - self.assertFalse(MyPerson.objects.get(id=1).has_special_name()) - - def test_no_proxy(self): - """ - Person is not proxied by StatusPerson subclass. - """ - Person.objects.create(name="Foo McBar") - self.assertEqual(list(StatusPerson.objects.all()), []) - - def test_basic_proxy_reverse(self): - """ - A new MyPerson also shows up as a standard Person. - """ - MyPerson.objects.create(name="Bazza del Frob") - self.assertEqual(len(MyPerson.objects.all()), 1) - self.assertEqual(len(Person.objects.all()), 1) - - LowerStatusPerson.objects.create(status="low", name="homer") - lsps = [lsp.name for lsp in LowerStatusPerson.objects.all()] - self.assertEqual(lsps, ["homer"]) - - def test_correct_type_proxy_of_proxy(self): - """ - Correct type when querying a proxy of proxy - """ - Person.objects.create(name="Foo McBar") - MyPerson.objects.create(name="Bazza del Frob") - LowerStatusPerson.objects.create(status="low", name="homer") - pp = sorted([mpp.name for mpp in MyPersonProxy.objects.all()]) - self.assertEqual(pp, ['Bazza del Frob', 'Foo McBar', 'homer']) - - def test_proxy_included_in_ancestors(self): - """ - Proxy models are included in the ancestors for a model's DoesNotExist - and MultipleObjectsReturned - """ - Person.objects.create(name="Foo McBar") - MyPerson.objects.create(name="Bazza del Frob") - LowerStatusPerson.objects.create(status="low", name="homer") - max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id'] - - self.assertRaises(Person.DoesNotExist, - MyPersonProxy.objects.get, - name='Zathras' - ) - self.assertRaises(Person.MultipleObjectsReturned, - MyPersonProxy.objects.get, - id__lt=max_id+1 - ) - self.assertRaises(Person.DoesNotExist, - StatusPerson.objects.get, - name='Zathras' - ) - - sp1 = StatusPerson.objects.create(name='Bazza Jr.') - sp2 = StatusPerson.objects.create(name='Foo Jr.') - max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id'] - - self.assertRaises(Person.MultipleObjectsReturned, - StatusPerson.objects.get, - id__lt=max_id+1 - ) - - def test_abc(self): - """ - All base classes must be non-abstract - """ - def build_abc(): - class NoAbstract(Abstract): - class Meta: - proxy = True - self.assertRaises(TypeError, build_abc) - - def test_no_cbc(self): - """ - The proxy must actually have one concrete base class - """ - def build_no_cbc(): - class TooManyBases(Person, Abstract): - class Meta: - proxy = True - self.assertRaises(TypeError, build_no_cbc) - - def test_no_base_classes(self): - def build_no_base_classes(): - class NoBaseClasses(models.Model): - class Meta: - proxy = True - self.assertRaises(TypeError, build_no_base_classes) - - def test_new_fields(self): - def build_new_fields(): - class NoNewFields(Person): - newfield = models.BooleanField() - class Meta: - proxy = True - self.assertRaises(FieldError, build_new_fields) - - def test_myperson_manager(self): - Person.objects.create(name="fred") - Person.objects.create(name="wilma") - Person.objects.create(name="barney") - - resp = [p.name for p in MyPerson.objects.all()] - self.assertEqual(resp, ['barney', 'fred']) - - resp = [p.name for p in MyPerson._default_manager.all()] - self.assertEqual(resp, ['barney', 'fred']) - - def test_otherperson_manager(self): - Person.objects.create(name="fred") - Person.objects.create(name="wilma") - Person.objects.create(name="barney") - - resp = [p.name for p in OtherPerson.objects.all()] - self.assertEqual(resp, ['barney', 'wilma']) - - resp = [p.name for p in OtherPerson.excluder.all()] - self.assertEqual(resp, ['barney', 'fred']) - - resp = [p.name for p in OtherPerson._default_manager.all()] - self.assertEqual(resp, ['barney', 'wilma']) - - def test_proxy_model_signals(self): - """ - Test save signals for proxy models - """ - output = [] - - def make_handler(model, event): - def _handler(*args, **kwargs): - output.append('%s %s save' % (model, event)) - return _handler - - h1 = make_handler('MyPerson', 'pre') - h2 = make_handler('MyPerson', 'post') - h3 = make_handler('Person', 'pre') - h4 = make_handler('Person', 'post') - - signals.pre_save.connect(h1, sender=MyPerson) - signals.post_save.connect(h2, sender=MyPerson) - signals.pre_save.connect(h3, sender=Person) - signals.post_save.connect(h4, sender=Person) - - dino = MyPerson.objects.create(name=u"dino") - self.assertEqual(output, [ - 'MyPerson pre save', - 'MyPerson post save' - ]) - - output = [] - - h5 = make_handler('MyPersonProxy', 'pre') - h6 = make_handler('MyPersonProxy', 'post') - - signals.pre_save.connect(h5, sender=MyPersonProxy) - signals.post_save.connect(h6, sender=MyPersonProxy) - - dino = MyPersonProxy.objects.create(name=u"pebbles") - - self.assertEqual(output, [ - 'MyPersonProxy pre save', - 'MyPersonProxy post save' - ]) - - signals.pre_save.disconnect(h1, sender=MyPerson) - signals.post_save.disconnect(h2, sender=MyPerson) - signals.pre_save.disconnect(h3, sender=Person) - signals.post_save.disconnect(h4, sender=Person) - signals.pre_save.disconnect(h5, sender=MyPersonProxy) - signals.post_save.disconnect(h6, sender=MyPersonProxy) - - def test_content_type(self): - ctype = ContentType.objects.get_for_model - self.assertTrue(ctype(Person) is ctype(OtherPerson)) - - def test_user_userproxy_userproxyproxy(self): - User.objects.create(name='Bruce') - - resp = [u.name for u in User.objects.all()] - self.assertEqual(resp, ['Bruce']) - - resp = [u.name for u in UserProxy.objects.all()] - self.assertEqual(resp, ['Bruce']) - - resp = [u.name for u in UserProxyProxy.objects.all()] - self.assertEqual(resp, ['Bruce']) - - def test_proxy_delete(self): - """ - Proxy objects can be deleted - """ - User.objects.create(name='Bruce') - u2 = UserProxy.objects.create(name='George') - - resp = [u.name for u in UserProxy.objects.all()] - self.assertEqual(resp, ['Bruce', 'George']) - - u2.delete() - - resp = [u.name for u in UserProxy.objects.all()] - self.assertEqual(resp, ['Bruce']) - - def test_select_related(self): - """ - We can still use `select_related()` to include related models in our - querysets. - """ - country = Country.objects.create(name='Australia') - state = State.objects.create(name='New South Wales', country=country) - - resp = [s.name for s in State.objects.select_related()] - self.assertEqual(resp, ['New South Wales']) - - resp = [s.name for s in StateProxy.objects.select_related()] - self.assertEqual(resp, ['New South Wales']) - - self.assertEqual(StateProxy.objects.get(name='New South Wales').name, - 'New South Wales') - - resp = StateProxy.objects.select_related().get(name='New South Wales') - self.assertEqual(resp.name, 'New South Wales') - - def test_proxy_bug(self): - contributor = TrackerUser.objects.create(name='Contributor', - status='contrib') - someone = BaseUser.objects.create(name='Someone') - Bug.objects.create(summary='fix this', version='1.1beta', - assignee=contributor, reporter=someone) - pcontributor = ProxyTrackerUser.objects.create(name='OtherContributor', - status='proxy') - Improvement.objects.create(summary='improve that', version='1.1beta', - assignee=contributor, reporter=pcontributor, - associated_bug=ProxyProxyBug.objects.all()[0]) - - # Related field filter on proxy - resp = ProxyBug.objects.get(version__icontains='beta') - self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>') - - # Select related + filter on proxy - resp = ProxyBug.objects.select_related().get(version__icontains='beta') - self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>') - - # Proxy of proxy, select_related + filter - resp = ProxyProxyBug.objects.select_related().get( - version__icontains='beta' - ) - self.assertEqual(repr(resp), '<ProxyProxyBug: ProxyProxyBug:fix this>') - - # Select related + filter on a related proxy field - resp = ProxyImprovement.objects.select_related().get( - reporter__name__icontains='butor' - ) - self.assertEqual(repr(resp), - '<ProxyImprovement: ProxyImprovement:improve that>' - ) - - # Select related + filter on a related proxy of proxy field - resp = ProxyImprovement.objects.select_related().get( - associated_bug__summary__icontains='fix' - ) - self.assertEqual(repr(resp), - '<ProxyImprovement: ProxyImprovement:improve that>' - ) - - def test_proxy_load_from_fixture(self): - management.call_command('loaddata', 'mypeople.json', verbosity=0, commit=False) - p = MyPerson.objects.get(pk=100) - self.assertEqual(p.name, 'Elvis Presley') diff --git a/parts/django/tests/modeltests/raw_query/__init__.py b/parts/django/tests/modeltests/raw_query/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/raw_query/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/raw_query/fixtures/raw_query_books.json b/parts/django/tests/modeltests/raw_query/fixtures/raw_query_books.json deleted file mode 100644 index 35879aa..0000000 --- a/parts/django/tests/modeltests/raw_query/fixtures/raw_query_books.json +++ /dev/null @@ -1,110 +0,0 @@ -[ - { - "pk": 1, - "model": "raw_query.author", - "fields": { - "dob": "1950-09-20", - "first_name": "Joe", - "last_name": "Smith" - } - }, - { - "pk": 2, - "model": "raw_query.author", - "fields": { - "dob": "1920-04-02", - "first_name": "Jill", - "last_name": "Doe" - } - }, - { - "pk": 3, - "model": "raw_query.author", - "fields": { - "dob": "1986-01-25", - "first_name": "Bob", - "last_name": "Smith" - } - }, - { - "pk": 4, - "model": "raw_query.author", - "fields": { - "dob": "1932-05-10", - "first_name": "Bill", - "last_name": "Jones" - } - }, - { - "pk": 1, - "model": "raw_query.book", - "fields": { - "author": 1, - "title": "The awesome book", - "paperback": false, - "opening_line": "It was a bright cold day in April and the clocks were striking thirteen." - } - }, - { - "pk": 2, - "model": "raw_query.book", - "fields": { - "author": 1, - "title": "The horrible book", - "paperback": true, - "opening_line": "On an evening in the latter part of May a middle-aged man was walking homeward from Shaston to the village of Marlott, in the adjoining Vale of Blakemore, or Blackmoor." - } - }, - { - "pk": 3, - "model": "raw_query.book", - "fields": { - "author": 1, - "title": "Another awesome book", - "paperback": false, - "opening_line": "A squat grey building of only thirty-four stories." - } - }, - { - "pk": 4, - "model": "raw_query.book", - "fields": { - "author": 3, - "title": "Some other book", - "paperback": true, - "opening_line": "It was the day my grandmother exploded." - } - }, - { - "pk": 1, - "model": "raw_query.coffee", - "fields": { - "brand": "dunkin doughnuts" - } - }, - { - "pk": 2, - "model": "raw_query.coffee", - "fields": { - "brand": "starbucks" - } - }, - { - "pk": 1, - "model": "raw_query.reviewer", - "fields": { - "reviewed": [ - 2, - 3, - 4 - ] - } - }, - { - "pk": 2, - "model": "raw_query.reviewer", - "fields": { - "reviewed": [] - } - } -] diff --git a/parts/django/tests/modeltests/raw_query/models.py b/parts/django/tests/modeltests/raw_query/models.py deleted file mode 100644 index bb42b5b..0000000 --- a/parts/django/tests/modeltests/raw_query/models.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.db import models - -class Author(models.Model): - first_name = models.CharField(max_length=255) - last_name = models.CharField(max_length=255) - dob = models.DateField() - - def __init__(self, *args, **kwargs): - super(Author, self).__init__(*args, **kwargs) - # Protect against annotations being passed to __init__ -- - # this'll make the test suite get angry if annotations aren't - # treated differently than fields. - for k in kwargs: - assert k in [f.attname for f in self._meta.fields], \ - "Author.__init__ got an unexpected paramater: %s" % k - -class Book(models.Model): - title = models.CharField(max_length=255) - author = models.ForeignKey(Author) - paperback = models.BooleanField() - opening_line = models.TextField() - -class Coffee(models.Model): - brand = models.CharField(max_length=255, db_column="name") - -class Reviewer(models.Model): - reviewed = models.ManyToManyField(Book) - -class FriendlyAuthor(Author): - pass diff --git a/parts/django/tests/modeltests/raw_query/tests.py b/parts/django/tests/modeltests/raw_query/tests.py deleted file mode 100644 index a1e7edb..0000000 --- a/parts/django/tests/modeltests/raw_query/tests.py +++ /dev/null @@ -1,236 +0,0 @@ -from datetime import date - -from django.conf import settings -from django.db import connection -from django.db.models.sql.query import InvalidQuery -from django.test import TestCase - -from models import Author, Book, Coffee, Reviewer, FriendlyAuthor - - -class RawQueryTests(TestCase): - fixtures = ['raw_query_books.json'] - - def assertSuccessfulRawQuery(self, model, query, expected_results, - expected_annotations=(), params=[], translations=None): - """ - Execute the passed query against the passed model and check the output - """ - results = list(model.objects.raw(query, params=params, translations=translations)) - self.assertProcessed(model, results, expected_results, expected_annotations) - self.assertAnnotations(results, expected_annotations) - - def assertProcessed(self, model, results, orig, expected_annotations=()): - """ - Compare the results of a raw query against expected results - """ - self.assertEqual(len(results), len(orig)) - for index, item in enumerate(results): - orig_item = orig[index] - for annotation in expected_annotations: - setattr(orig_item, *annotation) - - for field in model._meta.fields: - # Check that all values on the model are equal - self.assertEquals(getattr(item,field.attname), - getattr(orig_item,field.attname)) - # This includes checking that they are the same type - self.assertEquals(type(getattr(item,field.attname)), - type(getattr(orig_item,field.attname))) - - def assertNoAnnotations(self, results): - """ - Check that the results of a raw query contain no annotations - """ - self.assertAnnotations(results, ()) - - def assertAnnotations(self, results, expected_annotations): - """ - Check that the passed raw query results contain the expected - annotations - """ - if expected_annotations: - for index, result in enumerate(results): - annotation, value = expected_annotations[index] - self.assertTrue(hasattr(result, annotation)) - self.assertEqual(getattr(result, annotation), value) - - def assert_num_queries(self, n, func, *args, **kwargs): - old_DEBUG = settings.DEBUG - settings.DEBUG = True - starting_queries = len(connection.queries) - try: - func(*args, **kwargs) - finally: - settings.DEBUG = old_DEBUG - self.assertEqual(starting_queries + n, len(connection.queries)) - - def testSimpleRawQuery(self): - """ - Basic test of raw query with a simple database query - """ - query = "SELECT * FROM raw_query_author" - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors) - - def testRawQueryLazy(self): - """ - Raw queries are lazy: they aren't actually executed until they're - iterated over. - """ - q = Author.objects.raw('SELECT * FROM raw_query_author') - self.assert_(q.query.cursor is None) - list(q) - self.assert_(q.query.cursor is not None) - - def testFkeyRawQuery(self): - """ - Test of a simple raw query against a model containing a foreign key - """ - query = "SELECT * FROM raw_query_book" - books = Book.objects.all() - self.assertSuccessfulRawQuery(Book, query, books) - - def testDBColumnHandler(self): - """ - Test of a simple raw query against a model containing a field with - db_column defined. - """ - query = "SELECT * FROM raw_query_coffee" - coffees = Coffee.objects.all() - self.assertSuccessfulRawQuery(Coffee, query, coffees) - - def testOrderHandler(self): - """ - Test of raw raw query's tolerance for columns being returned in any - order - """ - selects = ( - ('dob, last_name, first_name, id'), - ('last_name, dob, first_name, id'), - ('first_name, last_name, dob, id'), - ) - - for select in selects: - query = "SELECT %s FROM raw_query_author" % select - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors) - - def testTranslations(self): - """ - Test of raw query's optional ability to translate unexpected result - column names to specific model fields - """ - query = "SELECT first_name AS first, last_name AS last, dob, id FROM raw_query_author" - translations = {'first': 'first_name', 'last': 'last_name'} - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors, translations=translations) - - def testParams(self): - """ - Test passing optional query parameters - """ - query = "SELECT * FROM raw_query_author WHERE first_name = %s" - author = Author.objects.all()[2] - params = [author.first_name] - results = list(Author.objects.raw(query, params=params)) - self.assertProcessed(Author, results, [author]) - self.assertNoAnnotations(results) - self.assertEqual(len(results), 1) - - def testManyToMany(self): - """ - Test of a simple raw query against a model containing a m2m field - """ - query = "SELECT * FROM raw_query_reviewer" - reviewers = Reviewer.objects.all() - self.assertSuccessfulRawQuery(Reviewer, query, reviewers) - - def testExtraConversions(self): - """ - Test to insure that extra translations are ignored. - """ - query = "SELECT * FROM raw_query_author" - translations = {'something': 'else'} - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors, translations=translations) - - def testMissingFields(self): - query = "SELECT id, first_name, dob FROM raw_query_author" - for author in Author.objects.raw(query): - self.assertNotEqual(author.first_name, None) - # last_name isn't given, but it will be retrieved on demand - self.assertNotEqual(author.last_name, None) - - def testMissingFieldsWithoutPK(self): - query = "SELECT first_name, dob FROM raw_query_author" - try: - list(Author.objects.raw(query)) - self.fail('Query without primary key should fail') - except InvalidQuery: - pass - - def testAnnotations(self): - query = "SELECT a.*, count(b.id) as book_count FROM raw_query_author a LEFT JOIN raw_query_book b ON a.id = b.author_id GROUP BY a.id, a.first_name, a.last_name, a.dob ORDER BY a.id" - expected_annotations = ( - ('book_count', 3), - ('book_count', 0), - ('book_count', 1), - ('book_count', 0), - ) - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors, expected_annotations) - - def testInvalidQuery(self): - query = "UPDATE raw_query_author SET first_name='thing' WHERE first_name='Joe'" - self.assertRaises(InvalidQuery, Author.objects.raw, query) - - def testWhiteSpaceQuery(self): - query = " SELECT * FROM raw_query_author" - authors = Author.objects.all() - self.assertSuccessfulRawQuery(Author, query, authors) - - def testMultipleIterations(self): - query = "SELECT * FROM raw_query_author" - normal_authors = Author.objects.all() - raw_authors = Author.objects.raw(query) - - # First Iteration - first_iterations = 0 - for index, raw_author in enumerate(raw_authors): - self.assertEqual(normal_authors[index], raw_author) - first_iterations += 1 - - # Second Iteration - second_iterations = 0 - for index, raw_author in enumerate(raw_authors): - self.assertEqual(normal_authors[index], raw_author) - second_iterations += 1 - - self.assertEqual(first_iterations, second_iterations) - - def testGetItem(self): - # Indexing on RawQuerySets - query = "SELECT * FROM raw_query_author ORDER BY id ASC" - third_author = Author.objects.raw(query)[2] - self.assertEqual(third_author.first_name, 'Bob') - - first_two = Author.objects.raw(query)[0:2] - self.assertEquals(len(first_two), 2) - - self.assertRaises(TypeError, lambda: Author.objects.raw(query)['test']) - - def test_inheritance(self): - # date is the end of the Cuban Missile Crisis, I have no idea when - # Wesley was bron - f = FriendlyAuthor.objects.create(first_name="Wesley", last_name="Chun", - dob=date(1962, 10, 28)) - query = "SELECT * FROM raw_query_friendlyauthor" - self.assertEqual( - [o.pk for o in FriendlyAuthor.objects.raw(query)], [f.pk] - ) - - def test_query_count(self): - self.assert_num_queries(1, - list, Author.objects.raw("SELECT * FROM raw_query_author") - ) diff --git a/parts/django/tests/modeltests/reserved_names/__init__.py b/parts/django/tests/modeltests/reserved_names/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/reserved_names/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/reserved_names/models.py b/parts/django/tests/modeltests/reserved_names/models.py deleted file mode 100644 index d8c1238..0000000 --- a/parts/django/tests/modeltests/reserved_names/models.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -18. Using SQL reserved names - -Need to use a reserved SQL name as a column name or table name? Need to include -a hyphen in a column or table name? No problem. Django quotes names -appropriately behind the scenes, so your database won't complain about -reserved-name usage. -""" - -from django.db import models - -class Thing(models.Model): - when = models.CharField(max_length=1, primary_key=True) - join = models.CharField(max_length=1) - like = models.CharField(max_length=1) - drop = models.CharField(max_length=1) - alter = models.CharField(max_length=1) - having = models.CharField(max_length=1) - where = models.DateField(max_length=1) - has_hyphen = models.CharField(max_length=1, db_column='has-hyphen') - class Meta: - db_table = 'select' - - def __unicode__(self): - return self.when
\ No newline at end of file diff --git a/parts/django/tests/modeltests/reserved_names/tests.py b/parts/django/tests/modeltests/reserved_names/tests.py deleted file mode 100644 index b7e4867..0000000 --- a/parts/django/tests/modeltests/reserved_names/tests.py +++ /dev/null @@ -1,48 +0,0 @@ -import datetime - -from django.test import TestCase - -from models import Thing - -class ReservedNameTests(TestCase): - def generate(self): - day1 = datetime.date(2005, 1, 1) - t = Thing.objects.create(when='a', join='b', like='c', drop='d', - alter='e', having='f', where=day1, has_hyphen='h') - day2 = datetime.date(2006, 2, 2) - u = Thing.objects.create(when='h', join='i', like='j', drop='k', - alter='l', having='m', where=day2) - - def test_simple(self): - day1 = datetime.date(2005, 1, 1) - t = Thing.objects.create(when='a', join='b', like='c', drop='d', - alter='e', having='f', where=day1, has_hyphen='h') - self.assertEqual(t.when, 'a') - - day2 = datetime.date(2006, 2, 2) - u = Thing.objects.create(when='h', join='i', like='j', drop='k', - alter='l', having='m', where=day2) - self.assertEqual(u.when, 'h') - - def test_order_by(self): - self.generate() - things = [t.when for t in Thing.objects.order_by('when')] - self.assertEqual(things, ['a', 'h']) - - def test_fields(self): - self.generate() - v = Thing.objects.get(pk='a') - self.assertEqual(v.join, 'b') - self.assertEqual(v.where, datetime.date(year=2005, month=1, day=1)) - - def test_dates(self): - self.generate() - resp = Thing.objects.dates('where', 'year') - self.assertEqual(list(resp), [ - datetime.datetime(2005, 1, 1, 0, 0), - datetime.datetime(2006, 1, 1, 0, 0), - ]) - - def test_month_filter(self): - self.generate() - self.assertEqual(Thing.objects.filter(where__month=1)[0].when, 'a') diff --git a/parts/django/tests/modeltests/reverse_lookup/__init__.py b/parts/django/tests/modeltests/reverse_lookup/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/reverse_lookup/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/reverse_lookup/models.py b/parts/django/tests/modeltests/reverse_lookup/models.py deleted file mode 100644 index 2ffdc39..0000000 --- a/parts/django/tests/modeltests/reverse_lookup/models.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -25. Reverse lookups - -This demonstrates the reverse lookup features of the database API. -""" - -from django.db import models - -class User(models.Model): - name = models.CharField(max_length=200) - - def __unicode__(self): - return self.name - -class Poll(models.Model): - question = models.CharField(max_length=200) - creator = models.ForeignKey(User) - - def __unicode__(self): - return self.question - -class Choice(models.Model): - name = models.CharField(max_length=100) - poll = models.ForeignKey(Poll, related_name="poll_choice") - related_poll = models.ForeignKey(Poll, related_name="related_choice") - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/modeltests/reverse_lookup/tests.py b/parts/django/tests/modeltests/reverse_lookup/tests.py deleted file mode 100644 index 9a6e306..0000000 --- a/parts/django/tests/modeltests/reverse_lookup/tests.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.test import TestCase -from django.core.exceptions import FieldError - -from models import User, Poll, Choice - -class ReverseLookupTests(TestCase): - - def setUp(self): - john = User.objects.create(name="John Doe") - jim = User.objects.create(name="Jim Bo") - first_poll = Poll.objects.create( - question="What's the first question?", - creator=john - ) - second_poll = Poll.objects.create( - question="What's the second question?", - creator=jim - ) - new_choice = Choice.objects.create( - poll=first_poll, - related_poll=second_poll, - name="This is the answer." - ) - - def test_reverse_by_field(self): - u1 = User.objects.get( - poll__question__exact="What's the first question?" - ) - self.assertEqual(u1.name, "John Doe") - - u2 = User.objects.get( - poll__question__exact="What's the second question?" - ) - self.assertEqual(u2.name, "Jim Bo") - - def test_reverse_by_related_name(self): - p1 = Poll.objects.get(poll_choice__name__exact="This is the answer.") - self.assertEqual(p1.question, "What's the first question?") - - p2 = Poll.objects.get( - related_choice__name__exact="This is the answer.") - self.assertEqual(p2.question, "What's the second question?") - - def test_reverse_field_name_disallowed(self): - """ - If a related_name is given you can't use the field name instead - """ - self.assertRaises(FieldError, Poll.objects.get, - choice__name__exact="This is the answer") diff --git a/parts/django/tests/modeltests/save_delete_hooks/__init__.py b/parts/django/tests/modeltests/save_delete_hooks/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/save_delete_hooks/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/save_delete_hooks/models.py b/parts/django/tests/modeltests/save_delete_hooks/models.py deleted file mode 100644 index 515c7f6..0000000 --- a/parts/django/tests/modeltests/save_delete_hooks/models.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -13. Adding hooks before/after saving and deleting - -To execute arbitrary code around ``save()`` and ``delete()``, just subclass -the methods. -""" - -from django.db import models - - -class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=20) - - def __init__(self, *args, **kwargs): - super(Person, self).__init__(*args, **kwargs) - self.data = [] - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - - def save(self, *args, **kwargs): - self.data.append("Before save") - # Call the "real" save() method - super(Person, self).save(*args, **kwargs) - self.data.append("After save") - - def delete(self): - self.data.append("Before deletion") - # Call the "real" delete() method - super(Person, self).delete() - self.data.append("After deletion") diff --git a/parts/django/tests/modeltests/save_delete_hooks/tests.py b/parts/django/tests/modeltests/save_delete_hooks/tests.py deleted file mode 100644 index dc7b8ee..0000000 --- a/parts/django/tests/modeltests/save_delete_hooks/tests.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.test import TestCase - -from models import Person - - -class SaveDeleteHookTests(TestCase): - def test_basic(self): - p = Person(first_name="John", last_name="Smith") - self.assertEqual(p.data, []) - p.save() - self.assertEqual(p.data, [ - "Before save", - "After save", - ]) - - self.assertQuerysetEqual( - Person.objects.all(), [ - "John Smith", - ], - unicode - ) - - p.delete() - self.assertEqual(p.data, [ - "Before save", - "After save", - "Before deletion", - "After deletion", - ]) - self.assertQuerysetEqual(Person.objects.all(), []) diff --git a/parts/django/tests/modeltests/select_related/__init__.py b/parts/django/tests/modeltests/select_related/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/select_related/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/select_related/models.py b/parts/django/tests/modeltests/select_related/models.py deleted file mode 100644 index 3c2e772..0000000 --- a/parts/django/tests/modeltests/select_related/models.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -41. Tests for select_related() - -``select_related()`` follows all relationships and pre-caches any foreign key -values so that complex trees can be fetched in a single query. However, this -isn't always a good idea, so the ``depth`` argument control how many "levels" -the select-related behavior will traverse. -""" - -from django.db import models - -# Who remembers high school biology? - -class Domain(models.Model): - name = models.CharField(max_length=50) - def __unicode__(self): - return self.name - -class Kingdom(models.Model): - name = models.CharField(max_length=50) - domain = models.ForeignKey(Domain) - def __unicode__(self): - return self.name - -class Phylum(models.Model): - name = models.CharField(max_length=50) - kingdom = models.ForeignKey(Kingdom) - def __unicode__(self): - return self.name - -class Klass(models.Model): - name = models.CharField(max_length=50) - phylum = models.ForeignKey(Phylum) - def __unicode__(self): - return self.name - -class Order(models.Model): - name = models.CharField(max_length=50) - klass = models.ForeignKey(Klass) - def __unicode__(self): - return self.name - -class Family(models.Model): - name = models.CharField(max_length=50) - order = models.ForeignKey(Order) - def __unicode__(self): - return self.name - -class Genus(models.Model): - name = models.CharField(max_length=50) - family = models.ForeignKey(Family) - def __unicode__(self): - return self.name - -class Species(models.Model): - name = models.CharField(max_length=50) - genus = models.ForeignKey(Genus) - def __unicode__(self): - return self.name
\ No newline at end of file diff --git a/parts/django/tests/modeltests/select_related/tests.py b/parts/django/tests/modeltests/select_related/tests.py deleted file mode 100644 index 72b3ab2..0000000 --- a/parts/django/tests/modeltests/select_related/tests.py +++ /dev/null @@ -1,166 +0,0 @@ -from django.test import TestCase -from django.conf import settings -from django import db - -from models import Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species - -class SelectRelatedTests(TestCase): - - def create_tree(self, stringtree): - """ - Helper to create a complete tree. - """ - names = stringtree.split() - models = [Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species] - assert len(names) == len(models), (names, models) - - parent = None - for name, model in zip(names, models): - try: - obj = model.objects.get(name=name) - except model.DoesNotExist: - obj = model(name=name) - if parent: - setattr(obj, parent.__class__.__name__.lower(), parent) - obj.save() - parent = obj - - def create_base_data(self): - self.create_tree("Eukaryota Animalia Anthropoda Insecta Diptera Drosophilidae Drosophila melanogaster") - self.create_tree("Eukaryota Animalia Chordata Mammalia Primates Hominidae Homo sapiens") - self.create_tree("Eukaryota Plantae Magnoliophyta Magnoliopsida Fabales Fabaceae Pisum sativum") - self.create_tree("Eukaryota Fungi Basidiomycota Homobasidiomycatae Agaricales Amanitacae Amanita muscaria") - - def setUp(self): - # The test runner sets settings.DEBUG to False, but we want to gather - # queries so we'll set it to True here and reset it at the end of the - # test case. - self.create_base_data() - settings.DEBUG = True - db.reset_queries() - - def tearDown(self): - settings.DEBUG = False - - def test_access_fks_without_select_related(self): - """ - Normally, accessing FKs doesn't fill in related objects - """ - fly = Species.objects.get(name="melanogaster") - domain = fly.genus.family.order.klass.phylum.kingdom.domain - self.assertEqual(domain.name, 'Eukaryota') - self.assertEqual(len(db.connection.queries), 8) - - def test_access_fks_with_select_related(self): - """ - A select_related() call will fill in those related objects without any - extra queries - """ - person = Species.objects.select_related(depth=10).get(name="sapiens") - domain = person.genus.family.order.klass.phylum.kingdom.domain - self.assertEqual(domain.name, 'Eukaryota') - self.assertEqual(len(db.connection.queries), 1) - - def test_list_without_select_related(self): - """ - select_related() also of course applies to entire lists, not just - items. This test verifies the expected behavior without select_related. - """ - world = Species.objects.all() - families = [o.genus.family.name for o in world] - self.assertEqual(sorted(families), [ - 'Amanitacae', - 'Drosophilidae', - 'Fabaceae', - 'Hominidae', - ]) - self.assertEqual(len(db.connection.queries), 9) - - def test_list_with_select_related(self): - """ - select_related() also of course applies to entire lists, not just - items. This test verifies the expected behavior with select_related. - """ - world = Species.objects.all().select_related() - families = [o.genus.family.name for o in world] - self.assertEqual(sorted(families), [ - 'Amanitacae', - 'Drosophilidae', - 'Fabaceae', - 'Hominidae', - ]) - self.assertEqual(len(db.connection.queries), 1) - - def test_depth(self, depth=1, expected=7): - """ - The "depth" argument to select_related() will stop the descent at a - particular level. - """ - pea = Species.objects.select_related(depth=depth).get(name="sativum") - self.assertEqual( - pea.genus.family.order.klass.phylum.kingdom.domain.name, - 'Eukaryota' - ) - # Notice: one fewer queries than above because of depth=1 - self.assertEqual(len(db.connection.queries), expected) - - def test_larger_depth(self): - """ - The "depth" argument to select_related() will stop the descent at a - particular level. This tests a larger depth value. - """ - self.test_depth(depth=5, expected=3) - - def test_list_with_depth(self): - """ - The "depth" argument to select_related() will stop the descent at a - particular level. This can be used on lists as well. - """ - world = Species.objects.all().select_related(depth=2) - orders = [o.genus.family.order.name for o in world] - self.assertEqual(sorted(orders), - ['Agaricales', 'Diptera', 'Fabales', 'Primates']) - self.assertEqual(len(db.connection.queries), 5) - - def test_select_related_with_extra(self): - s = Species.objects.all().select_related(depth=1)\ - .extra(select={'a': 'select_related_species.id + 10'})[0] - self.assertEqual(s.id + 10, s.a) - - def test_certain_fields(self): - """ - The optional fields passed to select_related() control which related - models we pull in. This allows for smaller queries and can act as an - alternative (or, in addition to) the depth parameter. - - In this case, we explicitly say to select the 'genus' and - 'genus.family' models, leading to the same number of queries as before. - """ - world = Species.objects.select_related('genus__family') - families = [o.genus.family.name for o in world] - self.assertEqual(sorted(families), - ['Amanitacae', 'Drosophilidae', 'Fabaceae', 'Hominidae']) - self.assertEqual(len(db.connection.queries), 1) - - def test_more_certain_fields(self): - """ - In this case, we explicitly say to select the 'genus' and - 'genus.family' models, leading to the same number of queries as before. - """ - world = Species.objects.filter(genus__name='Amanita')\ - .select_related('genus__family') - orders = [o.genus.family.order.name for o in world] - self.assertEqual(orders, [u'Agaricales']) - self.assertEqual(len(db.connection.queries), 2) - - def test_field_traversal(self): - s = Species.objects.all().select_related('genus__family__order' - ).order_by('id')[0:1].get().genus.family.order.name - self.assertEqual(s, u'Diptera') - self.assertEqual(len(db.connection.queries), 1) - - def test_depth_fields_fails(self): - self.assertRaises(TypeError, - Species.objects.select_related, - 'genus__family__order', depth=4 - ) diff --git a/parts/django/tests/modeltests/serializers/__init__.py b/parts/django/tests/modeltests/serializers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/serializers/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/serializers/models.py b/parts/django/tests/modeltests/serializers/models.py deleted file mode 100644 index c12e73f..0000000 --- a/parts/django/tests/modeltests/serializers/models.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- -""" -42. Serialization - -``django.core.serializers`` provides interfaces to converting Django -``QuerySet`` objects to and from "flat" data (i.e. strings). -""" - -from decimal import Decimal -from django.db import models - -class Category(models.Model): - name = models.CharField(max_length=20) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - -class Author(models.Model): - name = models.CharField(max_length=20) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - -class Article(models.Model): - author = models.ForeignKey(Author) - headline = models.CharField(max_length=50) - pub_date = models.DateTimeField() - categories = models.ManyToManyField(Category) - - class Meta: - ordering = ('pub_date',) - - def __unicode__(self): - return self.headline - - -class AuthorProfile(models.Model): - author = models.OneToOneField(Author, primary_key=True) - date_of_birth = models.DateField() - - def __unicode__(self): - return u"Profile of %s" % self.author - - -class Actor(models.Model): - name = models.CharField(max_length=20, primary_key=True) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - -class Movie(models.Model): - actor = models.ForeignKey(Actor) - title = models.CharField(max_length=50) - price = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal('0.00')) - - class Meta: - ordering = ('title',) - - def __unicode__(self): - return self.title - - -class Score(models.Model): - score = models.FloatField() - - -class Team(object): - def __init__(self, title): - self.title = title - - def __unicode__(self): - raise NotImplementedError("Not so simple") - - def __str__(self): - raise NotImplementedError("Not so simple") - - def to_string(self): - return "%s" % self.title - - -class TeamField(models.CharField): - __metaclass__ = models.SubfieldBase - - def __init__(self): - super(TeamField, self).__init__(max_length=100) - - def get_db_prep_save(self, value): - return unicode(value.title) - - def to_python(self, value): - if isinstance(value, Team): - return value - return Team(value) - - def value_to_string(self, obj): - return self._get_val_from_obj(obj).to_string() - - -class Player(models.Model): - name = models.CharField(max_length=50) - rank = models.IntegerField() - team = TeamField() - - def __unicode__(self): - return u'%s (%d) playing for %s' % (self.name, self.rank, self.team.to_string()) diff --git a/parts/django/tests/modeltests/serializers/tests.py b/parts/django/tests/modeltests/serializers/tests.py deleted file mode 100644 index 9b648a8..0000000 --- a/parts/django/tests/modeltests/serializers/tests.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from StringIO import StringIO -from xml.dom import minidom - -from django.core import serializers -from django.db import transaction -from django.test import TestCase, TransactionTestCase, Approximate -from django.utils import simplejson - -from models import Category, Author, Article, AuthorProfile, Actor, \ - Movie, Score, Player, Team - -class SerializersTestBase(object): - @staticmethod - def _comparison_value(value): - return value - - def setUp(self): - sports = Category.objects.create(name="Sports") - music = Category.objects.create(name="Music") - op_ed = Category.objects.create(name="Op-Ed") - - self.joe = Author.objects.create(name="Joe") - self.jane = Author.objects.create(name="Jane") - - self.a1 = Article( - author=self.jane, - headline="Poker has no place on ESPN", - pub_date=datetime(2006, 6, 16, 11, 00) - ) - self.a1.save() - self.a1.categories = [sports, op_ed] - - self.a2 = Article( - author=self.joe, - headline="Time to reform copyright", - pub_date=datetime(2006, 6, 16, 13, 00, 11, 345) - ) - self.a2.save() - self.a2.categories = [music, op_ed] - - def test_serialize(self): - """Tests that basic serialization works.""" - serial_str = serializers.serialize(self.serializer_name, - Article.objects.all()) - self.assertTrue(self._validate_output(serial_str)) - - def test_serializer_roundtrip(self): - """Tests that serialized content can be deserialized.""" - serial_str = serializers.serialize(self.serializer_name, - Article.objects.all()) - models = list(serializers.deserialize(self.serializer_name, serial_str)) - self.assertEqual(len(models), 2) - - def test_altering_serialized_output(self): - """ - Tests the ability to create new objects by - modifying serialized content. - """ - old_headline = "Poker has no place on ESPN" - new_headline = "Poker has no place on television" - serial_str = serializers.serialize(self.serializer_name, - Article.objects.all()) - serial_str = serial_str.replace(old_headline, new_headline) - models = list(serializers.deserialize(self.serializer_name, serial_str)) - - # Prior to saving, old headline is in place - self.assertTrue(Article.objects.filter(headline=old_headline)) - self.assertFalse(Article.objects.filter(headline=new_headline)) - - for model in models: - model.save() - - # After saving, new headline is in place - self.assertTrue(Article.objects.filter(headline=new_headline)) - self.assertFalse(Article.objects.filter(headline=old_headline)) - - def test_one_to_one_as_pk(self): - """ - Tests that if you use your own primary key field - (such as a OneToOneField), it doesn't appear in the - serialized field list - it replaces the pk identifier. - """ - profile = AuthorProfile(author=self.joe, - date_of_birth=datetime(1970,1,1)) - profile.save() - serial_str = serializers.serialize(self.serializer_name, - AuthorProfile.objects.all()) - self.assertFalse(self._get_field_values(serial_str, 'author')) - - for obj in serializers.deserialize(self.serializer_name, serial_str): - self.assertEqual(obj.object.pk, self._comparison_value(self.joe.pk)) - - def test_serialize_field_subset(self): - """Tests that output can be restricted to a subset of fields""" - valid_fields = ('headline','pub_date') - invalid_fields = ("author", "categories") - serial_str = serializers.serialize(self.serializer_name, - Article.objects.all(), - fields=valid_fields) - for field_name in invalid_fields: - self.assertFalse(self._get_field_values(serial_str, field_name)) - - for field_name in valid_fields: - self.assertTrue(self._get_field_values(serial_str, field_name)) - - def test_serialize_unicode(self): - """Tests that unicode makes the roundtrip intact""" - actor_name = u"Za\u017c\u00f3\u0142\u0107" - movie_title = u'G\u0119\u015bl\u0105 ja\u017a\u0144' - ac = Actor(name=actor_name) - mv = Movie(title=movie_title, actor=ac) - ac.save() - mv.save() - - serial_str = serializers.serialize(self.serializer_name, [mv]) - self.assertEqual(self._get_field_values(serial_str, "title")[0], movie_title) - self.assertEqual(self._get_field_values(serial_str, "actor")[0], actor_name) - - obj_list = list(serializers.deserialize(self.serializer_name, serial_str)) - mv_obj = obj_list[0].object - self.assertEqual(mv_obj.title, movie_title) - - def test_serialize_with_null_pk(self): - """ - Tests that serialized data with no primary key results - in a model instance with no id - """ - category = Category(name="Reference") - serial_str = serializers.serialize(self.serializer_name, [category]) - pk_value = self._get_pk_values(serial_str)[0] - self.assertFalse(pk_value) - - cat_obj = list(serializers.deserialize(self.serializer_name, - serial_str))[0].object - self.assertEqual(cat_obj.id, None) - - def test_float_serialization(self): - """Tests that float values serialize and deserialize intact""" - sc = Score(score=3.4) - sc.save() - serial_str = serializers.serialize(self.serializer_name, [sc]) - deserial_objs = list(serializers.deserialize(self.serializer_name, - serial_str)) - self.assertEqual(deserial_objs[0].object.score, Approximate(3.4, places=1)) - - def test_custom_field_serialization(self): - """Tests that custom fields serialize and deserialize intact""" - team_str = "Spartak Moskva" - player = Player() - player.name = "Soslan Djanaev" - player.rank = 1 - player.team = Team(team_str) - player.save() - serial_str = serializers.serialize(self.serializer_name, - Player.objects.all()) - team = self._get_field_values(serial_str, "team") - self.assertTrue(team) - self.assertEqual(team[0], team_str) - - deserial_objs = list(serializers.deserialize(self.serializer_name, serial_str)) - self.assertEqual(deserial_objs[0].object.team.to_string(), - player.team.to_string()) - - def test_pre_1000ad_date(self): - """Tests that year values before 1000AD are properly formatted""" - # Regression for #12524 -- dates before 1000AD get prefixed - # 0's on the year - a = Article.objects.create( - author = self.jane, - headline = "Nobody remembers the early years", - pub_date = datetime(1, 2, 3, 4, 5, 6)) - - serial_str = serializers.serialize(self.serializer_name, [a]) - date_values = self._get_field_values(serial_str, "pub_date") - self.assertEquals(date_values[0], "0001-02-03 04:05:06") - - def test_pkless_serialized_strings(self): - """ - Tests that serialized strings without PKs - can be turned into models - """ - deserial_objs = list(serializers.deserialize(self.serializer_name, - self.pkless_str)) - for obj in deserial_objs: - self.assertFalse(obj.object.id) - obj.save() - self.assertEqual(Category.objects.all().count(), 4) - - -class SerializersTransactionTestBase(object): - def test_forward_refs(self): - """ - Tests that objects ids can be referenced before they are - defined in the serialization data. - """ - # The deserialization process needs to be contained - # within a transaction in order to test forward reference - # handling. - transaction.enter_transaction_management() - transaction.managed(True) - objs = serializers.deserialize(self.serializer_name, self.fwd_ref_str) - for obj in objs: - obj.save() - transaction.commit() - transaction.leave_transaction_management() - - for model_cls in (Category, Author, Article): - self.assertEqual(model_cls.objects.all().count(), 1) - art_obj = Article.objects.all()[0] - self.assertEqual(art_obj.categories.all().count(), 1) - self.assertEqual(art_obj.author.name, "Agnes") - - -class XmlSerializerTestCase(SerializersTestBase, TestCase): - serializer_name = "xml" - pkless_str = """<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object model="serializers.category"> - <field type="CharField" name="name">Reference</field> - </object> -</django-objects>""" - - @staticmethod - def _comparison_value(value): - # The XML serializer handles everything as strings, so comparisons - # need to be performed on the stringified value - return unicode(value) - - @staticmethod - def _validate_output(serial_str): - try: - minidom.parseString(serial_str) - except Exception: - return False - else: - return True - - @staticmethod - def _get_pk_values(serial_str): - ret_list = [] - dom = minidom.parseString(serial_str) - fields = dom.getElementsByTagName("object") - for field in fields: - ret_list.append(field.getAttribute("pk")) - return ret_list - - @staticmethod - def _get_field_values(serial_str, field_name): - ret_list = [] - dom = minidom.parseString(serial_str) - fields = dom.getElementsByTagName("field") - for field in fields: - if field.getAttribute("name") == field_name: - temp = [] - for child in field.childNodes: - temp.append(child.nodeValue) - ret_list.append("".join(temp)) - return ret_list - -class XmlSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase): - serializer_name = "xml" - fwd_ref_str = """<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="serializers.article"> - <field to="serializers.author" name="author" rel="ManyToOneRel">1</field> - <field type="CharField" name="headline">Forward references pose no problem</field> - <field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field> - <field to="serializers.category" name="categories" rel="ManyToManyRel"> - <object pk="1"></object> - </field> - </object> - <object pk="1" model="serializers.author"> - <field type="CharField" name="name">Agnes</field> - </object> - <object pk="1" model="serializers.category"> - <field type="CharField" name="name">Reference</field></object> -</django-objects>""" - - -class JsonSerializerTestCase(SerializersTestBase, TestCase): - serializer_name = "json" - pkless_str = """[{"pk": null, "model": "serializers.category", "fields": {"name": "Reference"}}]""" - - @staticmethod - def _validate_output(serial_str): - try: - simplejson.loads(serial_str) - except Exception: - return False - else: - return True - - @staticmethod - def _get_pk_values(serial_str): - ret_list = [] - serial_list = simplejson.loads(serial_str) - for obj_dict in serial_list: - ret_list.append(obj_dict["pk"]) - return ret_list - - @staticmethod - def _get_field_values(serial_str, field_name): - ret_list = [] - serial_list = simplejson.loads(serial_str) - for obj_dict in serial_list: - if field_name in obj_dict["fields"]: - ret_list.append(obj_dict["fields"][field_name]) - return ret_list - -class JsonSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase): - serializer_name = "json" - fwd_ref_str = """[ - { - "pk": 1, - "model": "serializers.article", - "fields": { - "headline": "Forward references pose no problem", - "pub_date": "2006-06-16 15:00:00", - "categories": [1], - "author": 1 - } - }, - { - "pk": 1, - "model": "serializers.category", - "fields": { - "name": "Reference" - } - }, - { - "pk": 1, - "model": "serializers.author", - "fields": { - "name": "Agnes" - } - }]""" - -try: - import yaml -except ImportError: - pass -else: - class YamlSerializerTestCase(SerializersTestBase, TestCase): - serializer_name = "yaml" - fwd_ref_str = """- fields: - headline: Forward references pose no problem - pub_date: 2006-06-16 15:00:00 - categories: [1] - author: 1 - pk: 1 - model: serializers.article -- fields: - name: Reference - pk: 1 - model: serializers.category -- fields: - name: Agnes - pk: 1 - model: serializers.author""" - - pkless_str = """- fields: - name: Reference - pk: null - model: serializers.category""" - - @staticmethod - def _validate_output(serial_str): - try: - yaml.load(StringIO(serial_str)) - except Exception: - return False - else: - return True - - @staticmethod - def _get_pk_values(serial_str): - ret_list = [] - stream = StringIO(serial_str) - for obj_dict in yaml.load(stream): - ret_list.append(obj_dict["pk"]) - return ret_list - - @staticmethod - def _get_field_values(serial_str, field_name): - ret_list = [] - stream = StringIO(serial_str) - for obj_dict in yaml.load(stream): - if "fields" in obj_dict and field_name in obj_dict["fields"]: - field_value = obj_dict["fields"][field_name] - # yaml.load will return non-string objects for some - # of the fields we are interested in, this ensures that - # everything comes back as a string - if isinstance(field_value, basestring): - ret_list.append(field_value) - else: - ret_list.append(str(field_value)) - return ret_list - - class YamlSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase): - serializer_name = "yaml" - fwd_ref_str = """- fields: - headline: Forward references pose no problem - pub_date: 2006-06-16 15:00:00 - categories: [1] - author: 1 - pk: 1 - model: serializers.article -- fields: - name: Reference - pk: 1 - model: serializers.category -- fields: - name: Agnes - pk: 1 - model: serializers.author""" diff --git a/parts/django/tests/modeltests/signals/__init__.py b/parts/django/tests/modeltests/signals/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/signals/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/signals/models.py b/parts/django/tests/modeltests/signals/models.py deleted file mode 100644 index f1250b4..0000000 --- a/parts/django/tests/modeltests/signals/models.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Testing signals before/after saving and deleting. -""" - -from django.db import models - - -class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=20) - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) diff --git a/parts/django/tests/modeltests/signals/tests.py b/parts/django/tests/modeltests/signals/tests.py deleted file mode 100644 index 27948c6..0000000 --- a/parts/django/tests/modeltests/signals/tests.py +++ /dev/null @@ -1,148 +0,0 @@ -from django.db.models import signals -from django.test import TestCase - -from models import Person - - -# #8285: signals can be any callable -class PostDeleteHandler(object): - def __init__(self, data): - self.data = data - - def __call__(self, signal, sender, instance, **kwargs): - self.data.append( - (instance, instance.id is None) - ) - -class MyReceiver(object): - def __init__(self, param): - self.param = param - self._run = False - - def __call__(self, signal, sender, **kwargs): - self._run = True - signal.disconnect(receiver=self, sender=sender) - -class SignalTests(TestCase): - def test_basic(self): - # Save up the number of connected signals so that we can check at the - # end that all the signals we register get properly unregistered (#9989) - pre_signals = ( - len(signals.pre_save.receivers), - len(signals.post_save.receivers), - len(signals.pre_delete.receivers), - len(signals.post_delete.receivers), - ) - - data = [] - - def pre_save_test(signal, sender, instance, **kwargs): - data.append( - (instance, kwargs.get("raw", False)) - ) - signals.pre_save.connect(pre_save_test) - - def post_save_test(signal, sender, instance, **kwargs): - data.append( - (instance, kwargs.get("created"), kwargs.get("raw", False)) - ) - signals.post_save.connect(post_save_test) - - def pre_delete_test(signal, sender, instance, **kwargs): - data.append( - (instance, instance.id is None) - ) - signals.pre_delete.connect(pre_delete_test) - - post_delete_test = PostDeleteHandler(data) - signals.post_delete.connect(post_delete_test) - - p1 = Person(first_name="John", last_name="Smith") - self.assertEqual(data, []) - p1.save() - self.assertEqual(data, [ - (p1, False), - (p1, True, False), - ]) - data[:] = [] - - p1.first_name = "Tom" - p1.save() - self.assertEqual(data, [ - (p1, False), - (p1, False, False), - ]) - data[:] = [] - - # Calling an internal method purely so that we can trigger a "raw" save. - p1.save_base(raw=True) - self.assertEqual(data, [ - (p1, True), - (p1, False, True), - ]) - data[:] = [] - - p1.delete() - self.assertEqual(data, [ - (p1, False), - (p1, False), - ]) - data[:] = [] - - p2 = Person(first_name="James", last_name="Jones") - p2.id = 99999 - p2.save() - self.assertEqual(data, [ - (p2, False), - (p2, True, False), - ]) - data[:] = [] - - p2.id = 99998 - p2.save() - self.assertEqual(data, [ - (p2, False), - (p2, True, False), - ]) - data[:] = [] - - p2.delete() - self.assertEqual(data, [ - (p2, False), - (p2, False) - ]) - - self.assertQuerysetEqual( - Person.objects.all(), [ - "James Jones", - ], - unicode - ) - - signals.post_delete.disconnect(post_delete_test) - signals.pre_delete.disconnect(pre_delete_test) - signals.post_save.disconnect(post_save_test) - signals.pre_save.disconnect(pre_save_test) - - # Check that all our signals got disconnected properly. - post_signals = ( - len(signals.pre_save.receivers), - len(signals.post_save.receivers), - len(signals.pre_delete.receivers), - len(signals.post_delete.receivers), - ) - self.assertEqual(pre_signals, post_signals) - - def test_disconnect_in_dispatch(self): - """ - Test that signals that disconnect when being called don't mess future - dispatching. - """ - a, b = MyReceiver(1), MyReceiver(2) - signals.post_save.connect(sender=Person, receiver=a) - signals.post_save.connect(sender=Person, receiver=b) - p = Person.objects.create(first_name='John', last_name='Smith') - - self.assertTrue(a._run) - self.assertTrue(b._run) - self.assertEqual(signals.post_save.receivers, []) diff --git a/parts/django/tests/modeltests/str/__init__.py b/parts/django/tests/modeltests/str/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/str/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/str/models.py b/parts/django/tests/modeltests/str/models.py deleted file mode 100644 index 84b8d67..0000000 --- a/parts/django/tests/modeltests/str/models.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -""" -2. Adding __str__() or __unicode__() to models - -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 - -class Article(models.Model): - headline = models.CharField(max_length=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(max_length=100) - pub_date = models.DateTimeField() - - def __unicode__(self): - return self.headline
\ No newline at end of file diff --git a/parts/django/tests/modeltests/str/tests.py b/parts/django/tests/modeltests/str/tests.py deleted file mode 100644 index 4e4c765..0000000 --- a/parts/django/tests/modeltests/str/tests.py +++ /dev/null @@ -1,23 +0,0 @@ - # -*- coding: utf-8 -*- -import datetime - -from django.test import TestCase - -from models import Article, InternationalArticle - -class SimpleTests(TestCase): - def test_basic(self): - a = Article.objects.create( - headline='Area man programs in Python', - pub_date=datetime.datetime(2005, 7, 28) - ) - self.assertEqual(str(a), 'Area man programs in Python') - self.assertEqual(repr(a), '<Article: Area man programs in Python>') - - def test_international(self): - a = InternationalArticle.objects.create( - headline=u'Girl wins €12.500 in lottery', - pub_date=datetime.datetime(2005, 7, 28) - ) - # The default str() output will be the UTF-8 encoded output of __unicode__(). - self.assertEqual(str(a), 'Girl wins \xe2\x82\xac12.500 in lottery')
\ No newline at end of file diff --git a/parts/django/tests/modeltests/test_client/__init__.py b/parts/django/tests/modeltests/test_client/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/test_client/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/test_client/fixtures/testdata.json b/parts/django/tests/modeltests/test_client/fixtures/testdata.json deleted file mode 100644 index 0dcf625..0000000 --- a/parts/django/tests/modeltests/test_client/fixtures/testdata.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { - "pk": "1", - "model": "auth.user", - "fields": { - "username": "testclient", - "first_name": "Test", - "last_name": "Client", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "2", - "model": "auth.user", - "fields": { - "username": "inactive", - "first_name": "Inactive", - "last_name": "User", - "is_active": false, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "3", - "model": "auth.user", - "fields": { - "username": "staff", - "first_name": "Staff", - "last_name": "Member", - "is_active": true, - "is_superuser": false, - "is_staff": true, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/modeltests/test_client/models.py b/parts/django/tests/modeltests/test_client/models.py deleted file mode 100644 index 654f649..0000000 --- a/parts/django/tests/modeltests/test_client/models.py +++ /dev/null @@ -1,459 +0,0 @@ -# coding: utf-8 -""" -39. Testing using the Test Client - -The test client is a class that can act like a simple -browser for testing purposes. - -It allows the user to compose GET and POST requests, and -obtain the response that the server gave to those requests. -The server Response objects are annotated with the details -of the contexts and templates that were rendered during the -process of serving the request. - -``Client`` objects are stateful - they will retain cookie (and -thus session) details for the lifetime of the ``Client`` instance. - -This is not intended as a replacement for Twill, Selenium, or -other browser automation frameworks - it is here to allow -testing against the contexts and templates produced by a view, -rather than the HTML rendered to the end-user. - -""" -from django.test import Client, TestCase -from django.conf import settings -from django.core import mail - -class ClientTest(TestCase): - fixtures = ['testdata.json'] - - def test_get_view(self): - "GET a 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'], u'\xf2') - self.assertEqual(response.template.name, 'GET Template') - - def test_get_post_view(self): - "GET a view that normally expects POSTs" - response = self.client.get('/test_client/post_view/', {}) - - # Check some response details - self.assertEqual(response.status_code, 200) - self.assertEqual(response.template.name, 'Empty GET Template') - self.assertTemplateUsed(response, 'Empty GET Template') - self.assertTemplateNotUsed(response, 'Empty POST Template') - - def test_empty_post(self): - "POST an empty dictionary to a view" - response = self.client.post('/test_client/post_view/', {}) - - # Check some response details - self.assertEqual(response.status_code, 200) - self.assertEqual(response.template.name, 'Empty POST Template') - self.assertTemplateNotUsed(response, 'Empty GET Template') - self.assertTemplateUsed(response, 'Empty POST Template') - - def test_post(self): - "POST some data to a view" - post_data = { - 'value': 37 - } - response = self.client.post('/test_client/post_view/', post_data) - - # Check some response details - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['data'], '37') - self.assertEqual(response.template.name, 'POST Template') - self.assertTrue('Data received' in response.content) - - def test_response_headers(self): - "Check the value of HTTP headers returned in a response" - response = self.client.get("/test_client/header_view/") - - self.assertEquals(response['X-DJANGO-TEST'], 'Slartibartfast') - - def test_raw_post(self): - "POST raw data (with a content type) to a view" - test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>""" - response = self.client.post("/test_client/raw_post_view/", test_doc, - content_type="text/xml") - self.assertEqual(response.status_code, 200) - self.assertEqual(response.template.name, "Book template") - self.assertEqual(response.content, "Blink - Malcolm Gladwell") - - def test_redirect(self): - "GET a URL that redirects elsewhere" - response = self.client.get('/test_client/redirect_view/') - # Check that the response was a 302 (redirect) and that - # assertRedirect() understands to put an implicit http://testserver/ in - # front of non-absolute URLs. - self.assertRedirects(response, '/test_client/get_view/') - - host = 'django.testserver' - client_providing_host = Client(HTTP_HOST=host) - response = client_providing_host.get('/test_client/redirect_view/') - # Check that the response was a 302 (redirect) with absolute URI - self.assertRedirects(response, '/test_client/get_view/', host=host) - - def test_redirect_with_query(self): - "GET a URL that redirects with given GET parameters" - response = self.client.get('/test_client/redirect_view/', {'var': 'value'}) - - # Check if parameters are intact - self.assertRedirects(response, 'http://testserver/test_client/get_view/?var=value') - - def test_permanent_redirect(self): - "GET a URL that redirects permanently elsewhere" - response = self.client.get('/test_client/permanent_redirect_view/') - # Check that the response was a 301 (permanent redirect) - self.assertRedirects(response, 'http://testserver/test_client/get_view/', status_code=301) - - client_providing_host = Client(HTTP_HOST='django.testserver') - response = client_providing_host.get('/test_client/permanent_redirect_view/') - # Check that the response was a 301 (permanent redirect) with absolute URI - self.assertRedirects(response, 'http://django.testserver/test_client/get_view/', status_code=301) - - def test_temporary_redirect(self): - "GET a URL that does a non-permanent redirect" - response = self.client.get('/test_client/temporary_redirect_view/') - # Check that the response was a 302 (non-permanent redirect) - self.assertRedirects(response, 'http://testserver/test_client/get_view/', status_code=302) - - def test_redirect_to_strange_location(self): - "GET a URL that redirects to a non-200 page" - response = self.client.get('/test_client/double_redirect_view/') - - # Check that the response was a 302, and that - # the attempt to get the redirection location returned 301 when retrieved - self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', target_status_code=301) - - def test_follow_redirect(self): - "A URL that redirects can be followed to termination." - response = self.client.get('/test_client/double_redirect_view/', follow=True) - self.assertRedirects(response, 'http://testserver/test_client/get_view/', status_code=302, target_status_code=200) - self.assertEquals(len(response.redirect_chain), 2) - - def test_redirect_http(self): - "GET a URL that redirects to an http URI" - response = self.client.get('/test_client/http_redirect_view/',follow=True) - self.assertFalse(response.test_was_secure_request) - - def test_redirect_https(self): - "GET a URL that redirects to an https URI" - response = self.client.get('/test_client/https_redirect_view/',follow=True) - self.assertTrue(response.test_was_secure_request) - - def test_notfound_response(self): - "GET a URL that responds as '404:Not Found'" - response = self.client.get('/test_client/bad_view/') - - # Check that the response was a 404, and that the content contains MAGIC - self.assertContains(response, 'MAGIC', status_code=404) - - def test_valid_form(self): - "POST valid data to a form" - post_data = { - 'text': 'Hello World', - 'email': 'foo@example.com', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Valid POST Template") - - def test_valid_form_with_hints(self): - "GET a form, providing hints in the GET data" - hints = { - 'text': 'Hello World', - 'multi': ('b','c','e') - } - response = self.client.get('/test_client/form_view/', data=hints) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Form GET Template") - # Check that the multi-value data has been rolled out ok - self.assertContains(response, 'Select a valid choice.', 0) - - def test_incomplete_data_form(self): - "POST incomplete data to a form" - post_data = { - 'text': 'Hello World', - 'value': 37 - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertContains(response, 'This field is required.', 3) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - self.assertFormError(response, 'form', 'email', 'This field is required.') - self.assertFormError(response, 'form', 'single', 'This field is required.') - self.assertFormError(response, 'form', 'multi', 'This field is required.') - - def test_form_error(self): - "POST erroneous data to a form" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.') - - def test_valid_form_with_template(self): - "POST valid data to a form using multiple templates" - post_data = { - 'text': 'Hello World', - 'email': 'foo@example.com', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view_with_template/', post_data) - self.assertContains(response, 'POST data OK') - self.assertTemplateUsed(response, "form_view.html") - self.assertTemplateUsed(response, 'base.html') - self.assertTemplateNotUsed(response, "Valid POST Template") - - def test_incomplete_data_form_with_template(self): - "POST incomplete data to a form using multiple templates" - post_data = { - 'text': 'Hello World', - 'value': 37 - } - response = self.client.post('/test_client/form_view_with_template/', post_data) - self.assertContains(response, 'POST data has errors') - self.assertTemplateUsed(response, 'form_view.html') - self.assertTemplateUsed(response, 'base.html') - self.assertTemplateNotUsed(response, "Invalid POST Template") - - self.assertFormError(response, 'form', 'email', 'This field is required.') - self.assertFormError(response, 'form', 'single', 'This field is required.') - self.assertFormError(response, 'form', 'multi', 'This field is required.') - - def test_form_error_with_template(self): - "POST erroneous data to a form using multiple templates" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view_with_template/', post_data) - self.assertContains(response, 'POST data has errors') - self.assertTemplateUsed(response, "form_view.html") - self.assertTemplateUsed(response, 'base.html') - self.assertTemplateNotUsed(response, "Invalid POST Template") - - self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.') - - def test_unknown_page(self): - "GET an invalid URL" - response = self.client.get('/test_client/unknown_view/') - - # Check that the response was a 404 - self.assertEqual(response.status_code, 404) - - def test_view_with_login(self): - "Request a page that is protected with @login_required" - - # Get the page without logging in. Should result in 302. - response = self.client.get('/test_client/login_protected_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/login_protected_view/') - - # Log in - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Request a page that requires a login - response = self.client.get('/test_client/login_protected_view/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['user'].username, 'testclient') - - def test_view_with_method_login(self): - "Request a page that is protected with a @login_required method" - - # Get the page without logging in. Should result in 302. - response = self.client.get('/test_client/login_protected_method_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/login_protected_method_view/') - - # Log in - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Request a page that requires a login - response = self.client.get('/test_client/login_protected_method_view/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['user'].username, 'testclient') - - def test_view_with_login_and_custom_redirect(self): - "Request a page that is protected with @login_required(redirect_field_name='redirect_to')" - - # Get the page without logging in. Should result in 302. - response = self.client.get('/test_client/login_protected_view_custom_redirect/') - self.assertRedirects(response, 'http://testserver/accounts/login/?redirect_to=/test_client/login_protected_view_custom_redirect/') - - # Log in - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Request a page that requires a login - response = self.client.get('/test_client/login_protected_view_custom_redirect/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['user'].username, 'testclient') - - def test_view_with_bad_login(self): - "Request a page that is protected with @login, but use bad credentials" - - login = self.client.login(username='otheruser', password='nopassword') - self.assertFalse(login) - - def test_view_with_inactive_login(self): - "Request a page that is protected with @login, but use an inactive login" - - login = self.client.login(username='inactive', password='password') - self.assertFalse(login) - - def test_logout(self): - "Request a logout after logging in" - # Log in - self.client.login(username='testclient', password='password') - - # Request a page that requires a login - response = self.client.get('/test_client/login_protected_view/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['user'].username, 'testclient') - - # Log out - self.client.logout() - - # Request a page that requires a login - response = self.client.get('/test_client/login_protected_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/login_protected_view/') - - def test_view_with_permissions(self): - "Request a page that is protected with @permission_required" - - # Get the page without logging in. Should result in 302. - response = self.client.get('/test_client/permission_protected_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/permission_protected_view/') - - # Log in - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Log in with wrong permissions. Should result in 302. - response = self.client.get('/test_client/permission_protected_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/permission_protected_view/') - - # TODO: Log in with right permissions and request the page again - - def test_view_with_method_permissions(self): - "Request a page that is protected with a @permission_required method" - - # Get the page without logging in. Should result in 302. - response = self.client.get('/test_client/permission_protected_method_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/permission_protected_method_view/') - - # Log in - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Log in with wrong permissions. Should result in 302. - response = self.client.get('/test_client/permission_protected_method_view/') - self.assertRedirects(response, 'http://testserver/accounts/login/?next=/test_client/permission_protected_method_view/') - - # TODO: Log in with right permissions and request the page again - - def test_session_modifying_view(self): - "Request a page that modifies the session" - # Session value isn't set initially - try: - self.client.session['tobacconist'] - self.fail("Shouldn't have a session value") - except KeyError: - pass - - from django.contrib.sessions.models import Session - response = self.client.post('/test_client/session_view/') - - # Check that the session was modified - self.assertEquals(self.client.session['tobacconist'], 'hovercraft') - - def test_view_with_exception(self): - "Request a page that is known to throw an error" - self.assertRaises(KeyError, self.client.get, "/test_client/broken_view/") - - #Try the same assertion, a different way - try: - self.client.get('/test_client/broken_view/') - self.fail('Should raise an error') - except KeyError: - pass - - def test_mail_sending(self): - "Test that mail is redirected to a dummy outbox during test setup" - - response = self.client.get('/test_client/mail_sending_view/') - self.assertEqual(response.status_code, 200) - - self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].subject, 'Test message') - self.assertEqual(mail.outbox[0].body, 'This is a test email') - self.assertEqual(mail.outbox[0].from_email, 'from@example.com') - self.assertEqual(mail.outbox[0].to[0], 'first@example.com') - self.assertEqual(mail.outbox[0].to[1], 'second@example.com') - - def test_mass_mail_sending(self): - "Test that mass mail is redirected to a dummy outbox during test setup" - - response = self.client.get('/test_client/mass_mail_sending_view/') - self.assertEqual(response.status_code, 200) - - self.assertEqual(len(mail.outbox), 2) - self.assertEqual(mail.outbox[0].subject, 'First Test message') - self.assertEqual(mail.outbox[0].body, 'This is the first test email') - self.assertEqual(mail.outbox[0].from_email, 'from@example.com') - self.assertEqual(mail.outbox[0].to[0], 'first@example.com') - self.assertEqual(mail.outbox[0].to[1], 'second@example.com') - - self.assertEqual(mail.outbox[1].subject, 'Second Test message') - self.assertEqual(mail.outbox[1].body, 'This is the second test email') - 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') - -class CSRFEnabledClientTests(TestCase): - def setUp(self): - # Enable the CSRF middleware for this test - self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES - csrf_middleware_class = 'django.middleware.csrf.CsrfViewMiddleware' - if csrf_middleware_class not in settings.MIDDLEWARE_CLASSES: - settings.MIDDLEWARE_CLASSES += (csrf_middleware_class,) - - def tearDown(self): - settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES - - def test_csrf_enabled_client(self): - "A client can be instantiated with CSRF checks enabled" - csrf_client = Client(enforce_csrf_checks=True) - - # The normal client allows the post - response = self.client.post('/test_client/post_view/', {}) - self.assertEqual(response.status_code, 200) - - # The CSRF-enabled client rejects it - response = csrf_client.post('/test_client/post_view/', {}) - self.assertEqual(response.status_code, 403) diff --git a/parts/django/tests/modeltests/test_client/tests.py b/parts/django/tests/modeltests/test_client/tests.py deleted file mode 100644 index 09f292e..0000000 --- a/parts/django/tests/modeltests/test_client/tests.py +++ /dev/null @@ -1,20 +0,0 @@ -# Validate that you can override the default test suite - -import unittest - -def suite(): - """ - Define a suite that deliberately ignores a test defined in - this module. - """ - - testSuite = unittest.TestSuite() - testSuite.addTest(SampleTests('testGoodStuff')) - return testSuite - -class SampleTests(unittest.TestCase): - def testGoodStuff(self): - pass - - def testBadStuff(self): - self.fail("This test shouldn't run") diff --git a/parts/django/tests/modeltests/test_client/urls.py b/parts/django/tests/modeltests/test_client/urls.py deleted file mode 100644 index 9e0eabe..0000000 --- a/parts/django/tests/modeltests/test_client/urls.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.conf.urls.defaults import * -from django.views.generic.simple import redirect_to -import views - -urlpatterns = patterns('', - (r'^get_view/$', views.get_view), - (r'^post_view/$', views.post_view), - (r'^header_view/$', views.view_with_header), - (r'^raw_post_view/$', views.raw_post_view), - (r'^redirect_view/$', views.redirect_view), - (r'^secure_view/$', views.view_with_secure), - (r'^permanent_redirect_view/$', redirect_to, {'url': '/test_client/get_view/'}), - (r'^temporary_redirect_view/$', redirect_to, {'url': '/test_client/get_view/', 'permanent': False}), - (r'^http_redirect_view/$', redirect_to, {'url': '/test_client/secure_view/'}), - (r'^https_redirect_view/$', redirect_to, {'url': 'https://testserver/test_client/secure_view/'}), - (r'^double_redirect_view/$', views.double_redirect_view), - (r'^bad_view/$', views.bad_view), - (r'^form_view/$', views.form_view), - (r'^form_view_with_template/$', views.form_view_with_template), - (r'^login_protected_view/$', views.login_protected_view), - (r'^login_protected_method_view/$', views.login_protected_method_view), - (r'^login_protected_view_custom_redirect/$', views.login_protected_view_changed_redirect), - (r'^permission_protected_view/$', views.permission_protected_view), - (r'^permission_protected_method_view/$', views.permission_protected_method_view), - (r'^session_view/$', views.session_view), - (r'^broken_view/$', views.broken_view), - (r'^mail_sending_view/$', views.mail_sending_view), - (r'^mass_mail_sending_view/$', views.mass_mail_sending_view) -) diff --git a/parts/django/tests/modeltests/test_client/views.py b/parts/django/tests/modeltests/test_client/views.py deleted file mode 100644 index baa9525..0000000 --- a/parts/django/tests/modeltests/test_client/views.py +++ /dev/null @@ -1,214 +0,0 @@ -from xml.dom.minidom import parseString - -from django.core import mail -from django.template import Context, Template -from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound -from django.contrib.auth.decorators import login_required, permission_required -from django.forms.forms import Form -from django.forms import fields -from django.shortcuts import render_to_response -from django.utils.decorators import method_decorator - -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': request.GET.get('var', 42)}) - - return HttpResponse(t.render(c)) - -def post_view(request): - """A view that expects a POST, and returns a different template depending - on whether any POST data is available - """ - if request.method == 'POST': - if request.POST: - t = Template('Data received: {{ data }} is the value.', name='POST Template') - c = Context({'data': request.POST['value']}) - else: - t = Template('Viewing POST page.', name='Empty POST Template') - c = Context() - else: - t = Template('Viewing GET page.', name='Empty GET Template') - c = Context() - - return HttpResponse(t.render(c)) - -def view_with_header(request): - "A view that has a custom header" - response = HttpResponse() - response['X-DJANGO-TEST'] = 'Slartibartfast' - return response - -def raw_post_view(request): - """A view which expects raw XML to be posted and returns content extracted - from the XML""" - if request.method == 'POST': - root = parseString(request.raw_post_data) - first_book = root.firstChild.firstChild - title, author = [n.firstChild.nodeValue for n in first_book.childNodes] - t = Template("{{ title }} - {{ author }}", name="Book template") - c = Context({"title": title, "author": author}) - else: - t = Template("GET request.", name="Book GET template") - c = Context() - - return HttpResponse(t.render(c)) - -def redirect_view(request): - "A view that redirects all requests to the GET view" - if request.GET: - from urllib import urlencode - query = '?' + urlencode(request.GET, True) - else: - query = '' - return HttpResponseRedirect('/test_client/get_view/' + query) - -def view_with_secure(request): - "A view that indicates if the request was secure" - response = HttpResponse() - response.test_was_secure_request = request.is_secure() - return response - -def double_redirect_view(request): - "A view that redirects all requests to a redirection view" - return HttpResponseRedirect('/test_client/permanent_redirect_view/') - -def bad_view(request): - "A view that returns a 404 with some error content" - return HttpResponseNotFound('Not found!. This page contains some MAGIC content') - -TestChoices = ( - ('a', 'First Choice'), - ('b', 'Second Choice'), - ('c', 'Third Choice'), - ('d', 'Fourth Choice'), - ('e', 'Fifth Choice') -) - -class TestForm(Form): - text = fields.CharField() - email = fields.EmailField() - value = fields.IntegerField() - single = fields.ChoiceField(choices=TestChoices) - multi = fields.MultipleChoiceField(choices=TestChoices) - -def form_view(request): - "A view that tests a simple form" - if request.method == 'POST': - form = TestForm(request.POST) - if form.is_valid(): - t = Template('Valid POST data.', name='Valid POST Template') - c = Context() - else: - t = Template('Invalid POST data. {{ form.errors }}', name='Invalid POST Template') - c = Context({'form': form}) - else: - form = TestForm(request.GET) - t = Template('Viewing base form. {{ form }}.', name='Form GET Template') - c = Context({'form': form}) - - return HttpResponse(t.render(c)) - -def form_view_with_template(request): - "A view that tests a simple form" - if request.method == 'POST': - form = TestForm(request.POST) - if form.is_valid(): - message = 'POST data OK' - else: - message = 'POST data has errors' - else: - form = TestForm() - message = 'GET form page' - return render_to_response('form_view.html', - { - 'form': form, - 'message': message - } - ) - -def login_protected_view(request): - "A simple view that is login protected." - t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template') - c = Context({'user': request.user}) - - return HttpResponse(t.render(c)) -login_protected_view = login_required(login_protected_view) - -def login_protected_view_changed_redirect(request): - "A simple view that is login protected with a custom redirect field set" - t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template') - c = Context({'user': request.user}) - - return HttpResponse(t.render(c)) -login_protected_view_changed_redirect = login_required(redirect_field_name="redirect_to")(login_protected_view_changed_redirect) - -def permission_protected_view(request): - "A simple view that is permission protected." - t = Template('This is a permission protected test. ' - 'Username is {{ user.username }}. ' - 'Permissions are {{ user.get_all_permissions }}.' , - name='Permissions Template') - c = Context({'user': request.user}) - return HttpResponse(t.render(c)) -permission_protected_view = permission_required('modeltests.test_perm')(permission_protected_view) - -class _ViewManager(object): - @method_decorator(login_required) - def login_protected_view(self, request): - t = Template('This is a login protected test using a method. ' - 'Username is {{ user.username }}.', - name='Login Method Template') - c = Context({'user': request.user}) - return HttpResponse(t.render(c)) - - @method_decorator(permission_required('modeltests.test_perm')) - def permission_protected_view(self, request): - t = Template('This is a permission protected test using a method. ' - 'Username is {{ user.username }}. ' - 'Permissions are {{ user.get_all_permissions }}.' , - name='Permissions Template') - c = Context({'user': request.user}) - return HttpResponse(t.render(c)) - -_view_manager = _ViewManager() -login_protected_method_view = _view_manager.login_protected_view -permission_protected_method_view = _view_manager.permission_protected_view - -def session_view(request): - "A view that modifies the session" - request.session['tobacconist'] = 'hovercraft' - - t = Template('This is a view that modifies the session.', - name='Session Modifying View Template') - c = Context() - return HttpResponse(t.render(c)) - -def broken_view(request): - """A view which just raises an exception, simulating a broken view.""" - raise KeyError("Oops! Looks like you wrote some bad code.") - -def mail_sending_view(request): - mail.EmailMessage( - "Test message", - "This is a test email", - "from@example.com", - ['first@example.com', 'second@example.com']).send() - return HttpResponse("Mail sent") - -def mass_mail_sending_view(request): - m1 = mail.EmailMessage( - 'First Test message', - 'This is the first test email', - 'from@example.com', - ['first@example.com', 'second@example.com']) - m2 = mail.EmailMessage( - 'Second Test message', - 'This is the second test email', - 'from@example.com', - ['second@example.com', 'third@example.com']) - - c = mail.get_connection() - c.send_messages([m1,m2]) - - return HttpResponse("Mail sent") diff --git a/parts/django/tests/modeltests/transactions/__init__.py b/parts/django/tests/modeltests/transactions/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/transactions/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/transactions/models.py b/parts/django/tests/modeltests/transactions/models.py deleted file mode 100644 index d957fe1..0000000 --- a/parts/django/tests/modeltests/transactions/models.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -15. Transactions - -Django handles transactions in three different ways. The default is to commit -each transaction upon a write, but you can decorate a function to get -commit-on-success behavior. Alternatively, you can manage the transaction -manually. -""" - -from django.db import models, DEFAULT_DB_ALIAS - -class Reporter(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - email = models.EmailField() - - class Meta: - ordering = ('first_name', 'last_name') - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name)
\ No newline at end of file diff --git a/parts/django/tests/modeltests/transactions/tests.py b/parts/django/tests/modeltests/transactions/tests.py deleted file mode 100644 index 9964f5d..0000000 --- a/parts/django/tests/modeltests/transactions/tests.py +++ /dev/null @@ -1,155 +0,0 @@ -from django.test import TransactionTestCase -from django.db import connection, transaction, IntegrityError, DEFAULT_DB_ALIAS -from django.conf import settings - -from models import Reporter - -PGSQL = 'psycopg2' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] -MYSQL = 'mysql' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] - -class TransactionTests(TransactionTestCase): - - if not MYSQL: - - def create_a_reporter_then_fail(self, first, last): - a = Reporter(first_name=first, last_name=last) - a.save() - raise Exception("I meant to do that") - - def remove_a_reporter(self, first_name): - r = Reporter.objects.get(first_name="Alice") - r.delete() - - def manually_managed(self): - r = Reporter(first_name="Dirk", last_name="Gently") - r.save() - transaction.commit() - - def manually_managed_mistake(self): - r = Reporter(first_name="Edward", last_name="Woodward") - r.save() - # Oops, I forgot to commit/rollback! - - def execute_bad_sql(self): - cursor = connection.cursor() - cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');") - transaction.set_dirty() - - def test_autocommit(self): - """ - The default behavior is to autocommit after each save() action. - """ - self.assertRaises(Exception, - self.create_a_reporter_then_fail, - "Alice", "Smith" - ) - - # The object created before the exception still exists - self.assertEqual(Reporter.objects.count(), 1) - - def test_autocommit_decorator(self): - """ - The autocommit decorator works exactly the same as the default behavior. - """ - autocomitted_create_then_fail = transaction.autocommit( - self.create_a_reporter_then_fail - ) - self.assertRaises(Exception, - autocomitted_create_then_fail, - "Alice", "Smith" - ) - # Again, the object created before the exception still exists - self.assertEqual(Reporter.objects.count(), 1) - - def test_autocommit_decorator_with_using(self): - """ - The autocommit decorator also works with a using argument. - """ - autocomitted_create_then_fail = transaction.autocommit(using='default')( - self.create_a_reporter_then_fail - ) - self.assertRaises(Exception, - autocomitted_create_then_fail, - "Alice", "Smith" - ) - # Again, the object created before the exception still exists - self.assertEqual(Reporter.objects.count(), 1) - - def test_commit_on_success(self): - """ - With the commit_on_success decorator, the transaction is only committed - if the function doesn't throw an exception. - """ - committed_on_success = transaction.commit_on_success( - self.create_a_reporter_then_fail) - self.assertRaises(Exception, committed_on_success, "Dirk", "Gently") - # This time the object never got saved - self.assertEqual(Reporter.objects.count(), 0) - - def test_commit_on_success_with_using(self): - """ - The commit_on_success decorator also works with a using argument. - """ - using_committed_on_success = transaction.commit_on_success(using='default')( - self.create_a_reporter_then_fail - ) - self.assertRaises(Exception, - using_committed_on_success, - "Dirk", "Gently" - ) - # This time the object never got saved - self.assertEqual(Reporter.objects.count(), 0) - - def test_commit_on_success_succeed(self): - """ - If there aren't any exceptions, the data will get saved. - """ - Reporter.objects.create(first_name="Alice", last_name="Smith") - remove_comitted_on_success = transaction.commit_on_success( - self.remove_a_reporter - ) - remove_comitted_on_success("Alice") - self.assertEqual(list(Reporter.objects.all()), []) - - def test_manually_managed(self): - """ - You can manually manage transactions if you really want to, but you - have to remember to commit/rollback. - """ - manually_managed = transaction.commit_manually(self.manually_managed) - manually_managed() - self.assertEqual(Reporter.objects.count(), 1) - - def test_manually_managed_mistake(self): - """ - If you forget, you'll get bad errors. - """ - manually_managed_mistake = transaction.commit_manually( - self.manually_managed_mistake - ) - self.assertRaises(transaction.TransactionManagementError, - manually_managed_mistake) - - def test_manually_managed_with_using(self): - """ - The commit_manually function also works with a using argument. - """ - using_manually_managed_mistake = transaction.commit_manually(using='default')( - self.manually_managed_mistake - ) - self.assertRaises(transaction.TransactionManagementError, - using_manually_managed_mistake - ) - - if PGSQL: - - def test_bad_sql(self): - """ - Regression for #11900: If a function wrapped by commit_on_success - writes a transaction that can't be committed, that transaction should - be rolled back. The bug is only visible using the psycopg2 backend, - though the fix is generally a good idea. - """ - execute_bad_sql = transaction.commit_on_success(self.execute_bad_sql) - self.assertRaises(IntegrityError, execute_bad_sql) - transaction.rollback() diff --git a/parts/django/tests/modeltests/unmanaged_models/__init__.py b/parts/django/tests/modeltests/unmanaged_models/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/modeltests/unmanaged_models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/modeltests/unmanaged_models/models.py b/parts/django/tests/modeltests/unmanaged_models/models.py deleted file mode 100644 index 0c2cf50..0000000 --- a/parts/django/tests/modeltests/unmanaged_models/models.py +++ /dev/null @@ -1,125 +0,0 @@ -""" -Models can have a ``managed`` attribute, which specifies whether the SQL code -is generated for the table on various manage.py operations. -""" - -from django.db import models - -# All of these models are creatd in the database by Django. - -class A01(models.Model): - f_a = models.CharField(max_length=10, db_index=True) - f_b = models.IntegerField() - - class Meta: - db_table = 'A01' - - def __unicode__(self): - return self.f_a - -class B01(models.Model): - fk_a = models.ForeignKey(A01) - f_a = models.CharField(max_length=10, db_index=True) - f_b = models.IntegerField() - - class Meta: - db_table = 'B01' - # 'managed' is True by default. This tests we can set it explicitly. - managed = True - - def __unicode__(self): - return self.f_a - -class C01(models.Model): - mm_a = models.ManyToManyField(A01, db_table='D01') - f_a = models.CharField(max_length=10, db_index=True) - f_b = models.IntegerField() - - class Meta: - db_table = 'C01' - - def __unicode__(self): - return self.f_a - -# All of these models use the same tables as the previous set (they are shadows -# of possibly a subset of the columns). There should be no creation errors, -# since we have told Django they aren't managed by Django. - -class A02(models.Model): - f_a = models.CharField(max_length=10, db_index=True) - - class Meta: - db_table = 'A01' - managed = False - - def __unicode__(self): - return self.f_a - -class B02(models.Model): - class Meta: - db_table = 'B01' - managed = False - - fk_a = models.ForeignKey(A02) - f_a = models.CharField(max_length=10, db_index=True) - f_b = models.IntegerField() - - def __unicode__(self): - return self.f_a - -# To re-use the many-to-many intermediate table, we need to manually set up -# things up. -class C02(models.Model): - mm_a = models.ManyToManyField(A02, through="Intermediate") - f_a = models.CharField(max_length=10, db_index=True) - f_b = models.IntegerField() - - class Meta: - db_table = 'C01' - managed = False - - def __unicode__(self): - return self.f_a - -class Intermediate(models.Model): - a02 = models.ForeignKey(A02, db_column="a01_id") - c02 = models.ForeignKey(C02, db_column="c01_id") - - class Meta: - db_table = 'D01' - managed = False - -# -# These next models test the creation (or not) of many to many join tables -# between managed and unmanaged models. A join table between two unmanaged -# models shouldn't be automatically created (see #10647). -# - -# Firstly, we need some models that will create the tables, purely so that the -# tables are created. This is a test setup, not a requirement for unmanaged -# models. -class Proxy1(models.Model): - class Meta: - db_table = "unmanaged_models_proxy1" - -class Proxy2(models.Model): - class Meta: - db_table = "unmanaged_models_proxy2" - -class Unmanaged1(models.Model): - class Meta: - managed = False - db_table = "unmanaged_models_proxy1" - -# Unmanged with an m2m to unmanaged: the intermediary table won't be created. -class Unmanaged2(models.Model): - mm = models.ManyToManyField(Unmanaged1) - - class Meta: - managed = False - db_table = "unmanaged_models_proxy2" - -# Here's an unmanaged model with an m2m to a managed one; the intermediary -# table *will* be created (unless given a custom `through` as for C02 above). -class Managed1(models.Model): - mm = models.ManyToManyField(Unmanaged1) diff --git a/parts/django/tests/modeltests/unmanaged_models/tests.py b/parts/django/tests/modeltests/unmanaged_models/tests.py deleted file mode 100644 index dbbe848..0000000 --- a/parts/django/tests/modeltests/unmanaged_models/tests.py +++ /dev/null @@ -1,58 +0,0 @@ -from django.test import TestCase -from django.db import connection -from models import Unmanaged1, Unmanaged2, Managed1 -from models import A01, A02, B01, B02, C01, C02 - -class SimpleTests(TestCase): - - def test_simple(self): - """ - The main test here is that the all the models can be created without - any database errors. We can also do some more simple insertion and - lookup tests whilst we're here to show that the second of models do - refer to the tables from the first set. - """ - # Insert some data into one set of models. - a = A01.objects.create(f_a="foo", f_b=42) - B01.objects.create(fk_a=a, f_a="fred", f_b=1729) - c = C01.objects.create(f_a="barney", f_b=1) - c.mm_a = [a] - - # ... and pull it out via the other set. - a2 = A02.objects.all()[0] - self.assertTrue(isinstance(a2, A02)) - self.assertEqual(a2.f_a, "foo") - - b2 = B02.objects.all()[0] - self.assertTrue(isinstance(b2, B02)) - self.assertEqual(b2.f_a, "fred") - - self.assertTrue(isinstance(b2.fk_a, A02)) - self.assertEqual(b2.fk_a.f_a, "foo") - - self.assertEqual(list(C02.objects.filter(f_a=None)), []) - - resp = list(C02.objects.filter(mm_a=a.id)) - self.assertEqual(len(resp), 1) - - self.assertTrue(isinstance(resp[0], C02)) - self.assertEqual(resp[0].f_a, 'barney') - - -class ManyToManyUnmanagedTests(TestCase): - - def test_many_to_many_between_unmanaged(self): - """ - The intermediary table between two unmanaged models should not be created. - """ - table = Unmanaged2._meta.get_field('mm').m2m_db_table() - tables = connection.introspection.table_names() - self.assert_(table not in tables, "Table '%s' should not exist, but it does." % table) - - def test_many_to_many_between_unmanaged_and_managed(self): - """ - An intermediary table between a managed and an unmanaged model should be created. - """ - table = Managed1._meta.get_field('mm').m2m_db_table() - tables = connection.introspection.table_names() - self.assert_(table in tables, "Table '%s' does not exist." % table) diff --git a/parts/django/tests/modeltests/update/__init__.py b/parts/django/tests/modeltests/update/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/update/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/update/models.py b/parts/django/tests/modeltests/update/models.py deleted file mode 100644 index 7b633e2..0000000 --- a/parts/django/tests/modeltests/update/models.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -Tests for the update() queryset method that allows in-place, multi-object -updates. -""" - -from django.db import models - -class DataPoint(models.Model): - name = models.CharField(max_length=20) - value = models.CharField(max_length=20) - another_value = models.CharField(max_length=20, blank=True) - - def __unicode__(self): - return unicode(self.name) - -class RelatedPoint(models.Model): - name = models.CharField(max_length=20) - data = models.ForeignKey(DataPoint) - - def __unicode__(self): - return unicode(self.name) - - -class A(models.Model): - x = models.IntegerField(default=10) - -class B(models.Model): - a = models.ForeignKey(A) - y = models.IntegerField(default=10) - -class C(models.Model): - y = models.IntegerField(default=10) - -class D(C): - a = models.ForeignKey(A) diff --git a/parts/django/tests/modeltests/update/tests.py b/parts/django/tests/modeltests/update/tests.py deleted file mode 100644 index d0b6ea3..0000000 --- a/parts/django/tests/modeltests/update/tests.py +++ /dev/null @@ -1,116 +0,0 @@ -from django.test import TestCase - -from models import A, B, C, D, DataPoint, RelatedPoint - - -class SimpleTest(TestCase): - def setUp(self): - self.a1 = A.objects.create() - self.a2 = A.objects.create() - for x in range(20): - B.objects.create(a=self.a1) - D.objects.create(a=self.a1) - - def test_nonempty_update(self): - """ - Test that update changes the right number of rows for a nonempty queryset - """ - num_updated = self.a1.b_set.update(y=100) - self.assertEqual(num_updated, 20) - cnt = B.objects.filter(y=100).count() - self.assertEqual(cnt, 20) - - def test_empty_update(self): - """ - Test that update changes the right number of rows for an empty queryset - """ - num_updated = self.a2.b_set.update(y=100) - self.assertEqual(num_updated, 0) - cnt = B.objects.filter(y=100).count() - self.assertEqual(cnt, 0) - - def test_nonempty_update_with_inheritance(self): - """ - Test that update changes the right number of rows for an empty queryset - when the update affects only a base table - """ - num_updated = self.a1.d_set.update(y=100) - self.assertEqual(num_updated, 20) - cnt = D.objects.filter(y=100).count() - self.assertEqual(cnt, 20) - - def test_empty_update_with_inheritance(self): - """ - Test that update changes the right number of rows for an empty queryset - when the update affects only a base table - """ - num_updated = self.a2.d_set.update(y=100) - self.assertEqual(num_updated, 0) - cnt = D.objects.filter(y=100).count() - self.assertEqual(cnt, 0) - -class AdvancedTests(TestCase): - - def setUp(self): - self.d0 = DataPoint.objects.create(name="d0", value="apple") - self.d2 = DataPoint.objects.create(name="d2", value="banana") - self.d3 = DataPoint.objects.create(name="d3", value="banana") - self.r1 = RelatedPoint.objects.create(name="r1", data=self.d3) - - def test_update(self): - """ - Objects are updated by first filtering the candidates into a queryset - and then calling the update() method. It executes immediately and - returns nothing. - """ - resp = DataPoint.objects.filter(value="apple").update(name="d1") - self.assertEqual(resp, 1) - resp = DataPoint.objects.filter(value="apple") - self.assertEqual(list(resp), [self.d0]) - - def test_update_multiple_objects(self): - """ - We can update multiple objects at once. - """ - resp = DataPoint.objects.filter(value="banana").update( - value="pineapple") - self.assertEqual(resp, 2) - self.assertEqual(DataPoint.objects.get(name="d2").value, u'pineapple') - - def test_update_fk(self): - """ - Foreign key fields can also be updated, although you can only update - the object referred to, not anything inside the related object. - """ - resp = RelatedPoint.objects.filter(name="r1").update(data=self.d0) - self.assertEqual(resp, 1) - resp = RelatedPoint.objects.filter(data__name="d0") - self.assertEqual(list(resp), [self.r1]) - - def test_update_multiple_fields(self): - """ - Multiple fields can be updated at once - """ - resp = DataPoint.objects.filter(value="apple").update( - value="fruit", another_value="peach") - self.assertEqual(resp, 1) - d = DataPoint.objects.get(name="d0") - self.assertEqual(d.value, u'fruit') - self.assertEqual(d.another_value, u'peach') - - def test_update_all(self): - """ - In the rare case you want to update every instance of a model, update() - is also a manager method. - """ - self.assertEqual(DataPoint.objects.update(value='thing'), 3) - resp = DataPoint.objects.values('value').distinct() - self.assertEqual(list(resp), [{'value': u'thing'}]) - - def test_update_slice_fail(self): - """ - We do not support update on already sliced query sets. - """ - method = DataPoint.objects.all()[:2].update - self.assertRaises(AssertionError, method, - another_value='another thing') diff --git a/parts/django/tests/modeltests/user_commands/__init__.py b/parts/django/tests/modeltests/user_commands/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/user_commands/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/user_commands/management/__init__.py b/parts/django/tests/modeltests/user_commands/management/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/user_commands/management/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/user_commands/management/commands/__init__.py b/parts/django/tests/modeltests/user_commands/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/user_commands/management/commands/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/user_commands/management/commands/dance.py b/parts/django/tests/modeltests/user_commands/management/commands/dance.py deleted file mode 100644 index acefe09..0000000 --- a/parts/django/tests/modeltests/user_commands/management/commands/dance.py +++ /dev/null @@ -1,14 +0,0 @@ -from optparse import make_option -from django.core.management.base import BaseCommand - -class Command(BaseCommand): - help = "Dance around like a madman." - args = '' - requires_model_validation = True - - option_list =[ - make_option("-s", "--style", default="Rock'n'Roll") - ] - - def handle(self, *args, **options): - self.stdout.write("I don't feel like dancing %s." % options["style"]) diff --git a/parts/django/tests/modeltests/user_commands/models.py b/parts/django/tests/modeltests/user_commands/models.py deleted file mode 100644 index f2aa549..0000000 --- a/parts/django/tests/modeltests/user_commands/models.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -38. User-registered management commands - -The ``manage.py`` utility provides a number of useful commands for managing a -Django project. If you want to add a utility command of your own, you can. - -The user-defined command ``dance`` is defined in the management/commands -subdirectory of this test application. It is a simple command that responds -with a printed message when invoked. - -For more details on how to define your own ``manage.py`` commands, look at the -``django.core.management.commands`` directory. This directory contains the -definitions for the base Django ``manage.py`` commands. -""" diff --git a/parts/django/tests/modeltests/user_commands/tests.py b/parts/django/tests/modeltests/user_commands/tests.py deleted file mode 100644 index 84aa7a5..0000000 --- a/parts/django/tests/modeltests/user_commands/tests.py +++ /dev/null @@ -1,21 +0,0 @@ -from StringIO import StringIO - -from django.test import TestCase -from django.core import management -from django.core.management.base import CommandError - -class CommandTests(TestCase): - def test_command(self): - out = StringIO() - management.call_command('dance', stdout=out) - self.assertEquals(out.getvalue(), - "I don't feel like dancing Rock'n'Roll.") - - def test_command_style(self): - out = StringIO() - management.call_command('dance', style='Jive', stdout=out) - self.assertEquals(out.getvalue(), - "I don't feel like dancing Jive.") - - def test_explode(self): - self.assertRaises(CommandError, management.call_command, ('explode',))
\ No newline at end of file diff --git a/parts/django/tests/modeltests/validation/__init__.py b/parts/django/tests/modeltests/validation/__init__.py deleted file mode 100644 index d0a7d19..0000000 --- a/parts/django/tests/modeltests/validation/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest - -from django.core.exceptions import ValidationError - -class ValidationTestCase(unittest.TestCase): - def assertFailsValidation(self, clean, failed_fields): - self.assertRaises(ValidationError, clean) - try: - clean() - except ValidationError, e: - self.assertEquals(sorted(failed_fields), sorted(e.message_dict.keys())) - - def assertFieldFailsValidationWithMessage(self, clean, field_name, message): - self.assertRaises(ValidationError, clean) - try: - clean() - except ValidationError, e: - self.assertTrue(field_name in e.message_dict) - self.assertEquals(message, e.message_dict[field_name]) - - diff --git a/parts/django/tests/modeltests/validation/models.py b/parts/django/tests/modeltests/validation/models.py deleted file mode 100644 index dd42936..0000000 --- a/parts/django/tests/modeltests/validation/models.py +++ /dev/null @@ -1,65 +0,0 @@ -from datetime import datetime -from django.core.exceptions import ValidationError -from django.db import models -from django.test import TestCase - - -def validate_answer_to_universe(value): - if value != 42: - raise ValidationError('This is not the answer to life, universe and everything!', code='not42') - -class ModelToValidate(models.Model): - name = models.CharField(max_length=100) - created = models.DateTimeField(default=datetime.now) - number = models.IntegerField(db_column='number_val') - parent = models.ForeignKey('self', blank=True, null=True, limit_choices_to={'number': 10}) - email = models.EmailField(blank=True) - url = models.URLField(blank=True) - f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe]) - - def clean(self): - super(ModelToValidate, self).clean() - if self.number == 11: - raise ValidationError('Invalid number supplied!') - -class UniqueFieldsModel(models.Model): - unique_charfield = models.CharField(max_length=100, unique=True) - unique_integerfield = models.IntegerField(unique=True) - non_unique_field = models.IntegerField() - -class CustomPKModel(models.Model): - my_pk_field = models.CharField(max_length=100, primary_key=True) - -class UniqueTogetherModel(models.Model): - cfield = models.CharField(max_length=100) - ifield = models.IntegerField() - efield = models.EmailField() - - class Meta: - unique_together = (('ifield', 'cfield',), ['ifield', 'efield']) - -class UniqueForDateModel(models.Model): - start_date = models.DateField() - end_date = models.DateTimeField() - count = models.IntegerField(unique_for_date="start_date", unique_for_year="end_date") - order = models.IntegerField(unique_for_month="end_date") - name = models.CharField(max_length=100) - -class CustomMessagesModel(models.Model): - other = models.IntegerField(blank=True, null=True) - number = models.IntegerField(db_column='number_val', - error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'}, - validators=[validate_answer_to_universe] - ) - -class Author(models.Model): - name = models.CharField(max_length=100) - -class Article(models.Model): - title = models.CharField(max_length=100) - author = models.ForeignKey(Author) - pub_date = models.DateTimeField(blank=True) - - def clean(self): - if self.pub_date is None: - self.pub_date = datetime.now() diff --git a/parts/django/tests/modeltests/validation/test_custom_messages.py b/parts/django/tests/modeltests/validation/test_custom_messages.py deleted file mode 100644 index 05bb651..0000000 --- a/parts/django/tests/modeltests/validation/test_custom_messages.py +++ /dev/null @@ -1,13 +0,0 @@ -from modeltests.validation import ValidationTestCase -from models import CustomMessagesModel - - -class CustomMessagesTest(ValidationTestCase): - def test_custom_simple_validator_message(self): - cmm = CustomMessagesModel(number=12) - self.assertFieldFailsValidationWithMessage(cmm.full_clean, 'number', ['AAARGH']) - - def test_custom_null_message(self): - cmm = CustomMessagesModel() - self.assertFieldFailsValidationWithMessage(cmm.full_clean, 'number', ['NULL']) - diff --git a/parts/django/tests/modeltests/validation/test_unique.py b/parts/django/tests/modeltests/validation/test_unique.py deleted file mode 100644 index fb77c4d..0000000 --- a/parts/django/tests/modeltests/validation/test_unique.py +++ /dev/null @@ -1,85 +0,0 @@ -import unittest -import datetime -from django.conf import settings -from django.db import connection -from models import CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate - - -class GetUniqueCheckTests(unittest.TestCase): - def test_unique_fields_get_collected(self): - m = UniqueFieldsModel() - self.assertEqual( - ([(UniqueFieldsModel, ('id',)), - (UniqueFieldsModel, ('unique_charfield',)), - (UniqueFieldsModel, ('unique_integerfield',))], - []), - m._get_unique_checks() - ) - - def test_unique_together_gets_picked_up_and_converted_to_tuple(self): - m = UniqueTogetherModel() - self.assertEqual( - ([(UniqueTogetherModel, ('ifield', 'cfield',)), - (UniqueTogetherModel, ('ifield', 'efield')), - (UniqueTogetherModel, ('id',)), ], - []), - m._get_unique_checks() - ) - - def test_primary_key_is_considered_unique(self): - m = CustomPKModel() - self.assertEqual(([(CustomPKModel, ('my_pk_field',))], []), m._get_unique_checks()) - - def test_unique_for_date_gets_picked_up(self): - m = UniqueForDateModel() - self.assertEqual(( - [(UniqueForDateModel, ('id',))], - [(UniqueForDateModel, 'date', 'count', 'start_date'), - (UniqueForDateModel, 'year', 'count', 'end_date'), - (UniqueForDateModel, 'month', 'order', 'end_date')] - ), m._get_unique_checks() - ) - - def test_unique_for_date_exclusion(self): - m = UniqueForDateModel() - self.assertEqual(( - [(UniqueForDateModel, ('id',))], - [(UniqueForDateModel, 'year', 'count', 'end_date'), - (UniqueForDateModel, 'month', 'order', 'end_date')] - ), m._get_unique_checks(exclude='start_date') - ) - -class PerformUniqueChecksTest(unittest.TestCase): - def setUp(self): - # Set debug to True to gain access to connection.queries. - self._old_debug, settings.DEBUG = settings.DEBUG, True - super(PerformUniqueChecksTest, self).setUp() - - def tearDown(self): - # Restore old debug value. - settings.DEBUG = self._old_debug - super(PerformUniqueChecksTest, self).tearDown() - - def test_primary_key_unique_check_not_performed_when_adding_and_pk_not_specified(self): - # Regression test for #12560 - query_count = len(connection.queries) - mtv = ModelToValidate(number=10, name='Some Name') - setattr(mtv, '_adding', True) - mtv.full_clean() - self.assertEqual(query_count, len(connection.queries)) - - def test_primary_key_unique_check_performed_when_adding_and_pk_specified(self): - # Regression test for #12560 - query_count = len(connection.queries) - mtv = ModelToValidate(number=10, name='Some Name', id=123) - setattr(mtv, '_adding', True) - mtv.full_clean() - self.assertEqual(query_count + 1, len(connection.queries)) - - def test_primary_key_unique_check_not_performed_when_not_adding(self): - # Regression test for #12132 - query_count= len(connection.queries) - mtv = ModelToValidate(number=10, name='Some Name') - mtv.full_clean() - self.assertEqual(query_count, len(connection.queries)) - diff --git a/parts/django/tests/modeltests/validation/tests.py b/parts/django/tests/modeltests/validation/tests.py deleted file mode 100644 index 0027393..0000000 --- a/parts/django/tests/modeltests/validation/tests.py +++ /dev/null @@ -1,114 +0,0 @@ -from django import forms -from django.test import TestCase -from django.core.exceptions import NON_FIELD_ERRORS -from modeltests.validation import ValidationTestCase -from modeltests.validation.models import Author, Article, ModelToValidate - -# Import other tests for this package. -from modeltests.validation.validators import TestModelsWithValidators -from modeltests.validation.test_unique import GetUniqueCheckTests, PerformUniqueChecksTest -from modeltests.validation.test_custom_messages import CustomMessagesTest - - -class BaseModelValidationTests(ValidationTestCase): - - def test_missing_required_field_raises_error(self): - mtv = ModelToValidate(f_with_custom_validator=42) - self.assertFailsValidation(mtv.full_clean, ['name', 'number']) - - def test_with_correct_value_model_validates(self): - mtv = ModelToValidate(number=10, name='Some Name') - self.assertEqual(None, mtv.full_clean()) - - def test_custom_validate_method(self): - mtv = ModelToValidate(number=11) - self.assertFailsValidation(mtv.full_clean, [NON_FIELD_ERRORS, 'name']) - - def test_wrong_FK_value_raises_error(self): - mtv=ModelToValidate(number=10, name='Some Name', parent_id=3) - self.assertFailsValidation(mtv.full_clean, ['parent']) - - def test_correct_FK_value_validates(self): - parent = ModelToValidate.objects.create(number=10, name='Some Name') - mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk) - self.assertEqual(None, mtv.full_clean()) - - def test_limitted_FK_raises_error(self): - # The limit_choices_to on the parent field says that a parent object's - # number attribute must be 10, so this should fail validation. - parent = ModelToValidate.objects.create(number=11, name='Other Name') - mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk) - self.assertFailsValidation(mtv.full_clean, ['parent']) - - def test_wrong_email_value_raises_error(self): - mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email') - self.assertFailsValidation(mtv.full_clean, ['email']) - - def test_correct_email_value_passes(self): - mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com') - self.assertEqual(None, mtv.full_clean()) - - def test_wrong_url_value_raises_error(self): - mtv = ModelToValidate(number=10, name='Some Name', url='not a url') - self.assertFieldFailsValidationWithMessage(mtv.full_clean, 'url', [u'Enter a valid value.']) - - def test_correct_url_but_nonexisting_gives_404(self): - mtv = ModelToValidate(number=10, name='Some Name', url='http://google.com/we-love-microsoft.html') - self.assertFieldFailsValidationWithMessage(mtv.full_clean, 'url', [u'This URL appears to be a broken link.']) - - def test_correct_url_value_passes(self): - mtv = ModelToValidate(number=10, name='Some Name', url='http://www.djangoproject.com/') - self.assertEqual(None, mtv.full_clean()) # This will fail if there's no Internet connection - - def test_text_greater_that_charfields_max_length_eaises_erros(self): - mtv = ModelToValidate(number=10, name='Some Name'*100) - self.assertFailsValidation(mtv.full_clean, ['name',]) - -class ArticleForm(forms.ModelForm): - class Meta: - model = Article - exclude = ['author'] - -class ModelFormsTests(TestCase): - def setUp(self): - self.author = Author.objects.create(name='Joseph Kocherhans') - - def test_partial_validation(self): - # Make sure the "commit=False and set field values later" idiom still - # works with model validation. - data = { - 'title': 'The state of model validation', - 'pub_date': '2010-1-10 14:49:00' - } - form = ArticleForm(data) - self.assertEqual(form.errors.keys(), []) - article = form.save(commit=False) - article.author = self.author - article.save() - - def test_validation_with_empty_blank_field(self): - # Since a value for pub_date wasn't provided and the field is - # blank=True, model-validation should pass. - # Also, Article.clean() should be run, so pub_date will be filled after - # validation, so the form should save cleanly even though pub_date is - # not allowed to be null. - data = { - 'title': 'The state of model validation', - } - article = Article(author_id=self.author.id) - form = ArticleForm(data, instance=article) - self.assertEqual(form.errors.keys(), []) - self.assertNotEqual(form.instance.pub_date, None) - article = form.save() - - def test_validation_with_invalid_blank_field(self): - # Even though pub_date is set to blank=True, an invalid value was - # provided, so it should fail validation. - data = { - 'title': 'The state of model validation', - 'pub_date': 'never' - } - article = Article(author_id=self.author.id) - form = ArticleForm(data, instance=article) - self.assertEqual(form.errors.keys(), ['pub_date']) - diff --git a/parts/django/tests/modeltests/validation/validators.py b/parts/django/tests/modeltests/validation/validators.py deleted file mode 100644 index 3ad2c40..0000000 --- a/parts/django/tests/modeltests/validation/validators.py +++ /dev/null @@ -1,18 +0,0 @@ -from unittest import TestCase -from modeltests.validation import ValidationTestCase -from models import * - - -class TestModelsWithValidators(ValidationTestCase): - def test_custom_validator_passes_for_correct_value(self): - mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42) - self.assertEqual(None, mtv.full_clean()) - - def test_custom_validator_raises_error_for_incorrect_value(self): - mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12) - self.assertFailsValidation(mtv.full_clean, ['f_with_custom_validator']) - self.assertFieldFailsValidationWithMessage( - mtv.full_clean, - 'f_with_custom_validator', - [u'This is not the answer to life, universe and everything!'] - ) diff --git a/parts/django/tests/modeltests/validators/__init__.py b/parts/django/tests/modeltests/validators/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/validators/__init__.py +++ /dev/null diff --git a/parts/django/tests/modeltests/validators/models.py b/parts/django/tests/modeltests/validators/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/modeltests/validators/models.py +++ /dev/null diff --git a/parts/django/tests/modeltests/validators/tests.py b/parts/django/tests/modeltests/validators/tests.py deleted file mode 100644 index 44ad176..0000000 --- a/parts/django/tests/modeltests/validators/tests.py +++ /dev/null @@ -1,159 +0,0 @@ -# -*- coding: utf-8 -*- -import re -import types -from unittest import TestCase -from datetime import datetime, timedelta -from django.core.exceptions import ValidationError -from django.core.validators import * - -NOW = datetime.now() - -TEST_DATA = ( - # (validator, value, expected), - (validate_integer, '42', None), - (validate_integer, '-42', None), - (validate_integer, -42, None), - (validate_integer, -42.5, None), - - (validate_integer, None, ValidationError), - (validate_integer, 'a', ValidationError), - - (validate_email, 'email@here.com', None), - (validate_email, 'weirder-email@here.and.there.com', None), - - (validate_email, None, ValidationError), - (validate_email, '', ValidationError), - (validate_email, 'abc', ValidationError), - (validate_email, 'a @x.cz', ValidationError), - (validate_email, 'something@@somewhere.com', ValidationError), - - (validate_slug, 'slug-ok', None), - (validate_slug, 'longer-slug-still-ok', None), - (validate_slug, '--------', None), - (validate_slug, 'nohyphensoranything', None), - - (validate_slug, '', ValidationError), - (validate_slug, ' text ', ValidationError), - (validate_slug, ' ', ValidationError), - (validate_slug, 'some@mail.com', ValidationError), - (validate_slug, '你好', ValidationError), - (validate_slug, '\n', ValidationError), - - (validate_ipv4_address, '1.1.1.1', None), - (validate_ipv4_address, '255.0.0.0', None), - (validate_ipv4_address, '0.0.0.0', None), - - (validate_ipv4_address, '256.1.1.1', ValidationError), - (validate_ipv4_address, '25.1.1.', ValidationError), - (validate_ipv4_address, '25,1,1,1', ValidationError), - (validate_ipv4_address, '25.1 .1.1', ValidationError), - - (validate_comma_separated_integer_list, '1', None), - (validate_comma_separated_integer_list, '1,2,3', None), - (validate_comma_separated_integer_list, '1,2,3,', None), - - (validate_comma_separated_integer_list, '', ValidationError), - (validate_comma_separated_integer_list, 'a,b,c', ValidationError), - (validate_comma_separated_integer_list, '1, 2, 3', ValidationError), - - (MaxValueValidator(10), 10, None), - (MaxValueValidator(10), -10, None), - (MaxValueValidator(10), 0, None), - (MaxValueValidator(NOW), NOW, None), - (MaxValueValidator(NOW), NOW - timedelta(days=1), None), - - (MaxValueValidator(0), 1, ValidationError), - (MaxValueValidator(NOW), NOW + timedelta(days=1), ValidationError), - - (MinValueValidator(-10), -10, None), - (MinValueValidator(-10), 10, None), - (MinValueValidator(-10), 0, None), - (MinValueValidator(NOW), NOW, None), - (MinValueValidator(NOW), NOW + timedelta(days=1), None), - - (MinValueValidator(0), -1, ValidationError), - (MinValueValidator(NOW), NOW - timedelta(days=1), ValidationError), - - (MaxLengthValidator(10), '', None), - (MaxLengthValidator(10), 10*'x', None), - - (MaxLengthValidator(10), 15*'x', ValidationError), - - (MinLengthValidator(10), 15*'x', None), - (MinLengthValidator(10), 10*'x', None), - - (MinLengthValidator(10), '', ValidationError), - - (URLValidator(), 'http://www.djangoproject.com/', None), - (URLValidator(), 'http://localhost/', None), - (URLValidator(), 'http://example.com/', None), - (URLValidator(), 'http://www.example.com/', None), - (URLValidator(), 'http://www.example.com:8000/test', None), - (URLValidator(), 'http://valid-with-hyphens.com/', None), - (URLValidator(), 'http://subdomain.domain.com/', None), - (URLValidator(), 'http://200.8.9.10/', None), - (URLValidator(), 'http://200.8.9.10:8000/test', None), - (URLValidator(), 'http://valid-----hyphens.com/', None), - (URLValidator(), 'http://example.com?something=value', None), - (URLValidator(), 'http://example.com/index.php?something=value&another=value2', None), - - (URLValidator(), 'foo', ValidationError), - (URLValidator(), 'http://', ValidationError), - (URLValidator(), 'http://example', ValidationError), - (URLValidator(), 'http://example.', ValidationError), - (URLValidator(), 'http://.com', ValidationError), - (URLValidator(), 'http://invalid-.com', ValidationError), - (URLValidator(), 'http://-invalid.com', ValidationError), - (URLValidator(), 'http://inv-.alid-.com', ValidationError), - (URLValidator(), 'http://inv-.-alid.com', ValidationError), - - (BaseValidator(True), True, None), - (BaseValidator(True), False, ValidationError), - - (RegexValidator('.*'), '', None), - (RegexValidator(re.compile('.*')), '', None), - (RegexValidator('.*'), 'xxxxx', None), - - (RegexValidator('x'), 'y', ValidationError), - (RegexValidator(re.compile('x')), 'y', ValidationError), -) - -def create_simple_test_method(validator, expected, value, num): - if expected is not None and issubclass(expected, Exception): - test_mask = 'test_%s_raises_error_%d' - def test_func(self): - self.assertRaises(expected, validator, value) - else: - test_mask = 'test_%s_%d' - def test_func(self): - self.assertEqual(expected, validator(value)) - if isinstance(validator, types.FunctionType): - val_name = validator.__name__ - else: - val_name = validator.__class__.__name__ - test_name = test_mask % (val_name, num) - return test_name, test_func - -# Dynamically assemble a test class with the contents of TEST_DATA - -class TestSimpleValidators(TestCase): - def test_single_message(self): - v = ValidationError('Not Valid') - self.assertEquals(str(v), "[u'Not Valid']") - self.assertEquals(repr(v), "ValidationError([u'Not Valid'])") - - def test_message_list(self): - v = ValidationError(['First Problem', 'Second Problem']) - self.assertEquals(str(v), "[u'First Problem', u'Second Problem']") - self.assertEquals(repr(v), "ValidationError([u'First Problem', u'Second Problem'])") - - def test_message_dict(self): - v = ValidationError({'first': 'First Problem'}) - self.assertEquals(str(v), "{'first': 'First Problem'}") - self.assertEquals(repr(v), "ValidationError({'first': 'First Problem'})") - -test_counter = 0 -for validator, value, expected in TEST_DATA: - name, method = create_simple_test_method(validator, expected, value, test_counter) - setattr(TestSimpleValidators, name, method) - test_counter += 1 diff --git a/parts/django/tests/regressiontests/__init__.py b/parts/django/tests/regressiontests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_changelist/__init__.py b/parts/django/tests/regressiontests/admin_changelist/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_changelist/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_changelist/models.py b/parts/django/tests/regressiontests/admin_changelist/models.py deleted file mode 100644 index f030a78..0000000 --- a/parts/django/tests/regressiontests/admin_changelist/models.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.db import models -from django.contrib import admin - -class Parent(models.Model): - name = models.CharField(max_length=128) - -class Child(models.Model): - parent = models.ForeignKey(Parent, editable=False) - name = models.CharField(max_length=30, blank=True)
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_changelist/tests.py b/parts/django/tests/regressiontests/admin_changelist/tests.py deleted file mode 100644 index 96b36f8..0000000 --- a/parts/django/tests/regressiontests/admin_changelist/tests.py +++ /dev/null @@ -1,103 +0,0 @@ -from django.contrib import admin -from django.contrib.admin.options import IncorrectLookupParameters -from django.contrib.admin.views.main import ChangeList -from django.template import Context, Template -from django.test import TransactionTestCase -from regressiontests.admin_changelist.models import Child, Parent - -class ChangeListTests(TransactionTestCase): - def test_select_related_preserved(self): - """ - Regression test for #10348: ChangeList.get_query_set() shouldn't - overwrite a custom select_related provided by ModelAdmin.queryset(). - """ - m = ChildAdmin(Child, admin.site) - cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links, - m.list_filter, m.date_hierarchy, m.search_fields, - m.list_select_related, m.list_per_page, m.list_editable, m) - self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}}) - - def test_result_list_html(self): - """ - Verifies that inclusion tag result_list generates a table when with - default ModelAdmin settings. - """ - new_parent = Parent.objects.create(name='parent') - new_child = Child.objects.create(name='name', parent=new_parent) - request = MockRequest() - m = ChildAdmin(Child, admin.site) - cl = ChangeList(request, Child, m.list_display, m.list_display_links, - m.list_filter, m.date_hierarchy, m.search_fields, - m.list_select_related, m.list_per_page, m.list_editable, m) - cl.formset = None - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl}) - table_output = template.render(context) - row_html = '<tbody><tr class="row1"><td><input type="checkbox" class="action-select" value="1" name="_selected_action" /></td><th><a href="1/">name</a></th><td>Parent object</td></tr></tbody>' - self.assertFalse(table_output.find(row_html) == -1, - 'Failed to find expected row element: %s' % table_output) - - def test_result_list_editable_html(self): - """ - Regression tests for #11791: Inclusion tag result_list generates a - table and this checks that the items are nested within the table - element tags. - Also a regression test for #13599, verifies that hidden fields - when list_editable is enabled are rendered in a div outside the - table. - """ - new_parent = Parent.objects.create(name='parent') - new_child = Child.objects.create(name='name', parent=new_parent) - request = MockRequest() - m = ChildAdmin(Child, admin.site) - - # Test with list_editable fields - m.list_display = ['id', 'name', 'parent'] - m.list_display_links = ['id'] - m.list_editable = ['name'] - cl = ChangeList(request, Child, m.list_display, m.list_display_links, - m.list_filter, m.date_hierarchy, m.search_fields, - m.list_select_related, m.list_per_page, m.list_editable, m) - FormSet = m.get_changelist_formset(request) - cl.formset = FormSet(queryset=cl.result_list) - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl}) - table_output = template.render(context) - # make sure that hidden fields are in the correct place - hiddenfields_div = '<div class="hiddenfields"><input type="hidden" name="form-0-id" value="1" id="id_form-0-id" /></div>' - self.assertFalse(table_output.find(hiddenfields_div) == -1, - 'Failed to find hidden fields in: %s' % table_output) - # make sure that list editable fields are rendered in divs correctly - editable_name_field = '<input name="form-0-name" value="name" class="vTextField" maxlength="30" type="text" id="id_form-0-name" />' - self.assertFalse('<td>%s</td>' % editable_name_field == -1, - 'Failed to find "name" list_editable field in: %s' % table_output) - - def test_result_list_editable(self): - """ - Regression test for #14312: list_editable with pagination - """ - - new_parent = Parent.objects.create(name='parent') - for i in range(200): - new_child = Child.objects.create(name='name %s' % i, parent=new_parent) - request = MockRequest() - request.GET['p'] = -1 # Anything outside range - m = ChildAdmin(Child, admin.site) - - # Test with list_editable fields - m.list_display = ['id', 'name', 'parent'] - m.list_display_links = ['id'] - m.list_editable = ['name'] - self.assertRaises(IncorrectLookupParameters, lambda: \ - ChangeList(request, Child, m.list_display, m.list_display_links, - m.list_filter, m.date_hierarchy, m.search_fields, - m.list_select_related, m.list_per_page, m.list_editable, m)) - - -class ChildAdmin(admin.ModelAdmin): - list_display = ['name', 'parent'] - def queryset(self, request): - return super(ChildAdmin, self).queryset(request).select_related("parent__name") - -class MockRequest(object): - GET = {} diff --git a/parts/django/tests/regressiontests/admin_inlines/__init__.py b/parts/django/tests/regressiontests/admin_inlines/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_inlines/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_inlines/fixtures/admin-views-users.xml b/parts/django/tests/regressiontests/admin_inlines/fixtures/admin-views-users.xml deleted file mode 100644 index aba8f4a..0000000 --- a/parts/django/tests/regressiontests/admin_inlines/fixtures/admin-views-users.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_inlines/models.py b/parts/django/tests/regressiontests/admin_inlines/models.py deleted file mode 100644 index 4e5c4e3..0000000 --- a/parts/django/tests/regressiontests/admin_inlines/models.py +++ /dev/null @@ -1,125 +0,0 @@ -""" -Testing of admin inline formsets. - -""" -from django.db import models -from django.contrib import admin -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes import generic - -class Parent(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return self.name - -class Teacher(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return self.name - -class Child(models.Model): - name = models.CharField(max_length=50) - teacher = models.ForeignKey(Teacher) - - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - parent = generic.GenericForeignKey() - - def __unicode__(self): - return u'I am %s, a child of %s' % (self.name, self.parent) - -class Book(models.Model): - name = models.CharField(max_length=50) - -class Author(models.Model): - name = models.CharField(max_length=50) - books = models.ManyToManyField(Book) - -class BookInline(admin.TabularInline): - model = Author.books.through - -class AuthorAdmin(admin.ModelAdmin): - inlines = [BookInline] - -admin.site.register(Author, AuthorAdmin) - -class Holder(models.Model): - dummy = models.IntegerField() - - -class Inner(models.Model): - dummy = models.IntegerField() - holder = models.ForeignKey(Holder) - readonly = models.CharField("Inner readonly label", max_length=1) - - -class InnerInline(admin.StackedInline): - model = Inner - can_delete = False - readonly_fields = ('readonly',) # For bug #13174 tests. - - -class Holder2(models.Model): - dummy = models.IntegerField() - - -class Inner2(models.Model): - dummy = models.IntegerField() - holder = models.ForeignKey(Holder2) - -class HolderAdmin(admin.ModelAdmin): - - class Media: - js = ('my_awesome_admin_scripts.js',) - -class InnerInline2(admin.StackedInline): - model = Inner2 - - class Media: - js = ('my_awesome_inline_scripts.js',) - -class Holder3(models.Model): - dummy = models.IntegerField() - - -class Inner3(models.Model): - dummy = models.IntegerField() - holder = models.ForeignKey(Holder3) - -class InnerInline3(admin.StackedInline): - model = Inner3 - - class Media: - js = ('my_awesome_inline_scripts.js',) - -# Test bug #12561 and #12778 -# only ModelAdmin media -admin.site.register(Holder, HolderAdmin, inlines=[InnerInline]) -# ModelAdmin and Inline media -admin.site.register(Holder2, HolderAdmin, inlines=[InnerInline2]) -# only Inline media -admin.site.register(Holder3, inlines=[InnerInline3]) - -# Models for #12749 - -class Person(models.Model): - firstname = models.CharField(max_length=15) - -class OutfitItem(models.Model): - name = models.CharField(max_length=15) - -class Fashionista(models.Model): - person = models.OneToOneField(Person, primary_key=True) - weaknesses = models.ManyToManyField(OutfitItem, through='ShoppingWeakness', blank=True) - -class ShoppingWeakness(models.Model): - fashionista = models.ForeignKey(Fashionista) - item = models.ForeignKey(OutfitItem) - -class InlineWeakness(admin.TabularInline): - model = ShoppingWeakness - extra = 1 - -admin.site.register(Fashionista, inlines=[InlineWeakness]) diff --git a/parts/django/tests/regressiontests/admin_inlines/tests.py b/parts/django/tests/regressiontests/admin_inlines/tests.py deleted file mode 100644 index b10474d..0000000 --- a/parts/django/tests/regressiontests/admin_inlines/tests.py +++ /dev/null @@ -1,121 +0,0 @@ -from django.contrib.admin.helpers import InlineAdminForm -from django.contrib.contenttypes.models import ContentType -from django.test import TestCase - -# local test models -from models import (Holder, Inner, InnerInline, Holder2, Inner2, Holder3, - Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child) - - -class TestInline(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - holder = Holder(dummy=13) - holder.save() - Inner(dummy=42, holder=holder).save() - self.change_url = '/test_admin/admin/admin_inlines/holder/%i/' % holder.id - - result = self.client.login(username='super', password='secret') - self.assertEqual(result, True) - - def tearDown(self): - self.client.logout() - - def test_can_delete(self): - """ - can_delete should be passed to inlineformset factory. - """ - response = self.client.get(self.change_url) - inner_formset = response.context[-1]['inline_admin_formsets'][0].formset - expected = InnerInline.can_delete - actual = inner_formset.can_delete - self.assertEqual(expected, actual, 'can_delete must be equal') - - def test_readonly_stacked_inline_label(self): - """Bug #13174.""" - holder = Holder.objects.create(dummy=42) - inner = Inner.objects.create(holder=holder, dummy=42, readonly='') - response = self.client.get('/test_admin/admin/admin_inlines/holder/%i/' - % holder.id) - self.assertContains(response, '<label>Inner readonly label:</label>') - - def test_many_to_many_inlines(self): - "Autogenerated many-to-many inlines are displayed correctly (#13407)" - response = self.client.get('/test_admin/admin/admin_inlines/author/add/') - # The heading for the m2m inline block uses the right text - self.assertContains(response, '<h2>Author-book relationships</h2>') - # The "add another" label is correct - self.assertContains(response, 'Add another Author-Book Relationship') - # The '+' is dropped from the autogenerated form prefix (Author_books+) - self.assertContains(response, 'id="id_Author_books-TOTAL_FORMS"') - - def test_inline_primary(self): - person = Person.objects.create(firstname='Imelda') - item = OutfitItem.objects.create(name='Shoes') - # Imelda likes shoes, but can't cary her own bags. - data = { - 'shoppingweakness_set-TOTAL_FORMS': 1, - 'shoppingweakness_set-INITIAL_FORMS': 0, - 'shoppingweakness_set-MAX_NUM_FORMS': 0, - '_save': u'Save', - 'person': person.id, - 'max_weight': 0, - 'shoppingweakness_set-0-item': item.id, - } - response = self.client.post('/test_admin/admin/admin_inlines/fashionista/add/', data) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1) - -class TestInlineMedia(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - - result = self.client.login(username='super', password='secret') - self.assertEqual(result, True) - - def tearDown(self): - self.client.logout() - - def test_inline_media_only_base(self): - holder = Holder(dummy=13) - holder.save() - Inner(dummy=42, holder=holder).save() - change_url = '/test_admin/admin/admin_inlines/holder/%i/' % holder.id - response = self.client.get(change_url) - self.assertContains(response, 'my_awesome_admin_scripts.js') - - def test_inline_media_only_inline(self): - holder = Holder3(dummy=13) - holder.save() - Inner3(dummy=42, holder=holder).save() - change_url = '/test_admin/admin/admin_inlines/holder3/%i/' % holder.id - response = self.client.get(change_url) - self.assertContains(response, 'my_awesome_inline_scripts.js') - - def test_all_inline_media(self): - holder = Holder2(dummy=13) - holder.save() - Inner2(dummy=42, holder=holder).save() - change_url = '/test_admin/admin/admin_inlines/holder2/%i/' % holder.id - response = self.client.get(change_url) - self.assertContains(response, 'my_awesome_admin_scripts.js') - self.assertContains(response, 'my_awesome_inline_scripts.js') - -class TestInlineAdminForm(TestCase): - - def test_immutable_content_type(self): - """Regression for #9362 - The problem depends only on InlineAdminForm and its "original" - argument, so we can safely set the other arguments to None/{}. We just - need to check that the content_type argument of Child isn't altered by - the internals of the inline form.""" - - sally = Teacher.objects.create(name='Sally') - john = Parent.objects.create(name='John') - joe = Child.objects.create(name='Joe', teacher=sally, parent=john) - - iaf = InlineAdminForm(None, None, {}, {}, joe) - parent_ct = ContentType.objects.get_for_model(Parent) - self.assertEqual(iaf.original.content_type, parent_ct) diff --git a/parts/django/tests/regressiontests/admin_ordering/__init__.py b/parts/django/tests/regressiontests/admin_ordering/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_ordering/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_ordering/models.py b/parts/django/tests/regressiontests/admin_ordering/models.py deleted file mode 100644 index ad63685..0000000 --- a/parts/django/tests/regressiontests/admin_ordering/models.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding: utf-8 -from django.db import models - -class Band(models.Model): - name = models.CharField(max_length=100) - bio = models.TextField() - rank = models.IntegerField() - - class Meta: - ordering = ('name',) diff --git a/parts/django/tests/regressiontests/admin_ordering/tests.py b/parts/django/tests/regressiontests/admin_ordering/tests.py deleted file mode 100644 index f63f202..0000000 --- a/parts/django/tests/regressiontests/admin_ordering/tests.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.test import TestCase -from django.contrib.admin.options import ModelAdmin - -from models import Band - -class TestAdminOrdering(TestCase): - """ - Let's make sure that ModelAdmin.queryset uses the ordering we define in - ModelAdmin rather that ordering defined in the model's inner Meta - class. - """ - - def setUp(self): - b1 = Band(name='Aerosmith', bio='', rank=3) - b1.save() - b2 = Band(name='Radiohead', bio='', rank=1) - b2.save() - b3 = Band(name='Van Halen', bio='', rank=2) - b3.save() - - def test_default_ordering(self): - """ - The default ordering should be by name, as specified in the inner Meta - class. - """ - ma = ModelAdmin(Band, None) - names = [b.name for b in ma.queryset(None)] - self.assertEqual([u'Aerosmith', u'Radiohead', u'Van Halen'], names) - - def test_specified_ordering(self): - """ - Let's use a custom ModelAdmin that changes the ordering, and make sure - it actually changes. - """ - class BandAdmin(ModelAdmin): - ordering = ('rank',) # default ordering is ('name',) - ma = BandAdmin(Band, None) - names = [b.name for b in ma.queryset(None)] - self.assertEqual([u'Radiohead', u'Van Halen', u'Aerosmith'], names) diff --git a/parts/django/tests/regressiontests/admin_registration/__init__.py b/parts/django/tests/regressiontests/admin_registration/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_registration/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_registration/models.py b/parts/django/tests/regressiontests/admin_registration/models.py deleted file mode 100644 index 4a2d4e9..0000000 --- a/parts/django/tests/regressiontests/admin_registration/models.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -Tests for various ways of registering models with the admin site. -""" - -from django.db import models - -class Person(models.Model): - name = models.CharField(max_length=200) - -class Place(models.Model): - name = models.CharField(max_length=200) diff --git a/parts/django/tests/regressiontests/admin_registration/tests.py b/parts/django/tests/regressiontests/admin_registration/tests.py deleted file mode 100644 index e2a5d7e..0000000 --- a/parts/django/tests/regressiontests/admin_registration/tests.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.test import TestCase - -from django.contrib import admin - -from models import Person, Place - -class NameAdmin(admin.ModelAdmin): - list_display = ['name'] - save_on_top = True - -class TestRegistration(TestCase): - def setUp(self): - self.site = admin.AdminSite() - - def test_bare_registration(self): - self.site.register(Person) - self.assertTrue( - isinstance(self.site._registry[Person], admin.options.ModelAdmin) - ) - - def test_registration_with_model_admin(self): - self.site.register(Person, NameAdmin) - self.assertTrue( - isinstance(self.site._registry[Person], NameAdmin) - ) - - def test_prevent_double_registration(self): - self.site.register(Person) - self.assertRaises(admin.sites.AlreadyRegistered, - self.site.register, - Person) - - def test_registration_with_star_star_options(self): - self.site.register(Person, search_fields=['name']) - self.assertEqual(self.site._registry[Person].search_fields, ['name']) - - def test_star_star_overrides(self): - self.site.register(Person, NameAdmin, - search_fields=["name"], list_display=['__str__']) - self.assertEqual(self.site._registry[Person].search_fields, ['name']) - self.assertEqual(self.site._registry[Person].list_display, - ['action_checkbox', '__str__']) - self.assertTrue(self.site._registry[Person].save_on_top) - - def test_iterable_registration(self): - self.site.register([Person, Place], search_fields=['name']) - self.assertTrue( - isinstance(self.site._registry[Person], admin.options.ModelAdmin) - ) - self.assertEqual(self.site._registry[Person].search_fields, ['name']) - self.assertTrue( - isinstance(self.site._registry[Place], admin.options.ModelAdmin) - ) - self.assertEqual(self.site._registry[Place].search_fields, ['name']) diff --git a/parts/django/tests/regressiontests/admin_scripts/__init__.py b/parts/django/tests/regressiontests/admin_scripts/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/app_with_import/__init__.py b/parts/django/tests/regressiontests/admin_scripts/app_with_import/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/app_with_import/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/app_with_import/models.py b/parts/django/tests/regressiontests/admin_scripts/app_with_import/models.py deleted file mode 100644 index 06ca0e8..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/app_with_import/models.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.contrib.comments.models import Comment -from django.db import models - -# Regression for #13368. This is an example of a model -# that imports a class that has an abstract base class. -class CommentScore(models.Model): - comment = models.OneToOneField(Comment, primary_key=True) diff --git a/parts/django/tests/regressiontests/admin_scripts/broken_app/__init__.py b/parts/django/tests/regressiontests/admin_scripts/broken_app/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/broken_app/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/broken_app/models.py b/parts/django/tests/regressiontests/admin_scripts/broken_app/models.py deleted file mode 100644 index f37f1ef..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/broken_app/models.py +++ /dev/null @@ -1 +0,0 @@ -from django.db import modelz diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/__init__.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/__init__.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/foo.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/foo.py deleted file mode 100644 index 1b933d0..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/admin/foo.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin -from admin_scripts.complex_app.models.foo import Foo -admin.site.register(Foo) diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/__init__.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/models/__init__.py deleted file mode 100644 index a4d6d95..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from admin_scripts.complex_app.models.bar import Bar -from admin_scripts.complex_app.models.foo import Foo - -__all__ = ['Foo', 'Bar'] diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/bar.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/models/bar.py deleted file mode 100644 index a5d8853..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/bar.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.db import models - -from admin_scripts.complex_app.admin import foo -class Bar(models.Model): - name = models.CharField(max_length=5) - class Meta: - app_label = 'complex_app' diff --git a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/foo.py b/parts/django/tests/regressiontests/admin_scripts/complex_app/models/foo.py deleted file mode 100644 index 70c285e..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/complex_app/models/foo.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.db import models - -class Foo(models.Model): - name = models.CharField(max_length=5) - class Meta: - app_label = 'complex_app' diff --git a/parts/django/tests/regressiontests/admin_scripts/management/__init__.py b/parts/django/tests/regressiontests/admin_scripts/management/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/management/commands/__init__.py b/parts/django/tests/regressiontests/admin_scripts/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/commands/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/management/commands/app_command.py b/parts/django/tests/regressiontests/admin_scripts/management/commands/app_command.py deleted file mode 100644 index f72e912..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/commands/app_command.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.core.management.base import AppCommand - -class Command(AppCommand): - help = 'Test Application-based commands' - requires_model_validation = False - args = '[appname ...]' - - def handle_app(self, app, **options): - print 'EXECUTE:AppCommand app=%s, options=%s' % (app, sorted(options.items())) - diff --git a/parts/django/tests/regressiontests/admin_scripts/management/commands/base_command.py b/parts/django/tests/regressiontests/admin_scripts/management/commands/base_command.py deleted file mode 100644 index 438f703..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/commands/base_command.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.core.management.base import BaseCommand -from optparse import make_option - -class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option('--option_a','-a', action='store', dest='option_a', default='1'), - make_option('--option_b','-b', action='store', dest='option_b', default='2'), - make_option('--option_c','-c', action='store', dest='option_c', default='3'), - ) - help = 'Test basic commands' - requires_model_validation = False - args = '[labels ...]' - - def handle(self, *labels, **options): - print 'EXECUTE:BaseCommand labels=%s, options=%s' % (labels, sorted(options.items())) diff --git a/parts/django/tests/regressiontests/admin_scripts/management/commands/label_command.py b/parts/django/tests/regressiontests/admin_scripts/management/commands/label_command.py deleted file mode 100644 index 2b735c8..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/commands/label_command.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.core.management.base import LabelCommand - -class Command(LabelCommand): - help = "Test Label-based commands" - requires_model_validation = False - args = '<label>' - - def handle_label(self, label, **options): - print 'EXECUTE:LabelCommand label=%s, options=%s' % (label, sorted(options.items())) diff --git a/parts/django/tests/regressiontests/admin_scripts/management/commands/noargs_command.py b/parts/django/tests/regressiontests/admin_scripts/management/commands/noargs_command.py deleted file mode 100644 index 683eb7a..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/management/commands/noargs_command.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.core.management.base import NoArgsCommand - -class Command(NoArgsCommand): - help = "Test No-args commands" - requires_model_validation = False - - - def handle_noargs(self, **options): - print 'EXECUTE:NoArgsCommand options=%s' % sorted(options.items()) diff --git a/parts/django/tests/regressiontests/admin_scripts/models.py b/parts/django/tests/regressiontests/admin_scripts/models.py deleted file mode 100644 index 96a40d2..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/models.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.db import models - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('-pub_date', 'headline') -
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_scripts/simple_app/__init__.py b/parts/django/tests/regressiontests/admin_scripts/simple_app/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/simple_app/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_scripts/simple_app/models.py b/parts/django/tests/regressiontests/admin_scripts/simple_app/models.py deleted file mode 100644 index 65b30ed..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/simple_app/models.py +++ /dev/null @@ -1 +0,0 @@ -from admin_scripts.complex_app.models.bar import Bar diff --git a/parts/django/tests/regressiontests/admin_scripts/tests.py b/parts/django/tests/regressiontests/admin_scripts/tests.py deleted file mode 100644 index 2a7f302..0000000 --- a/parts/django/tests/regressiontests/admin_scripts/tests.py +++ /dev/null @@ -1,1199 +0,0 @@ -""" -A series of tests to establish that the command-line managment tools work as -advertised - especially with regards to the handling of the DJANGO_SETTINGS_MODULE -and default settings.py files. -""" -import os -import unittest -import shutil -import sys -import re - -from django import conf, bin, get_version -from django.conf import settings - - -class AdminScriptTestCase(unittest.TestCase): - def write_settings(self, filename, apps=None, is_dir=False, sdict=None): - test_dir = os.path.dirname(os.path.dirname(__file__)) - if is_dir: - settings_dir = os.path.join(test_dir,filename) - os.mkdir(settings_dir) - settings_file = open(os.path.join(settings_dir,'__init__.py'), 'w') - else: - settings_file = open(os.path.join(test_dir, filename), 'w') - settings_file.write('# Settings file automatically generated by regressiontests.admin_scripts test case\n') - exports = [ - 'DATABASES', - 'ROOT_URLCONF' - ] - for s in exports: - if hasattr(settings, s): - o = getattr(settings, s) - if not isinstance(o, dict): - o = "'%s'" % o - settings_file.write("%s = %s\n" % (s, o)) - - if apps is None: - apps = ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts'] - - if apps: - settings_file.write("INSTALLED_APPS = %s\n" % apps) - - if sdict: - for k, v in sdict.items(): - settings_file.write("%s = %s\n" % (k, v)) - - settings_file.close() - - def remove_settings(self, filename, is_dir=False): - test_dir = os.path.dirname(os.path.dirname(__file__)) - full_name = os.path.join(test_dir, filename) - if is_dir: - shutil.rmtree(full_name) - else: - os.remove(full_name) - - # Also try to remove the compiled file; if it exists, it could - # mess up later tests that depend upon the .py file not existing - try: - if sys.platform.startswith('java'): - # Jython produces module$py.class files - os.remove(re.sub(r'\.py$', '$py.class', full_name)) - else: - # CPython produces module.pyc files - os.remove(full_name + 'c') - except OSError: - pass - - def _ext_backend_paths(self): - """ - Returns the paths for any external backend packages. - """ - paths = [] - first_package_re = re.compile(r'(^[^\.]+)\.') - for backend in settings.DATABASES.values(): - result = first_package_re.findall(backend['ENGINE']) - if result and result != 'django': - backend_pkg = __import__(result[0]) - backend_dir = os.path.dirname(backend_pkg.__file__) - paths.append(os.path.dirname(backend_dir)) - return paths - - def run_test(self, script, args, settings_file=None, apps=None): - test_dir = os.path.dirname(os.path.dirname(__file__)) - project_dir = os.path.dirname(test_dir) - base_dir = os.path.dirname(project_dir) - ext_backend_base_dirs = self._ext_backend_paths() - - # Remember the old environment - old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None) - if sys.platform.startswith('java'): - python_path_var_name = 'JYTHONPATH' - else: - python_path_var_name = 'PYTHONPATH' - - old_python_path = os.environ.get(python_path_var_name, None) - old_cwd = os.getcwd() - - # Set the test environment - if settings_file: - os.environ['DJANGO_SETTINGS_MODULE'] = settings_file - elif 'DJANGO_SETTINGS_MODULE' in os.environ: - del os.environ['DJANGO_SETTINGS_MODULE'] - python_path = [test_dir, base_dir] - python_path.extend(ext_backend_base_dirs) - os.environ[python_path_var_name] = os.pathsep.join(python_path) - - # Build the command line - executable = sys.executable - arg_string = ' '.join(['%s' % arg for arg in args]) - if ' ' in executable: - cmd = '""%s" "%s" %s"' % (executable, script, arg_string) - else: - cmd = '%s "%s" %s' % (executable, script, arg_string) - - # Move to the test directory and run - os.chdir(test_dir) - try: - from subprocess import Popen, PIPE - p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) - stdin, stdout, stderr = (p.stdin, p.stdout, p.stderr) - p.wait() - except ImportError: - stdin, stdout, stderr = os.popen3(cmd) - out, err = stdout.read(), stderr.read() - - # Restore the old environment - if old_django_settings_module: - os.environ['DJANGO_SETTINGS_MODULE'] = old_django_settings_module - if old_python_path: - os.environ[python_path_var_name] = old_python_path - # Move back to the old working directory - os.chdir(old_cwd) - - return out, err - - def run_django_admin(self, args, settings_file=None): - bin_dir = os.path.abspath(os.path.dirname(bin.__file__)) - return self.run_test(os.path.join(bin_dir,'django-admin.py'), args, settings_file) - - def run_manage(self, args, settings_file=None): - conf_dir = os.path.dirname(conf.__file__) - template_manage_py = os.path.join(conf_dir, 'project_template', 'manage.py') - - test_dir = os.path.dirname(os.path.dirname(__file__)) - test_manage_py = os.path.join(test_dir, 'manage.py') - shutil.copyfile(template_manage_py, test_manage_py) - - stdout, stderr = self.run_test('./manage.py', args, settings_file) - - # Cleanup - remove the generated manage.py script - os.remove(test_manage_py) - - return stdout, stderr - - def assertNoOutput(self, stream): - "Utility assertion: assert that the given stream is empty" - self.assertEquals(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream) - def assertOutput(self, stream, msg): - "Utility assertion: assert that the given message exists in the output" - self.assertTrue(msg in stream, "'%s' does not match actual output text '%s'" % (msg, stream)) - -########################################################################## -# DJANGO ADMIN TESTS -# This first series of test classes checks the environment processing -# of the django-admin.py script -########################################################################## - - -class DjangoAdminNoSettings(AdminScriptTestCase): - "A series of tests for django-admin.py when there is no settings.py file." - - def test_builtin_command(self): - "no settings: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_bad_settings(self): - "no settings: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "no settings: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - -class DjangoAdminDefaultSettings(AdminScriptTestCase): - """A series of tests for django-admin.py when using a settings.py file that - contains the test application. - """ - def setUp(self): - self.write_settings('settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "default: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_settings(self): - "default: django-admin builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "default: django-admin builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "default: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "default: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "default: django-admin can't execute user commands if it isn't provided settings" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "default: django-admin can execute user commands if settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "default: django-admin can execute user commands if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - -class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase): - """A series of tests for django-admin.py when using a settings.py file that - contains the test application specified using a full path. - """ - def setUp(self): - self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'regressiontests.admin_scripts']) - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "fulldefault: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_settings(self): - "fulldefault: django-admin builtin commands succeed if a settings file is provided" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "fulldefault: django-admin builtin commands succeed if the environment contains settings" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "fulldefault: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "fulldefault: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "fulldefault: django-admin can't execute user commands unless settings are provided" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "fulldefault: django-admin can execute user commands if settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "fulldefault: django-admin can execute user commands if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - -class DjangoAdminMinimalSettings(AdminScriptTestCase): - """A series of tests for django-admin.py when using a settings.py file that - doesn't contain the test application. - """ - def setUp(self): - self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes']) - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "minimal: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_settings(self): - "minimal: django-admin builtin commands fail if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_builtin_with_environment(self): - "minimal: django-admin builtin commands fail if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_builtin_with_bad_settings(self): - "minimal: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "minimal: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "minimal: django-admin can't execute user commands unless settings are provided" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "minimal: django-admin can't execute user commands, even if settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_environment(self): - "minimal: django-admin can't execute user commands, even if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - -class DjangoAdminAlternateSettings(AdminScriptTestCase): - """A series of tests for django-admin.py when using a settings file - with a name other than 'settings.py'. - """ - def setUp(self): - self.write_settings('alternate_settings.py') - - def tearDown(self): - self.remove_settings('alternate_settings.py') - - def test_builtin_command(self): - "alternate: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_settings(self): - "alternate: django-admin builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=alternate_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "alternate: django-admin builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'alternate_settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "alternate: django-admin can't execute user commands unless settings are provided" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "alternate: django-admin can execute user commands if settings are provided as argument" - args = ['noargs_command', '--settings=alternate_settings'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "alternate: django-admin can execute user commands if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_django_admin(args,'alternate_settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - -class DjangoAdminMultipleSettings(AdminScriptTestCase): - """A series of tests for django-admin.py when multiple settings files - (including the default 'settings.py') are available. The default settings - file is insufficient for performing the operations described, so the - alternate settings must be used by the running script. - """ - def setUp(self): - self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes']) - self.write_settings('alternate_settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - self.remove_settings('alternate_settings.py') - - def test_builtin_command(self): - "alternate: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_settings(self): - "alternate: django-admin builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=alternate_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "alternate: django-admin builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'alternate_settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "alternate: django-admin can't execute user commands unless settings are provided" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "alternate: django-admin can't execute user commands, even if settings are provided as argument" - args = ['noargs_command', '--settings=alternate_settings'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "alternate: django-admin can't execute user commands, even if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_django_admin(args,'alternate_settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - -class DjangoAdminSettingsDirectory(AdminScriptTestCase): - """ - A series of tests for django-admin.py when the settings file is in a - directory. (see #9751). - """ - - def setUp(self): - self.write_settings('settings', is_dir=True) - - def tearDown(self): - self.remove_settings('settings', is_dir=True) - - def test_setup_environ(self): - "directory: startapp creates the correct directory" - test_dir = os.path.dirname(os.path.dirname(__file__)) - args = ['startapp','settings_test'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assert_(os.path.exists(os.path.join(test_dir, 'settings_test'))) - shutil.rmtree(os.path.join(test_dir, 'settings_test')) - - def test_builtin_command(self): - "directory: django-admin builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined') - - def test_builtin_with_bad_settings(self): - "directory: django-admin builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "directory: django-admin builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_custom_command(self): - "directory: django-admin can't execute user commands unless settings are provided" - args = ['noargs_command'] - out, err = self.run_django_admin(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_builtin_with_settings(self): - "directory: django-admin builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_django_admin(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "directory: django-admin builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_django_admin(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - -########################################################################## -# MANAGE.PY TESTS -# This next series of test classes checks the environment processing -# of the generated manage.py script -########################################################################## - -class ManageNoSettings(AdminScriptTestCase): - "A series of tests for manage.py when there is no settings.py file." - - def test_builtin_command(self): - "no settings: manage.py builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_bad_settings(self): - "no settings: manage.py builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_bad_environment(self): - "no settings: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - -class ManageDefaultSettings(AdminScriptTestCase): - """A series of tests for manage.py when using a settings.py file that - contains the test application. - """ - def setUp(self): - self.write_settings('settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "default: manage.py builtin commands succeed when default settings are appropriate" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_settings(self): - "default: manage.py builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "default: manage.py builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "default: manage.py builtin commands succeed if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "default: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_custom_command(self): - "default: manage.py can execute user commands when default settings are appropriate" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_settings(self): - "default: manage.py can execute user commands when settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "default: manage.py can execute user commands when settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - -class ManageFullPathDefaultSettings(AdminScriptTestCase): - """A series of tests for manage.py when using a settings.py file that - contains the test application specified using a full path. - """ - def setUp(self): - self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'regressiontests.admin_scripts']) - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "fulldefault: manage.py builtin commands succeed when default settings are appropriate" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_settings(self): - "fulldefault: manage.py builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "fulldefault: manage.py builtin commands succeed if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_bad_settings(self): - "fulldefault: manage.py builtin commands succeed if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "fulldefault: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_custom_command(self): - "fulldefault: manage.py can execute user commands when default settings are appropriate" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_settings(self): - "fulldefault: manage.py can execute user commands when settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "fulldefault: manage.py can execute user commands when settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - -class ManageMinimalSettings(AdminScriptTestCase): - """A series of tests for manage.py when using a settings.py file that - doesn't contain the test application. - """ - def setUp(self): - self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes']) - - def tearDown(self): - self.remove_settings('settings.py') - - def test_builtin_command(self): - "minimal: manage.py builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_builtin_with_settings(self): - "minimal: manage.py builtin commands fail if settings are provided as argument" - args = ['sqlall','--settings=settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_builtin_with_environment(self): - "minimal: manage.py builtin commands fail if settings are provided in the environment" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_builtin_with_bad_settings(self): - "minimal: manage.py builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "minimal: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found') - - def test_custom_command(self): - "minimal: manage.py can't execute user commands without appropriate settings" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "minimal: manage.py can't execute user commands, even if settings are provided as argument" - args = ['noargs_command', '--settings=settings'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_environment(self): - "minimal: manage.py can't execute user commands, even if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_manage(args,'settings') - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - -class ManageAlternateSettings(AdminScriptTestCase): - """A series of tests for manage.py when using a settings file - with a name other than 'settings.py'. - """ - def setUp(self): - self.write_settings('alternate_settings.py') - - def tearDown(self): - self.remove_settings('alternate_settings.py') - - def test_builtin_command(self): - "alternate: manage.py builtin commands fail with an import error when no default settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_settings(self): - "alternate: manage.py builtin commands fail if settings are provided as argument but no defaults" - args = ['sqlall','--settings=alternate_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_environment(self): - "alternate: manage.py builtin commands fail if settings are provided in the environment but no defaults" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'alternate_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_bad_settings(self): - "alternate: manage.py builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_builtin_with_bad_environment(self): - "alternate: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_custom_command(self): - "alternate: manage.py can't execute user commands" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_custom_command_with_settings(self): - "alternate: manage.py can't execute user commands, even if settings are provided as argument" - args = ['noargs_command', '--settings=alternate_settings'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - def test_custom_command_with_environment(self): - "alternate: manage.py can't execute user commands, even if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_manage(args,'alternate_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'") - - -class ManageMultipleSettings(AdminScriptTestCase): - """A series of tests for manage.py when multiple settings files - (including the default 'settings.py') are available. The default settings - file is insufficient for performing the operations described, so the - alternate settings must be used by the running script. - """ - def setUp(self): - self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes']) - self.write_settings('alternate_settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - self.remove_settings('alternate_settings.py') - - def test_builtin_command(self): - "multiple: manage.py builtin commands fail with an import error when no settings provided" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found.') - - def test_builtin_with_settings(self): - "multiple: manage.py builtin commands succeed if settings are provided as argument" - args = ['sqlall','--settings=alternate_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, 'CREATE TABLE') - - def test_builtin_with_environment(self): - "multiple: manage.py builtin commands fail if settings are provided in the environment" - # FIXME: This doesn't seem to be the correct output. - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'alternate_settings') - self.assertNoOutput(out) - self.assertOutput(err, 'App with label admin_scripts could not be found.') - - def test_builtin_with_bad_settings(self): - "multiple: manage.py builtin commands fail if settings file (from argument) doesn't exist" - args = ['sqlall','--settings=bad_settings', 'admin_scripts'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Could not import settings 'bad_settings'") - - def test_builtin_with_bad_environment(self): - "multiple: manage.py builtin commands fail if settings file (from environment) doesn't exist" - args = ['sqlall','admin_scripts'] - out, err = self.run_manage(args,'bad_settings') - self.assertNoOutput(out) - self.assertOutput(err, "App with label admin_scripts could not be found") - - def test_custom_command(self): - "multiple: manage.py can't execute user commands using default settings" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - def test_custom_command_with_settings(self): - "multiple: manage.py can execute user commands if settings are provided as argument" - args = ['noargs_command', '--settings=alternate_settings'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand") - - def test_custom_command_with_environment(self): - "multiple: manage.py can execute user commands if settings are provided in environment" - args = ['noargs_command'] - out, err = self.run_manage(args,'alternate_settings') - self.assertNoOutput(out) - self.assertOutput(err, "Unknown command: 'noargs_command'") - - -class ManageValidate(AdminScriptTestCase): - def tearDown(self): - self.remove_settings('settings.py') - - def test_nonexistent_app(self): - "manage.py validate reports an error on a non-existent app in INSTALLED_APPS" - self.write_settings('settings.py', apps=['admin_scriptz.broken_app'], sdict={'USE_I18N': False}) - args = ['validate'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, 'No module named admin_scriptz') - - def test_broken_app(self): - "manage.py validate reports an ImportError if an app's models.py raises one on import" - self.write_settings('settings.py', apps=['admin_scripts.broken_app']) - args = ['validate'] - out, err = self.run_manage(args) - self.assertNoOutput(out) - self.assertOutput(err, 'ImportError') - - def test_complex_app(self): - "manage.py validate does not raise an ImportError validating a complex app with nested calls to load_app" - self.write_settings('settings.py', - apps=['admin_scripts.complex_app', 'admin_scripts.simple_app'], - sdict={'DEBUG': True}) - args = ['validate'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, '0 errors found') - - def test_app_with_import(self): - "manage.py validate does not raise errors when an app imports a base class that itself has an abstract base" - self.write_settings('settings.py', - apps=['admin_scripts.app_with_import', 'django.contrib.comments'], - sdict={'DEBUG': True}) - args = ['validate'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, '0 errors found') - -########################################################################## -# COMMAND PROCESSING TESTS -# Check that user-space commands are correctly handled - in particular, -# that arguments to the commands are correctly parsed and processed. -########################################################################## - -class CommandTypes(AdminScriptTestCase): - "Tests for the various types of base command types that can be defined." - def setUp(self): - self.write_settings('settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - - def test_version(self): - "--version is handled as a special case" - args = ['--version'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - # Only check the first part of the version number - self.assertOutput(out, get_version().split('-')[0]) - - def test_help(self): - "--help is handled as a special case" - args = ['--help'] - out, err = self.run_manage(args) - if sys.version_info < (2, 5): - self.assertOutput(out, "usage: manage.py subcommand [options] [args]") - else: - self.assertOutput(out, "Usage: manage.py subcommand [options] [args]") - self.assertOutput(err, "Type 'manage.py help <subcommand>' for help on a specific subcommand.") - - def test_specific_help(self): - "--help can be used on a specific command" - args = ['sqlall','--help'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).") - - def test_base_command(self): - "User BaseCommands can execute when a label is provided" - args = ['base_command','testlabel'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_base_command_no_label(self): - "User BaseCommands can execute when no labels are provided" - args = ['base_command'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_base_command_multiple_label(self): - "User BaseCommands can execute when no labels are provided" - args = ['base_command','testlabel','anotherlabel'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_base_command_with_option(self): - "User BaseCommands can execute with options when a label is provided" - args = ['base_command','testlabel','--option_a=x'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_base_command_with_options(self): - "User BaseCommands can execute with multiple options when a label is provided" - args = ['base_command','testlabel','-a','x','--option_b=y'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_noargs(self): - "NoArg Commands can be executed" - args = ['noargs_command'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_noargs_with_args(self): - "NoArg Commands raise an error if an argument is provided" - args = ['noargs_command','argument'] - out, err = self.run_manage(args) - self.assertOutput(err, "Error: Command doesn't accept any arguments") - - def test_app_command(self): - "User AppCommands can execute when a single app name is provided" - args = ['app_command', 'auth'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'") - self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py'])) - self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_app_command_no_apps(self): - "User AppCommands raise an error when no app name is provided" - args = ['app_command'] - out, err = self.run_manage(args) - self.assertOutput(err, 'Error: Enter at least one appname.') - - def test_app_command_multiple_apps(self): - "User AppCommands raise an error when multiple app names are provided" - args = ['app_command','auth','contenttypes'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'") - self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py'])) - self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'") - self.assertOutput(out, os.sep.join(['django','contrib','contenttypes','models.py'])) - self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_app_command_invalid_appname(self): - "User AppCommands can execute when a single app name is provided" - args = ['app_command', 'NOT_AN_APP'] - out, err = self.run_manage(args) - self.assertOutput(err, "App with label NOT_AN_APP could not be found") - - def test_app_command_some_invalid_appnames(self): - "User AppCommands can execute when some of the provided app names are invalid" - args = ['app_command', 'auth', 'NOT_AN_APP'] - out, err = self.run_manage(args) - self.assertOutput(err, "App with label NOT_AN_APP could not be found") - - def test_label_command(self): - "User LabelCommands can execute when a label is provided" - args = ['label_command','testlabel'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - - def test_label_command_no_label(self): - "User LabelCommands raise an error if no label is provided" - args = ['label_command'] - out, err = self.run_manage(args) - self.assertOutput(err, 'Enter at least one label') - - def test_label_command_multiple_label(self): - "User LabelCommands are executed multiple times if multiple labels are provided" - args = ['label_command','testlabel','anotherlabel'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") - -class ArgumentOrder(AdminScriptTestCase): - """Tests for 2-stage argument parsing scheme. - - django-admin command arguments are parsed in 2 parts; the core arguments - (--settings, --traceback and --pythonpath) are parsed using a Lax parser. - This Lax parser ignores any unknown options. Then the full settings are - passed to the command parser, which extracts commands of interest to the - individual command. - """ - def setUp(self): - self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes']) - self.write_settings('alternate_settings.py') - - def tearDown(self): - self.remove_settings('settings.py') - self.remove_settings('alternate_settings.py') - - def test_setting_then_option(self): - "Options passed after settings are correctly handled" - args = ['base_command','testlabel','--settings=alternate_settings','--option_a=x'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") - - def test_setting_then_short_option(self): - "Short options passed after settings are correctly handled" - args = ['base_command','testlabel','--settings=alternate_settings','--option_a=x'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") - - def test_option_then_setting(self): - "Options passed before settings are correctly handled" - args = ['base_command','testlabel','--option_a=x','--settings=alternate_settings'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") - - def test_short_option_then_setting(self): - "Short options passed before settings are correctly handled" - args = ['base_command','testlabel','-a','x','--settings=alternate_settings'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") - - def test_option_then_setting_then_option(self): - "Options are correctly handled when they are passed before and after a setting" - args = ['base_command','testlabel','--option_a=x','--settings=alternate_settings','--option_b=y'] - out, err = self.run_manage(args) - self.assertNoOutput(err) - self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") diff --git a/parts/django/tests/regressiontests/admin_util/__init__.py b/parts/django/tests/regressiontests/admin_util/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_util/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_util/models.py b/parts/django/tests/regressiontests/admin_util/models.py deleted file mode 100644 index 3191a55..0000000 --- a/parts/django/tests/regressiontests/admin_util/models.py +++ /dev/null @@ -1,33 +0,0 @@ -from django.db import models - -class Article(models.Model): - """ - A simple Article model for testing - """ - site = models.ForeignKey('sites.Site', related_name="admin_articles") - title = models.CharField(max_length=100) - title2 = models.CharField(max_length=100, verbose_name="another name") - created = models.DateTimeField() - - def test_from_model(self): - return "nothing" - - def test_from_model_with_override(self): - return "nothing" - test_from_model_with_override.short_description = "not What you Expect" - -class Count(models.Model): - num = models.PositiveSmallIntegerField() - -class Event(models.Model): - date = models.DateTimeField(auto_now_add=True) - -class Location(models.Model): - event = models.OneToOneField(Event, verbose_name='awesome event') - -class Guest(models.Model): - event = models.OneToOneField(Event) - name = models.CharField(max_length=255) - - class Meta: - verbose_name = "awesome guest" diff --git a/parts/django/tests/regressiontests/admin_util/tests.py b/parts/django/tests/regressiontests/admin_util/tests.py deleted file mode 100644 index 7476d10..0000000 --- a/parts/django/tests/regressiontests/admin_util/tests.py +++ /dev/null @@ -1,239 +0,0 @@ -from datetime import datetime -import unittest - -from django.conf import settings -from django.db import models -from django.utils.formats import localize -from django.test import TestCase - -from django.contrib import admin -from django.contrib.admin.util import display_for_field, label_for_field, lookup_field -from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE -from django.contrib.sites.models import Site -from django.contrib.admin.util import NestedObjects - -from models import Article, Count, Event, Location - - -class NestedObjectsTests(TestCase): - """ - Tests for ``NestedObject`` utility collection. - - """ - def setUp(self): - self.n = NestedObjects() - self.objs = [Count.objects.create(num=i) for i in range(5)] - - def _check(self, target): - self.assertEquals(self.n.nested(lambda obj: obj.num), target) - - def _add(self, obj, parent=None): - # don't bother providing the extra args that NestedObjects ignores - self.n.add(None, None, obj, None, parent) - - def test_unrelated_roots(self): - self._add(self.objs[0]) - self._add(self.objs[1]) - self._add(self.objs[2], self.objs[1]) - - self._check([0, 1, [2]]) - - def test_siblings(self): - self._add(self.objs[0]) - self._add(self.objs[1], self.objs[0]) - self._add(self.objs[2], self.objs[0]) - - self._check([0, [1, 2]]) - - def test_duplicate_instances(self): - self._add(self.objs[0]) - self._add(self.objs[1]) - dupe = Count.objects.get(num=1) - self._add(dupe, self.objs[0]) - - self._check([0, 1]) - - def test_non_added_parent(self): - self._add(self.objs[0], self.objs[1]) - - self._check([0]) - - def test_cyclic(self): - self._add(self.objs[0], self.objs[2]) - self._add(self.objs[1], self.objs[0]) - self._add(self.objs[2], self.objs[1]) - self._add(self.objs[0], self.objs[2]) - - self._check([0, [1, [2]]]) - - -class UtilTests(unittest.TestCase): - def test_values_from_lookup_field(self): - """ - Regression test for #12654: lookup_field - """ - SITE_NAME = 'example.com' - TITLE_TEXT = 'Some title' - CREATED_DATE = datetime.min - ADMIN_METHOD = 'admin method' - SIMPLE_FUNCTION = 'function' - INSTANCE_ATTRIBUTE = 'attr' - - class MockModelAdmin(object): - def get_admin_value(self, obj): - return ADMIN_METHOD - - simple_function = lambda obj: SIMPLE_FUNCTION - - article = Article( - site=Site(domain=SITE_NAME), - title=TITLE_TEXT, - created=CREATED_DATE, - ) - article.non_field = INSTANCE_ATTRIBUTE - - verifications = ( - ('site', SITE_NAME), - ('created', localize(CREATED_DATE)), - ('title', TITLE_TEXT), - ('get_admin_value', ADMIN_METHOD), - (simple_function, SIMPLE_FUNCTION), - ('test_from_model', article.test_from_model()), - ('non_field', INSTANCE_ATTRIBUTE) - ) - - mock_admin = MockModelAdmin() - for name, value in verifications: - field, attr, resolved_value = lookup_field(name, article, mock_admin) - - if field is not None: - resolved_value = display_for_field(resolved_value, field) - - self.assertEqual(value, resolved_value) - - def test_null_display_for_field(self): - """ - Regression test for #12550: display_for_field should handle None - value. - """ - display_value = display_for_field(None, models.CharField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) - - display_value = display_for_field(None, models.CharField( - choices=( - (None, "test_none"), - ) - )) - self.assertEqual(display_value, "test_none") - - display_value = display_for_field(None, models.DateField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) - - display_value = display_for_field(None, models.TimeField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) - - # Regression test for #13071: NullBooleanField has special - # handling. - display_value = display_for_field(None, models.NullBooleanField()) - expected = u'<img src="%simg/admin/icon-unknown.gif" alt="None" />' % settings.ADMIN_MEDIA_PREFIX - self.assertEqual(display_value, expected) - - display_value = display_for_field(None, models.DecimalField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) - - display_value = display_for_field(None, models.FloatField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) - - def test_label_for_field(self): - """ - Tests for label_for_field - """ - self.assertEquals( - label_for_field("title", Article), - "title" - ) - self.assertEquals( - label_for_field("title2", Article), - "another name" - ) - self.assertEquals( - label_for_field("title2", Article, return_attr=True), - ("another name", None) - ) - - self.assertEquals( - label_for_field("__unicode__", Article), - "article" - ) - self.assertEquals( - label_for_field("__str__", Article), - "article" - ) - - self.assertRaises( - AttributeError, - lambda: label_for_field("unknown", Article) - ) - - def test_callable(obj): - return "nothing" - self.assertEquals( - label_for_field(test_callable, Article), - "Test callable" - ) - self.assertEquals( - label_for_field(test_callable, Article, return_attr=True), - ("Test callable", test_callable) - ) - - self.assertEquals( - label_for_field("test_from_model", Article), - "Test from model" - ) - self.assertEquals( - label_for_field("test_from_model", Article, return_attr=True), - ("Test from model", Article.test_from_model) - ) - self.assertEquals( - label_for_field("test_from_model_with_override", Article), - "not What you Expect" - ) - - self.assertEquals( - label_for_field(lambda x: "nothing", Article), - "--" - ) - - class MockModelAdmin(object): - def test_from_model(self, obj): - return "nothing" - test_from_model.short_description = "not Really the Model" - - self.assertEquals( - label_for_field("test_from_model", Article, model_admin=MockModelAdmin), - "not Really the Model" - ) - self.assertEquals( - label_for_field("test_from_model", Article, - model_admin = MockModelAdmin, - return_attr = True - ), - ("not Really the Model", MockModelAdmin.test_from_model) - ) - - def test_related_name(self): - """ - Regression test for #13963 - """ - self.assertEquals( - label_for_field('location', Event, return_attr=True), - ('location', None), - ) - self.assertEquals( - label_for_field('event', Location, return_attr=True), - ('awesome event', None), - ) - self.assertEquals( - label_for_field('guest', Event, return_attr=True), - ('awesome guest', None), - ) diff --git a/parts/django/tests/regressiontests/admin_validation/__init__.py b/parts/django/tests/regressiontests/admin_validation/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_validation/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_validation/models.py b/parts/django/tests/regressiontests/admin_validation/models.py deleted file mode 100644 index 24387cc..0000000 --- a/parts/django/tests/regressiontests/admin_validation/models.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -Tests of ModelAdmin validation logic. -""" - -from django.db import models - - -class Album(models.Model): - title = models.CharField(max_length=150) - - -class Song(models.Model): - title = models.CharField(max_length=150) - album = models.ForeignKey(Album) - original_release = models.DateField(editable=False) - - class Meta: - ordering = ('title',) - - def __unicode__(self): - return self.title - - def readonly_method_on_model(self): - # does nothing - pass - - -class TwoAlbumFKAndAnE(models.Model): - album1 = models.ForeignKey(Album, related_name="album1_set") - album2 = models.ForeignKey(Album, related_name="album2_set") - e = models.CharField(max_length=1) - - -class Author(models.Model): - name = models.CharField(max_length=100) - - -class Book(models.Model): - name = models.CharField(max_length=100) - subtitle = models.CharField(max_length=100) - price = models.FloatField() - authors = models.ManyToManyField(Author, through='AuthorsBooks') - - -class AuthorsBooks(models.Model): - author = models.ForeignKey(Author) - book = models.ForeignKey(Book) diff --git a/parts/django/tests/regressiontests/admin_validation/tests.py b/parts/django/tests/regressiontests/admin_validation/tests.py deleted file mode 100644 index 1872ca5..0000000 --- a/parts/django/tests/regressiontests/admin_validation/tests.py +++ /dev/null @@ -1,247 +0,0 @@ -from django.contrib import admin -from django import forms -from django.contrib.admin.validation import validate, validate_inline, \ - ImproperlyConfigured -from django.test import TestCase - -from models import Song, Book, Album, TwoAlbumFKAndAnE - -class SongForm(forms.ModelForm): - pass - -class ValidFields(admin.ModelAdmin): - form = SongForm - fields = ['title'] - -class InvalidFields(admin.ModelAdmin): - form = SongForm - fields = ['spam'] - -class ValidationTestCase(TestCase): - def assertRaisesMessage(self, exc, msg, func, *args, **kwargs): - try: - func(*args, **kwargs) - except Exception, e: - self.assertEqual(msg, str(e)) - self.assertTrue(isinstance(e, exc), "Expected %s, got %s" % (exc, type(e))) - - def test_readonly_and_editable(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = ["original_release"] - fieldsets = [ - (None, { - "fields": ["title", "original_release"], - }), - ] - validate(SongAdmin, Song) - - def test_custom_modelforms_with_fields_fieldsets(self): - """ - # Regression test for #8027: custom ModelForms with fields/fieldsets - """ - validate(ValidFields, Song) - self.assertRaisesMessage(ImproperlyConfigured, - "'InvalidFields.fields' refers to field 'spam' that is missing from the form.", - validate, - InvalidFields, Song) - - def test_exclude_values(self): - """ - Tests for basic validation of 'exclude' option values (#12689) - """ - class ExcludedFields1(admin.ModelAdmin): - exclude = ('foo') - self.assertRaisesMessage(ImproperlyConfigured, - "'ExcludedFields1.exclude' must be a list or tuple.", - validate, - ExcludedFields1, Book) - - def test_exclude_duplicate_values(self): - class ExcludedFields2(admin.ModelAdmin): - exclude = ('name', 'name') - self.assertRaisesMessage(ImproperlyConfigured, - "There are duplicate field(s) in ExcludedFields2.exclude", - validate, - ExcludedFields2, Book) - - def test_exclude_in_inline(self): - class ExcludedFieldsInline(admin.TabularInline): - model = Song - exclude = ('foo') - - class ExcludedFieldsAlbumAdmin(admin.ModelAdmin): - model = Album - inlines = [ExcludedFieldsInline] - - self.assertRaisesMessage(ImproperlyConfigured, - "'ExcludedFieldsInline.exclude' must be a list or tuple.", - validate, - ExcludedFieldsAlbumAdmin, Album) - - def test_exclude_inline_model_admin(self): - """ - # Regression test for #9932 - exclude in InlineModelAdmin - # should not contain the ForeignKey field used in ModelAdmin.model - """ - class SongInline(admin.StackedInline): - model = Song - exclude = ['album'] - - class AlbumAdmin(admin.ModelAdmin): - model = Album - inlines = [SongInline] - - self.assertRaisesMessage(ImproperlyConfigured, - "SongInline cannot exclude the field 'album' - this is the foreign key to the parent model Album.", - validate, - AlbumAdmin, Album) - - def test_fk_exclusion(self): - """ - Regression test for #11709 - when testing for fk excluding (when exclude is - given) make sure fk_name is honored or things blow up when there is more - than one fk to the parent model. - """ - class TwoAlbumFKAndAnEInline(admin.TabularInline): - model = TwoAlbumFKAndAnE - exclude = ("e",) - fk_name = "album1" - validate_inline(TwoAlbumFKAndAnEInline, None, Album) - - def test_inline_self_validation(self): - class TwoAlbumFKAndAnEInline(admin.TabularInline): - model = TwoAlbumFKAndAnE - - self.assertRaisesMessage(Exception, - "<class 'regressiontests.admin_validation.models.TwoAlbumFKAndAnE'> has more than 1 ForeignKey to <class 'regressiontests.admin_validation.models.Album'>", - validate_inline, - TwoAlbumFKAndAnEInline, None, Album) - - def test_inline_with_specified(self): - class TwoAlbumFKAndAnEInline(admin.TabularInline): - model = TwoAlbumFKAndAnE - fk_name = "album1" - validate_inline(TwoAlbumFKAndAnEInline, None, Album) - - def test_readonly(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = ("title",) - - validate(SongAdmin, Song) - - def test_readonly_on_method(self): - def my_function(obj): - pass - - class SongAdmin(admin.ModelAdmin): - readonly_fields = (my_function,) - - validate(SongAdmin, Song) - - def test_readonly_on_modeladmin(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = ("readonly_method_on_modeladmin",) - - def readonly_method_on_modeladmin(self, obj): - pass - - validate(SongAdmin, Song) - - def test_readonly_method_on_model(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = ("readonly_method_on_model",) - - validate(SongAdmin, Song) - - def test_nonexistant_field(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = ("title", "nonexistant") - - self.assertRaisesMessage(ImproperlyConfigured, - "SongAdmin.readonly_fields[1], 'nonexistant' is not a callable or an attribute of 'SongAdmin' or found in the model 'Song'.", - validate, - SongAdmin, Song) - - def test_extra(self): - class SongAdmin(admin.ModelAdmin): - def awesome_song(self, instance): - if instance.title == "Born to Run": - return "Best Ever!" - return "Status unknown." - validate(SongAdmin, Song) - - def test_readonly_lambda(self): - class SongAdmin(admin.ModelAdmin): - readonly_fields = (lambda obj: "test",) - - validate(SongAdmin, Song) - - def test_graceful_m2m_fail(self): - """ - Regression test for #12203/#12237 - Fail more gracefully when a M2M field that - specifies the 'through' option is included in the 'fields' or the 'fieldsets' - ModelAdmin options. - """ - - class BookAdmin(admin.ModelAdmin): - fields = ['authors'] - - self.assertRaisesMessage(ImproperlyConfigured, - "'BookAdmin.fields' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.", - validate, - BookAdmin, Book) - - def test_cannon_include_through(self): - class FieldsetBookAdmin(admin.ModelAdmin): - fieldsets = ( - ('Header 1', {'fields': ('name',)}), - ('Header 2', {'fields': ('authors',)}), - ) - self.assertRaisesMessage(ImproperlyConfigured, - "'FieldsetBookAdmin.fieldsets[1][1]['fields']' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.", - validate, - FieldsetBookAdmin, Book) - - def test_nested_fieldsets(self): - class NestedFieldsetAdmin(admin.ModelAdmin): - fieldsets = ( - ('Main', {'fields': ('price', ('name', 'subtitle'))}), - ) - validate(NestedFieldsetAdmin, Book) - - def test_explicit_through_override(self): - """ - Regression test for #12209 -- If the explicitly provided through model - is specified as a string, the admin should still be able use - Model.m2m_field.through - """ - - class AuthorsInline(admin.TabularInline): - model = Book.authors.through - - class BookAdmin(admin.ModelAdmin): - inlines = [AuthorsInline] - - # If the through model is still a string (and hasn't been resolved to a model) - # the validation will fail. - validate(BookAdmin, Book) - - def test_non_model_fields(self): - """ - Regression for ensuring ModelAdmin.fields can contain non-model fields - that broke with r11737 - """ - class SongForm(forms.ModelForm): - extra_data = forms.CharField() - class Meta: - model = Song - - class FieldsOnFormOnlyAdmin(admin.ModelAdmin): - form = SongForm - fields = ['title', 'extra_data'] - - validate(FieldsOnFormOnlyAdmin, Song) - - - - diff --git a/parts/django/tests/regressiontests/admin_views/__init__.py b/parts/django/tests/regressiontests/admin_views/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_views/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_views/customadmin.py b/parts/django/tests/regressiontests/admin_views/customadmin.py deleted file mode 100644 index 34e39ef..0000000 --- a/parts/django/tests/regressiontests/admin_views/customadmin.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -A second, custom AdminSite -- see tests.CustomAdminSiteTests. -""" -from django.conf.urls.defaults import patterns -from django.contrib import admin -from django.http import HttpResponse - -import models - -class Admin2(admin.AdminSite): - login_template = 'custom_admin/login.html' - logout_template = 'custom_admin/logout.html' - index_template = 'custom_admin/index.html' - password_change_template = 'custom_admin/password_change_form.html' - password_change_done_template = 'custom_admin/password_change_done.html' - - # A custom index view. - def index(self, request, extra_context=None): - return super(Admin2, self).index(request, {'foo': '*bar*'}) - - def get_urls(self): - return patterns('', - (r'^my_view/$', self.admin_view(self.my_view)), - ) + super(Admin2, self).get_urls() - - def my_view(self, request): - return HttpResponse("Django is a magical pony!") - -site = Admin2(name="admin2") - -site.register(models.Article, models.ArticleAdmin) -site.register(models.Section, inlines=[models.ArticleInline]) -site.register(models.Thing, models.ThingAdmin) -site.register(models.Fabric, models.FabricAdmin) diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-actions.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-actions.xml deleted file mode 100644 index 316e750..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-actions.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.subscriber"> - <field type="CharField" name="name">John Doe</field> - <field type="CharField" name="email">john@example.org</field> - </object> - <object pk="2" model="admin_views.subscriber"> - <field type="CharField" name="name">Max Mustermann</field> - <field type="CharField" name="email">max@example.org</field> - </object> - <object pk="1" model="admin_views.externalsubscriber"> - <field type="CharField" name="name">John Doe</field> - <field type="CharField" name="email">john@example.org</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml deleted file mode 100644 index e121356..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.color"> - <field type="CharField" name="value">Red</field> - <field type="BooleanField" name="warm">1</field> - </object> - <object pk="2" model="admin_views.color"> - <field type="CharField" name="value">Orange</field> - <field type="BooleanField" name="warm">1</field> - </object> - <object pk="3" model="admin_views.color"> - <field type="CharField" name="value">Blue</field> - <field type="BooleanField" name="warm">0</field> - </object> - <object pk="4" model="admin_views.color"> - <field type="CharField" name="value">Green</field> - <field type="BooleanField" name="warm">0</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-fabrics.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-fabrics.xml deleted file mode 100644 index 485bb27..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-fabrics.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.fabric"> - <field type="CharField" name="surface">x</field> - </object> - <object pk="2" model="admin_views.fabric"> - <field type="CharField" name="surface">y</field> - </object> - <object pk="3" model="admin_views.fabric"> - <field type="CharField" name="surface">plain</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-person.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-person.xml deleted file mode 100644 index ff00fd2..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-person.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.person"> - <field type="CharField" name="name">John Mauchly</field> - <field type="IntegerField" name="gender">1</field> - <field type="BooleanField" name="alive">True</field> - </object> - <object pk="2" model="admin_views.person"> - <field type="CharField" name="name">Grace Hopper</field> - <field type="IntegerField" name="gender">1</field> - <field type="BooleanField" name="alive">False</field> - </object> - <object pk="3" model="admin_views.person"> - <field type="CharField" name="name">Guido van Rossum</field> - <field type="IntegerField" name="gender">1</field> - <field type="BooleanField" name="alive">True</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-unicode.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-unicode.xml deleted file mode 100644 index 5652aa1..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-unicode.xml +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="1" model="admin_views.book"> - <field type="CharField" name="name">Lærdommer</field> - </object> - <object pk="1" model="admin_views.promo"> - <field type="CharField" name="name"><Promo for Lærdommer></field> - <field to="admin_views.book" name="book" rel="ManyToOneRel">1</field> - </object> - <object pk="1" model="admin_views.chapter"> - <field type="CharField" name="title">Norske bostaver æøå skaper problemer</field> - <field type="TextField" name="content"><p>Svært frustrerende med UnicodeDecodeErro</p></field> - <field to="admin_views.book" name="book" rel="ManyToOneRel">1</field> - </object> - <object pk="2" model="admin_views.chapter"> - <field type="CharField" name="title">Kjærlighet</field> - <field type="TextField" name="content"><p>La kjærligheten til de lidende seire.</p></field> - <field to="admin_views.book" name="book" rel="ManyToOneRel">1</field> - </object> - <object pk="3" model="admin_views.chapter"> - <field type="CharField" name="title">Kjærlighet</field> - <field type="TextField" name="content"><p>Noe innhold</p></field> - <field to="admin_views.book" name="book" rel="ManyToOneRel">1</field> - </object> - <object pk="1" model="admin_views.chapterxtra1"> - <field type="CharField" name="xtra"><Xtra(1) Norske bostaver æøå skaper problemer></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">1</field> - </object> - <object pk="2" model="admin_views.chapterxtra1"> - <field type="CharField" name="xtra"><Xtra(1) Kjærlighet></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">2</field> - </object> - <object pk="3" model="admin_views.chapterxtra1"> - <field type="CharField" name="xtra"><Xtra(1) Kjærlighet></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">3</field> - </object> - <object pk="1" model="admin_views.chapterxtra2"> - <field type="CharField" name="xtra"><Xtra(2) Norske bostaver æøå skaper problemer></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">1</field> - </object> - <object pk="2" model="admin_views.chapterxtra2"> - <field type="CharField" name="xtra"><Xtra(2) Kjærlighet></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">2</field> - </object> - <object pk="3" model="admin_views.chapterxtra2"> - <field type="CharField" name="xtra"><Xtra(2) Kjærlighet></field> - <field to="admin_views.chapter" name="chap" rel="OneToOneRel">3</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-users.xml b/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-users.xml deleted file mode 100644 index f1ff296..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/admin-views-users.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="101" model="auth.user"> - <field type="CharField" name="username">adduser</field> - <field type="CharField" name="first_name">Add</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">auser@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">False</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="102" model="auth.user"> - <field type="CharField" name="username">changeuser</field> - <field type="CharField" name="first_name">Change</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">cuser@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">False</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="103" model="auth.user"> - <field type="CharField" name="username">deleteuser</field> - <field type="CharField" name="first_name">Delete</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">duser@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">False</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="104" model="auth.user"> - <field type="CharField" name="username">joepublic</field> - <field type="CharField" name="first_name">Joe</field> - <field type="CharField" name="last_name">Public</field> - <field type="CharField" name="email">joepublic@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">False</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">False</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="1" model="admin_views.section"> - <field type="CharField" name="name">Test section</field> - </object> - <object pk="1" model="admin_views.article"> - <field type="TextField" name="content"><p>Middle content</p></field> - <field type="DateTimeField" name="date">2008-03-18 11:54:58</field> - <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> - </object> - <object pk="2" model="admin_views.article"> - <field type="TextField" name="content"><p>Oldest content</p></field> - <field type="DateTimeField" name="date">2000-03-18 11:54:58</field> - <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> - </object> - <object pk="3" model="admin_views.article"> - <field type="TextField" name="content"><p>Newest content</p></field> - <field type="DateTimeField" name="date">2009-03-18 11:54:58</field> - <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> - </object> - - -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/deleted-objects.xml b/parts/django/tests/regressiontests/admin_views/fixtures/deleted-objects.xml deleted file mode 100644 index 92e43db..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/deleted-objects.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.villain"> - <field type="CharField" name="name">Adam</field> - </object> - <object pk="2" model="admin_views.villain"> - <field type="CharField" name="name">Sue</field> - </object> - <object pk="3" model="admin_views.villain"> - <field type="CharField" name="name">Bob</field> - </object> - <object pk="3" model="admin_views.supervillain"> - </object> - <object pk="1" model="admin_views.plot"> - <field type="CharField" name="name">World Domination</field> - <field type="ForeignKey" name="team_leader">1</field> - <field type="ForeignKey" name="contact">2</field> - </object> - <object pk="2" model="admin_views.plot"> - <field type="CharField" name="name">World Peace</field> - <field type="ForeignKey" name="team_leader">2</field> - <field type="ForeignKey" name="contact">2</field> - </object> - <object pk="1" model="admin_views.plotdetails"> - <field type="CharField" name="details">almost finished</field> - <field type="ForeignKey" name="plot">1</field> - </object> - <object pk="1" model="admin_views.secrethideout"> - <field type="CharField" name="location">underground bunker</field> - <field type="ForeignKey" name="villain">1</field> - </object> - <object pk="2" model="admin_views.secrethideout"> - <field type="CharField" name="location">floating castle</field> - <field type="ForeignKey" name="villain">3</field> - </object> - <object pk="1" model="admin_views.supersecrethideout"> - <field type="CharField" name="location">super floating castle!</field> - <field type="ForeignKey" name="supervillain">3</field> - </object> - <object pk="1" model="admin_views.cyclicone"> - <field type="CharField" name="name">I am recursive</field> - <field type="ForeignKey" name="two">1</field> - </object> - <object pk="1" model="admin_views.cyclictwo"> - <field type="CharField" name="name">I am recursive too</field> - <field type="ForeignKey" name="one">1</field> - </object> - <object pk="3" model="admin_views.plot"> - <field type="CharField" name="name">Corn Conspiracy</field> - <field type="ForeignKey" name="team_leader">1</field> - <field type="ForeignKey" name="contact">1</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json b/parts/django/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json deleted file mode 100644 index 5cadf4c..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json +++ /dev/null @@ -1,107 +0,0 @@ -[ - { - "pk": 1, - "model": "admin_views.title", - "fields": - { - } - }, - - { - "pk": 2, - "model": "admin_views.title", - "fields": - { - } - }, - - { - "pk": 3, - "model": "admin_views.title", - "fields": - { - } - }, - - { - "pk": 4, - "model": "admin_views.title", - "fields": - { - } - }, - - { - "pk": 1, - "model": "admin_views.titletranslation", - "fields": - { - "text": "Bar", - "title": 1 - } - }, - - { - "pk": 2, - "model": "admin_views.titletranslation", - "fields": - { - "text": "Foo", - "title": 2 - } - }, - - { - "pk": 3, - "model": "admin_views.titletranslation", - "fields": - { - "text": "Few", - "title": 3 - } - }, - - { - "pk": 4, - "model": "admin_views.titletranslation", - "fields": - { - "text": "Bas", - "title": 4 - } - }, - - { - "pk": 1, - "model": "admin_views.recommender", - "fields": - { - } - }, - - { - "pk": 4, - "model": "admin_views.recommender", - "fields": - { - } - }, - - { - "pk": 2, - "model": "admin_views.recommendation", - "fields": - { - "recommender": 1 - } - }, - - { - "pk": 3, - "model": "admin_views.recommendation", - "fields": - { - "recommender": 4 - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_views/fixtures/string-primary-key.xml b/parts/django/tests/regressiontests/admin_views/fixtures/string-primary-key.xml deleted file mode 100644 index 8e1dbf0..0000000 --- a/parts/django/tests/regressiontests/admin_views/fixtures/string-primary-key.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="admin_views.modelwithstringprimarykey"> - <field type="CharField" name="id"><![CDATA[abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 -_.!~*'() ;/?:@&=+$, <>#%" {}|\^[]`]]></field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_views/models.py b/parts/django/tests/regressiontests/admin_views/models.py deleted file mode 100644 index 191b4f3..0000000 --- a/parts/django/tests/regressiontests/admin_views/models.py +++ /dev/null @@ -1,636 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -import tempfile -import os - -from django.contrib import admin -from django.core.files.storage import FileSystemStorage -from django.contrib.admin.views.main import ChangeList -from django.core.mail import EmailMessage -from django.db import models -from django import forms -from django.forms.models import BaseModelFormSet -from django.contrib.auth.models import User -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType - -class Section(models.Model): - """ - A simple section that links to articles, to test linking to related items - in admin views. - """ - name = models.CharField(max_length=100) - -class Article(models.Model): - """ - A simple article to test admin views. Test backwards compatibility. - """ - title = models.CharField(max_length=100) - content = models.TextField() - date = models.DateTimeField() - section = models.ForeignKey(Section, null=True, blank=True) - - def __unicode__(self): - return self.title - - def model_year(self): - return self.date.year - model_year.admin_order_field = 'date' - model_year.short_description = '' - -class Book(models.Model): - """ - A simple book that has chapters. - """ - name = models.CharField(max_length=100, verbose_name=u'¿Name?') - - def __unicode__(self): - return self.name - -class Promo(models.Model): - name = models.CharField(max_length=100, verbose_name=u'¿Name?') - book = models.ForeignKey(Book) - - def __unicode__(self): - return self.name - -class Chapter(models.Model): - title = models.CharField(max_length=100, verbose_name=u'¿Title?') - content = models.TextField() - book = models.ForeignKey(Book) - - def __unicode__(self): - return self.title - - class Meta: - # Use a utf-8 bytestring to ensure it works (see #11710) - verbose_name = '¿Chapter?' - -class ChapterXtra1(models.Model): - chap = models.OneToOneField(Chapter, verbose_name=u'¿Chap?') - xtra = models.CharField(max_length=100, verbose_name=u'¿Xtra?') - - def __unicode__(self): - return u'¿Xtra1: %s' % self.xtra - -class ChapterXtra2(models.Model): - chap = models.OneToOneField(Chapter, verbose_name=u'¿Chap?') - xtra = models.CharField(max_length=100, verbose_name=u'¿Xtra?') - - def __unicode__(self): - return u'¿Xtra2: %s' % self.xtra - -def callable_year(dt_value): - return dt_value.year -callable_year.admin_order_field = 'date' - -class ArticleInline(admin.TabularInline): - model = Article - -class ChapterInline(admin.TabularInline): - model = Chapter - -class ArticleAdmin(admin.ModelAdmin): - list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year') - list_filter = ('date', 'section') - - def changelist_view(self, request): - "Test that extra_context works" - return super(ArticleAdmin, self).changelist_view( - request, extra_context={ - 'extra_var': 'Hello!' - } - ) - - def modeladmin_year(self, obj): - return obj.date.year - modeladmin_year.admin_order_field = 'date' - modeladmin_year.short_description = None - -class CustomArticle(models.Model): - content = models.TextField() - date = models.DateTimeField() - -class CustomArticleAdmin(admin.ModelAdmin): - """ - Tests various hooks for using custom templates and contexts. - """ - change_list_template = 'custom_admin/change_list.html' - change_form_template = 'custom_admin/change_form.html' - add_form_template = 'custom_admin/add_form.html' - object_history_template = 'custom_admin/object_history.html' - delete_confirmation_template = 'custom_admin/delete_confirmation.html' - delete_selected_confirmation_template = 'custom_admin/delete_selected_confirmation.html' - - def changelist_view(self, request): - "Test that extra_context works" - return super(CustomArticleAdmin, self).changelist_view( - request, extra_context={ - 'extra_var': 'Hello!' - } - ) - -class ModelWithStringPrimaryKey(models.Model): - id = models.CharField(max_length=255, primary_key=True) - - def __unicode__(self): - return self.id - -class Color(models.Model): - value = models.CharField(max_length=10) - warm = models.BooleanField() - def __unicode__(self): - return self.value - -class Thing(models.Model): - title = models.CharField(max_length=20) - color = models.ForeignKey(Color, limit_choices_to={'warm': True}) - def __unicode__(self): - return self.title - -class ThingAdmin(admin.ModelAdmin): - list_filter = ('color',) - -class Fabric(models.Model): - NG_CHOICES = ( - ('Textured', ( - ('x', 'Horizontal'), - ('y', 'Vertical'), - ) - ), - ('plain', 'Smooth'), - ) - surface = models.CharField(max_length=20, choices=NG_CHOICES) - -class FabricAdmin(admin.ModelAdmin): - list_display = ('surface',) - list_filter = ('surface',) - -class Person(models.Model): - GENDER_CHOICES = ( - (1, "Male"), - (2, "Female"), - ) - name = models.CharField(max_length=100) - gender = models.IntegerField(choices=GENDER_CHOICES) - alive = models.BooleanField() - - def __unicode__(self): - return self.name - - class Meta: - ordering = ["id"] - -class BasePersonModelFormSet(BaseModelFormSet): - def clean(self): - for person_dict in self.cleaned_data: - person = person_dict.get('id') - alive = person_dict.get('alive') - if person and alive and person.name == "Grace Hopper": - raise forms.ValidationError, "Grace is not a Zombie" - -class PersonAdmin(admin.ModelAdmin): - list_display = ('name', 'gender', 'alive') - list_editable = ('gender', 'alive') - list_filter = ('gender',) - search_fields = (u'name',) - ordering = ["id"] - save_as = True - - def get_changelist_formset(self, request, **kwargs): - return super(PersonAdmin, self).get_changelist_formset(request, - formset=BasePersonModelFormSet, **kwargs) - - -class Persona(models.Model): - """ - A simple persona associated with accounts, to test inlining of related - accounts which inherit from a common accounts class. - """ - name = models.CharField(blank=False, max_length=80) - def __unicode__(self): - return self.name - -class Account(models.Model): - """ - A simple, generic account encapsulating the information shared by all - types of accounts. - """ - username = models.CharField(blank=False, max_length=80) - persona = models.ForeignKey(Persona, related_name="accounts") - servicename = u'generic service' - - def __unicode__(self): - return "%s: %s" % (self.servicename, self.username) - -class FooAccount(Account): - """A service-specific account of type Foo.""" - servicename = u'foo' - -class BarAccount(Account): - """A service-specific account of type Bar.""" - servicename = u'bar' - -class FooAccountAdmin(admin.StackedInline): - model = FooAccount - extra = 1 - -class BarAccountAdmin(admin.StackedInline): - model = BarAccount - extra = 1 - -class PersonaAdmin(admin.ModelAdmin): - inlines = ( - FooAccountAdmin, - BarAccountAdmin - ) - -class Subscriber(models.Model): - name = models.CharField(blank=False, max_length=80) - email = models.EmailField(blank=False, max_length=175) - - def __unicode__(self): - return "%s (%s)" % (self.name, self.email) - -class SubscriberAdmin(admin.ModelAdmin): - actions = ['mail_admin'] - - def mail_admin(self, request, selected): - EmailMessage( - 'Greetings from a ModelAdmin action', - 'This is the test email from a admin action', - 'from@example.com', - ['to@example.com'] - ).send() - -class ExternalSubscriber(Subscriber): - pass - -class OldSubscriber(Subscriber): - pass - -def external_mail(modeladmin, request, selected): - EmailMessage( - 'Greetings from a function action', - 'This is the test email from a function action', - 'from@example.com', - ['to@example.com'] - ).send() - -def redirect_to(modeladmin, request, selected): - from django.http import HttpResponseRedirect - return HttpResponseRedirect('/some-where-else/') - -class ExternalSubscriberAdmin(admin.ModelAdmin): - actions = [external_mail, redirect_to] - -class Media(models.Model): - name = models.CharField(max_length=60) - -class Podcast(Media): - release_date = models.DateField() - -class PodcastAdmin(admin.ModelAdmin): - list_display = ('name', 'release_date') - list_editable = ('release_date',) - - ordering = ('name',) - -class Vodcast(Media): - media = models.OneToOneField(Media, primary_key=True, parent_link=True) - released = models.BooleanField(default=False) - -class VodcastAdmin(admin.ModelAdmin): - list_display = ('name', 'released') - list_editable = ('released',) - - ordering = ('name',) - -class Parent(models.Model): - name = models.CharField(max_length=128) - -class Child(models.Model): - parent = models.ForeignKey(Parent, editable=False) - name = models.CharField(max_length=30, blank=True) - -class ChildInline(admin.StackedInline): - model = Child - -class ParentAdmin(admin.ModelAdmin): - model = Parent - inlines = [ChildInline] - -class EmptyModel(models.Model): - def __unicode__(self): - return "Primary key = %s" % self.id - -class EmptyModelAdmin(admin.ModelAdmin): - def queryset(self, request): - return super(EmptyModelAdmin, self).queryset(request).filter(pk__gt=1) - -class OldSubscriberAdmin(admin.ModelAdmin): - actions = None - -temp_storage = FileSystemStorage(tempfile.mkdtemp()) -UPLOAD_TO = os.path.join(temp_storage.location, 'test_upload') - -class Gallery(models.Model): - name = models.CharField(max_length=100) - -class Picture(models.Model): - name = models.CharField(max_length=100) - image = models.FileField(storage=temp_storage, upload_to='test_upload') - gallery = models.ForeignKey(Gallery, related_name="pictures") - -class PictureInline(admin.TabularInline): - model = Picture - extra = 1 - -class GalleryAdmin(admin.ModelAdmin): - inlines = [PictureInline] - -class PictureAdmin(admin.ModelAdmin): - pass - -class Language(models.Model): - iso = models.CharField(max_length=5, primary_key=True) - name = models.CharField(max_length=50) - english_name = models.CharField(max_length=50) - shortlist = models.BooleanField(default=False) - - class Meta: - ordering = ('iso',) - -class LanguageAdmin(admin.ModelAdmin): - list_display = ['iso', 'shortlist', 'english_name', 'name'] - list_editable = ['shortlist'] - -# a base class for Recommender and Recommendation -class Title(models.Model): - pass - -class TitleTranslation(models.Model): - title = models.ForeignKey(Title) - text = models.CharField(max_length=100) - -class Recommender(Title): - pass - -class Recommendation(Title): - recommender = models.ForeignKey(Recommender) - -class RecommendationAdmin(admin.ModelAdmin): - search_fields = ('titletranslation__text', 'recommender__titletranslation__text',) - -class Collector(models.Model): - name = models.CharField(max_length=100) - -class Widget(models.Model): - owner = models.ForeignKey(Collector) - name = models.CharField(max_length=100) - -class DooHickey(models.Model): - code = models.CharField(max_length=10, primary_key=True) - owner = models.ForeignKey(Collector) - name = models.CharField(max_length=100) - -class Grommet(models.Model): - code = models.AutoField(primary_key=True) - owner = models.ForeignKey(Collector) - name = models.CharField(max_length=100) - -class Whatsit(models.Model): - index = models.IntegerField(primary_key=True) - owner = models.ForeignKey(Collector) - name = models.CharField(max_length=100) - -class Doodad(models.Model): - name = models.CharField(max_length=100) - -class FancyDoodad(Doodad): - owner = models.ForeignKey(Collector) - expensive = models.BooleanField(default=True) - -class WidgetInline(admin.StackedInline): - model = Widget - -class DooHickeyInline(admin.StackedInline): - model = DooHickey - -class GrommetInline(admin.StackedInline): - model = Grommet - -class WhatsitInline(admin.StackedInline): - model = Whatsit - -class FancyDoodadInline(admin.StackedInline): - model = FancyDoodad - -class Category(models.Model): - collector = models.ForeignKey(Collector) - order = models.PositiveIntegerField() - - class Meta: - ordering = ('order',) - - def __unicode__(self): - return u'%s:o%s' % (self.id, self.order) - -class CategoryAdmin(admin.ModelAdmin): - list_display = ('id', 'collector', 'order') - list_editable = ('order',) - -class CategoryInline(admin.StackedInline): - model = Category - -class CollectorAdmin(admin.ModelAdmin): - inlines = [ - WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, - FancyDoodadInline, CategoryInline - ] - -class Link(models.Model): - posted = models.DateField( - default=lambda: datetime.date.today() - datetime.timedelta(days=7) - ) - url = models.URLField() - post = models.ForeignKey("Post") - - -class LinkInline(admin.TabularInline): - model = Link - extra = 1 - - readonly_fields = ("posted",) - - -class Post(models.Model): - title = models.CharField(max_length=100) - content = models.TextField() - posted = models.DateField(default=datetime.date.today) - public = models.NullBooleanField() - - def awesomeness_level(self): - return "Very awesome." - -class PostAdmin(admin.ModelAdmin): - list_display = ['title', 'public'] - readonly_fields = ('posted', 'awesomeness_level', 'coolness', 'value', lambda obj: "foo") - - inlines = [ - LinkInline - ] - - def coolness(self, instance): - if instance.pk: - return "%d amount of cool." % instance.pk - else: - return "Unkown coolness." - - def value(self, instance): - return 1000 - value.short_description = 'Value in $US' - -class Gadget(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class CustomChangeList(ChangeList): - def get_query_set(self): - return self.root_query_set.filter(pk=9999) # Does not exist - -class GadgetAdmin(admin.ModelAdmin): - def get_changelist(self, request, **kwargs): - return CustomChangeList - -class Villain(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class SuperVillain(Villain): - pass - -class FunkyTag(models.Model): - "Because we all know there's only one real use case for GFKs." - name = models.CharField(max_length=25) - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') - - def __unicode__(self): - return self.name - -class Plot(models.Model): - name = models.CharField(max_length=100) - team_leader = models.ForeignKey(Villain, related_name='lead_plots') - contact = models.ForeignKey(Villain, related_name='contact_plots') - tags = generic.GenericRelation(FunkyTag) - - def __unicode__(self): - return self.name - -class PlotDetails(models.Model): - details = models.CharField(max_length=100) - plot = models.OneToOneField(Plot) - - def __unicode__(self): - return self.details - -class SecretHideout(models.Model): - """ Secret! Not registered with the admin! """ - location = models.CharField(max_length=100) - villain = models.ForeignKey(Villain) - - def __unicode__(self): - return self.location - -class SuperSecretHideout(models.Model): - """ Secret! Not registered with the admin! """ - location = models.CharField(max_length=100) - supervillain = models.ForeignKey(SuperVillain) - - def __unicode__(self): - return self.location - -class CyclicOne(models.Model): - name = models.CharField(max_length=25) - two = models.ForeignKey('CyclicTwo') - - def __unicode__(self): - return self.name - -class CyclicTwo(models.Model): - name = models.CharField(max_length=25) - one = models.ForeignKey(CyclicOne) - - def __unicode__(self): - return self.name - -class Topping(models.Model): - name = models.CharField(max_length=20) - -class Pizza(models.Model): - name = models.CharField(max_length=20) - toppings = models.ManyToManyField('Topping') - -class PizzaAdmin(admin.ModelAdmin): - readonly_fields = ('toppings',) - -class Album(models.Model): - owner = models.ForeignKey(User) - title = models.CharField(max_length=30) - -class AlbumAdmin(admin.ModelAdmin): - list_filter = ['title'] - -admin.site.register(Article, ArticleAdmin) -admin.site.register(CustomArticle, CustomArticleAdmin) -admin.site.register(Section, save_as=True, inlines=[ArticleInline]) -admin.site.register(ModelWithStringPrimaryKey) -admin.site.register(Color) -admin.site.register(Thing, ThingAdmin) -admin.site.register(Person, PersonAdmin) -admin.site.register(Persona, PersonaAdmin) -admin.site.register(Subscriber, SubscriberAdmin) -admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin) -admin.site.register(OldSubscriber, OldSubscriberAdmin) -admin.site.register(Podcast, PodcastAdmin) -admin.site.register(Vodcast, VodcastAdmin) -admin.site.register(Parent, ParentAdmin) -admin.site.register(EmptyModel, EmptyModelAdmin) -admin.site.register(Fabric, FabricAdmin) -admin.site.register(Gallery, GalleryAdmin) -admin.site.register(Picture, PictureAdmin) -admin.site.register(Language, LanguageAdmin) -admin.site.register(Recommendation, RecommendationAdmin) -admin.site.register(Recommender) -admin.site.register(Collector, CollectorAdmin) -admin.site.register(Category, CategoryAdmin) -admin.site.register(Post, PostAdmin) -admin.site.register(Gadget, GadgetAdmin) -admin.site.register(Villain) -admin.site.register(SuperVillain) -admin.site.register(Plot) -admin.site.register(PlotDetails) -admin.site.register(CyclicOne) -admin.site.register(CyclicTwo) - -# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. -# That way we cover all four cases: -# related ForeignKey object registered in admin -# related ForeignKey object not registered in admin -# related OneToOne object registered in admin -# related OneToOne object not registered in admin -# when deleting Book so as exercise all four troublesome (w.r.t escaping -# and calling force_unicode to avoid problems on Python 2.3) paths through -# contrib.admin.util's get_deleted_objects function. -admin.site.register(Book, inlines=[ChapterInline]) -admin.site.register(Promo) -admin.site.register(ChapterXtra1) -admin.site.register(Pizza, PizzaAdmin) -admin.site.register(Topping) -admin.site.register(Album, AlbumAdmin) diff --git a/parts/django/tests/regressiontests/admin_views/tests.py b/parts/django/tests/regressiontests/admin_views/tests.py deleted file mode 100644 index d3467dd..0000000 --- a/parts/django/tests/regressiontests/admin_views/tests.py +++ /dev/null @@ -1,2287 +0,0 @@ -# coding: utf-8 - -import re -import datetime - -from django.conf import settings -from django.core.exceptions import SuspiciousOperation -from django.core.files import temp as tempfile -# Register auth models with the admin. -from django.contrib.auth import REDIRECT_FIELD_NAME, admin -from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD -from django.contrib.contenttypes.models import ContentType -from django.contrib.admin.models import LogEntry, DELETION -from django.contrib.admin.sites import LOGIN_FORM_KEY -from django.contrib.admin.util import quote -from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME -from django.forms.util import ErrorList -from django.test import TestCase -from django.utils import formats -from django.utils.cache import get_max_age -from django.utils.encoding import iri_to_uri -from django.utils.html import escape -from django.utils.translation import activate, deactivate -import django.template.context - -# local test models -from models import Article, BarAccount, CustomArticle, EmptyModel, \ - FooAccount, Gallery, ModelWithStringPrimaryKey, \ - Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \ - Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \ - Category, Post, Plot, FunkyTag - - -class AdminViewBasicTest(TestCase): - fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml'] - - # Store the bit of the URL where the admin is registered as a class - # variable. That way we can test a second AdminSite just by subclassing - # this test case and changing urlbit. - urlbit = 'admin' - - def setUp(self): - self.old_language_code = settings.LANGUAGE_CODE - self.client.login(username='super', password='secret') - - def tearDown(self): - settings.LANGUAGE_CODE = self.old_language_code - self.client.logout() - - def testTrailingSlashRequired(self): - """ - If you leave off the trailing slash, app should redirect and add it. - """ - request = self.client.get('/test_admin/%s/admin_views/article/add' % self.urlbit) - self.assertRedirects(request, - '/test_admin/%s/admin_views/article/add/' % self.urlbit, status_code=301 - ) - - def testBasicAddGet(self): - """ - A smoke test to ensure GET on the add_view works. - """ - response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit) - self.assertEqual(response.status_code, 200) - - def testAddWithGETArgs(self): - response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit, {'name': 'My Section'}) - self.assertEqual(response.status_code, 200) - self.assertTrue( - 'value="My Section"' in response.content, - "Couldn't find an input with the right value in the response." - ) - - def testBasicEditGet(self): - """ - A smoke test to ensure GET on the change_view works. - """ - response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit) - self.assertEqual(response.status_code, 200) - - def testBasicEditGetStringPK(self): - """ - A smoke test to ensure GET on the change_view works (returns an HTTP - 404 error, see #11191) when passing a string as the PK argument for a - model with an integer PK field. - """ - response = self.client.get('/test_admin/%s/admin_views/section/abc/' % self.urlbit) - self.assertEqual(response.status_code, 404) - - def testBasicAddPost(self): - """ - A smoke test to ensure POST on add_view works. - """ - post_data = { - "name": u"Another Section", - # inline data - "article_set-TOTAL_FORMS": u"3", - "article_set-INITIAL_FORMS": u"0", - "article_set-MAX_NUM_FORMS": u"0", - } - response = self.client.post('/test_admin/%s/admin_views/section/add/' % self.urlbit, post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - # Post data for edit inline - inline_post_data = { - "name": u"Test section", - # inline data - "article_set-TOTAL_FORMS": u"6", - "article_set-INITIAL_FORMS": u"3", - "article_set-MAX_NUM_FORMS": u"0", - "article_set-0-id": u"1", - # there is no title in database, give one here or formset will fail. - "article_set-0-title": u"Norske bostaver æøå skaper problemer", - "article_set-0-content": u"<p>Middle content</p>", - "article_set-0-date_0": u"2008-03-18", - "article_set-0-date_1": u"11:54:58", - "article_set-0-section": u"1", - "article_set-1-id": u"2", - "article_set-1-title": u"Need a title.", - "article_set-1-content": u"<p>Oldest content</p>", - "article_set-1-date_0": u"2000-03-18", - "article_set-1-date_1": u"11:54:58", - "article_set-2-id": u"3", - "article_set-2-title": u"Need a title.", - "article_set-2-content": u"<p>Newest content</p>", - "article_set-2-date_0": u"2009-03-18", - "article_set-2-date_1": u"11:54:58", - "article_set-3-id": u"", - "article_set-3-title": u"", - "article_set-3-content": u"", - "article_set-3-date_0": u"", - "article_set-3-date_1": u"", - "article_set-4-id": u"", - "article_set-4-title": u"", - "article_set-4-content": u"", - "article_set-4-date_0": u"", - "article_set-4-date_1": u"", - "article_set-5-id": u"", - "article_set-5-title": u"", - "article_set-5-content": u"", - "article_set-5-date_0": u"", - "article_set-5-date_1": u"", - } - - def testBasicEditPost(self): - """ - A smoke test to ensure POST on edit_view works. - """ - response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, self.inline_post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - def testEditSaveAs(self): - """ - Test "save as". - """ - post_data = self.inline_post_data.copy() - post_data.update({ - '_saveasnew': u'Save+as+new', - "article_set-1-section": u"1", - "article_set-2-section": u"1", - "article_set-3-section": u"1", - "article_set-4-section": u"1", - "article_set-5-section": u"1", - }) - response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - def testChangeListSortingCallable(self): - """ - Ensure we can sort on a list_display field that is a callable - (column 2 is callable_year in ArticleAdmin) - """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'asc', 'o': 2}) - self.assertEqual(response.status_code, 200) - self.assertTrue( - response.content.index('Oldest content') < response.content.index('Middle content') and - response.content.index('Middle content') < response.content.index('Newest content'), - "Results of sorting on callable are out of order." - ) - - def testChangeListSortingModel(self): - """ - Ensure we can sort on a list_display field that is a Model method - (colunn 3 is 'model_year' in ArticleAdmin) - """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'dsc', 'o': 3}) - self.assertEqual(response.status_code, 200) - self.assertTrue( - response.content.index('Newest content') < response.content.index('Middle content') and - response.content.index('Middle content') < response.content.index('Oldest content'), - "Results of sorting on Model method are out of order." - ) - - def testChangeListSortingModelAdmin(self): - """ - Ensure we can sort on a list_display field that is a ModelAdmin method - (colunn 4 is 'modeladmin_year' in ArticleAdmin) - """ - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'asc', 'o': 4}) - self.assertEqual(response.status_code, 200) - self.assertTrue( - response.content.index('Oldest content') < response.content.index('Middle content') and - response.content.index('Middle content') < response.content.index('Newest content'), - "Results of sorting on ModelAdmin method are out of order." - ) - - def testLimitedFilter(self): - """Ensure admin changelist filters do not contain objects excluded via limit_choices_to.""" - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit) - self.assertEqual(response.status_code, 200) - self.assertTrue( - '<div id="changelist-filter">' in response.content, - "Expected filter not found in changelist view." - ) - self.assertFalse( - '<a href="?color__id__exact=3">Blue</a>' in response.content, - "Changelist filter not correctly limited by limit_choices_to." - ) - - def testIncorrectLookupParameters(self): - """Ensure incorrect lookup parameters are handled gracefully.""" - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'notarealfield': '5'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) - response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) - self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) - - def testIsNullLookups(self): - """Ensure is_null is handled correctly.""" - Article.objects.create(title="I Could Go Anywhere", content="Versatile", date=datetime.datetime.now()) - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) - self.assertTrue('4 articles' in response.content, '"4 articles" missing from response') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': 'false'}) - self.assertTrue('3 articles' in response.content, '"3 articles" missing from response') - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'section__isnull': 'true'}) - self.assertTrue('1 article' in response.content, '"1 article" missing from response') - - def testLogoutAndPasswordChangeURLs(self): - response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) - self.assertFalse('<a href="/test_admin/%s/logout/">' % self.urlbit not in response.content) - self.assertFalse('<a href="/test_admin/%s/password_change/">' % self.urlbit not in response.content) - - def testNamedGroupFieldChoicesChangeList(self): - """ - Ensures the admin changelist shows correct values in the relevant column - for rows corresponding to instances of a model in which a named group - has been used in the choices option of a field. - """ - response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit) - self.assertEqual(response.status_code, 200) - self.assertTrue( - '<a href="1/">Horizontal</a>' in response.content and - '<a href="2/">Vertical</a>' in response.content, - "Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group." - ) - - def testNamedGroupFieldChoicesFilter(self): - """ - Ensures the filter UI shows correctly when at least one named group has - been used in the choices option of a model field. - """ - response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit) - self.assertEqual(response.status_code, 200) - self.assertTrue( - '<div id="changelist-filter">' in response.content, - "Expected filter not found in changelist view." - ) - self.assertTrue( - '<a href="?surface__exact=x">Horizontal</a>' in response.content and - '<a href="?surface__exact=y">Vertical</a>' in response.content, - "Changelist filter isn't showing options contained inside a model field 'choices' option named group." - ) - - def testChangeListNullBooleanDisplay(self): - Post.objects.create(public=None) - # This hard-codes the URl because it'll fail if it runs - # against the 'admin2' custom admin (which doesn't have the - # Post model). - response = self.client.get("/test_admin/admin/admin_views/post/") - self.assertTrue('icon-unknown.gif' in response.content) - - def testI18NLanguageNonEnglishDefault(self): - """ - Check if the Javascript i18n view returns an empty language catalog - if the default language is non-English but the selected language - is English. See #13388 and #3594 for more details. - """ - settings.LANGUAGE_CODE = 'fr' - activate('en-us') - response = self.client.get('/test_admin/admin/jsi18n/') - self.assertNotContains(response, 'Choisir une heure') - deactivate() - - def testI18NLanguageNonEnglishFallback(self): - """ - Makes sure that the fallback language is still working properly - in cases where the selected language cannot be found. - """ - settings.LANGUAGE_CODE = 'fr' - activate('none') - response = self.client.get('/test_admin/admin/jsi18n/') - self.assertContains(response, 'Choisir une heure') - deactivate() - - def test_disallowed_filtering(self): - self.assertRaises(SuspiciousOperation, - self.client.get, "/test_admin/admin/admin_views/album/?owner__email__startswith=fuzzy" - ) - -class SaveAsTests(TestCase): - fixtures = ['admin-views-users.xml','admin-views-person.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_save_as_duplication(self): - """Ensure save as actually creates a new person""" - post_data = {'_saveasnew':'', 'name':'John M', 'gender':1} - response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data) - self.assertEqual(len(Person.objects.filter(name='John M')), 1) - self.assertEqual(len(Person.objects.filter(id=1)), 1) - - def test_save_as_display(self): - """ - Ensure that 'save as' is displayed when activated and after submitting - invalid data aside save_as_new will not show us a form to overwrite the - initial model. - """ - response = self.client.get('/test_admin/admin/admin_views/person/1/') - self.assert_(response.context['save_as']) - post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'} - response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data) - self.assertEqual(response.context['form_url'], '../add/') - -class CustomModelAdminTest(AdminViewBasicTest): - urlbit = "admin2" - - def testCustomAdminSiteLoginTemplate(self): - self.client.logout() - request = self.client.get('/test_admin/admin2/') - self.assertTemplateUsed(request, 'custom_admin/login.html') - self.assert_('Hello from a custom login template' in request.content) - - def testCustomAdminSiteLogoutTemplate(self): - request = self.client.get('/test_admin/admin2/logout/') - self.assertTemplateUsed(request, 'custom_admin/logout.html') - self.assert_('Hello from a custom logout template' in request.content) - - def testCustomAdminSiteIndexViewAndTemplate(self): - request = self.client.get('/test_admin/admin2/') - self.assertTemplateUsed(request, 'custom_admin/index.html') - self.assert_('Hello from a custom index template *bar*' in request.content) - - def testCustomAdminSitePasswordChangeTemplate(self): - request = self.client.get('/test_admin/admin2/password_change/') - self.assertTemplateUsed(request, 'custom_admin/password_change_form.html') - self.assert_('Hello from a custom password change form template' in request.content) - - def testCustomAdminSitePasswordChangeDoneTemplate(self): - request = self.client.get('/test_admin/admin2/password_change/done/') - self.assertTemplateUsed(request, 'custom_admin/password_change_done.html') - self.assert_('Hello from a custom password change done template' in request.content) - - def testCustomAdminSiteView(self): - self.client.login(username='super', password='secret') - response = self.client.get('/test_admin/%s/my_view/' % self.urlbit) - self.assert_(response.content == "Django is a magical pony!", response.content) - -def get_perm(Model, perm): - """Return the permission object, for the Model""" - ct = ContentType.objects.get_for_model(Model) - return Permission.objects.get(content_type=ct, codename=perm) - -class AdminViewPermissionsTest(TestCase): - """Tests for Admin Views Permissions.""" - - fixtures = ['admin-views-users.xml'] - - def setUp(self): - """Test setup.""" - # Setup permissions, for our users who can add, change, and delete. - # We can't put this into the fixture, because the content type id - # and the permission id could be different on each run of the test. - - opts = Article._meta - - # User who can add Articles - add_user = User.objects.get(username='adduser') - add_user.user_permissions.add(get_perm(Article, - opts.get_add_permission())) - - # User who can change Articles - change_user = User.objects.get(username='changeuser') - change_user.user_permissions.add(get_perm(Article, - opts.get_change_permission())) - - # User who can delete Articles - delete_user = User.objects.get(username='deleteuser') - delete_user.user_permissions.add(get_perm(Article, - opts.get_delete_permission())) - - delete_user.user_permissions.add(get_perm(Section, - Section._meta.get_delete_permission())) - - # login POST dicts - self.super_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super', - 'password': 'secret'} - self.super_email_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super@example.com', - 'password': 'secret'} - self.super_email_bad_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super@example.com', - 'password': 'notsecret'} - self.adduser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'adduser', - 'password': 'secret'} - self.changeuser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'changeuser', - 'password': 'secret'} - self.deleteuser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'deleteuser', - 'password': 'secret'} - self.joepublic_login = { - LOGIN_FORM_KEY: 1, - 'username': 'joepublic', - 'password': 'secret'} - self.no_username_login = { - LOGIN_FORM_KEY: 1, - 'password': 'secret'} - - def testLogin(self): - """ - Make sure only staff members can log in. - - Successful posts to the login page will redirect to the orignal url. - Unsuccessfull attempts will continue to render the login page with - a 200 status code. - """ - # Super User - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.super_login) - self.assertRedirects(login, '/test_admin/admin/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Test if user enters e-mail address - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.super_email_login) - self.assertContains(login, "Your e-mail address is not your username") - # only correct passwords get a username hint - login = self.client.post('/test_admin/admin/', self.super_email_bad_login) - self.assertContains(login, "Please enter a correct username and password") - new_user = User(username='jondoe', password='secret', email='super@example.com') - new_user.save() - # check to ensure if there are multiple e-mail addresses a user doesn't get a 500 - login = self.client.post('/test_admin/admin/', self.super_email_login) - self.assertContains(login, "Please enter a correct username and password") - - # Add User - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.adduser_login) - self.assertRedirects(login, '/test_admin/admin/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Change User - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.changeuser_login) - self.assertRedirects(login, '/test_admin/admin/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Delete User - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.deleteuser_login) - self.assertRedirects(login, '/test_admin/admin/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Regular User should not be able to login. - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.joepublic_login) - self.assertEqual(login.status_code, 200) - self.assertContains(login, "Please enter a correct username and password.") - - # Requests without username should not return 500 errors. - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/', self.no_username_login) - self.assertEqual(login.status_code, 200) - form = login.context[0].get('form') - self.assert_(login.context[0].get('error_message')) - - def testLoginSuccessfullyRedirectsToOriginalUrl(self): - request = self.client.get('/test_admin/admin/') - self.assertEqual(request.status_code, 200) - query_string = 'the-answer=42' - redirect_url = '/test_admin/admin/?%s' % query_string - new_next = {REDIRECT_FIELD_NAME: redirect_url} - login = self.client.post('/test_admin/admin/', dict(self.super_login, **new_next), QUERY_STRING=query_string) - self.assertRedirects(login, redirect_url) - - def testAddView(self): - """Test add view restricts access and actually adds items.""" - - add_dict = {'title' : 'Døm ikke', - 'content': '<p>great article</p>', - 'date_0': '2008-03-18', 'date_1': '10:54:39', - 'section': 1} - - # Change User should not have access to add articles - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.changeuser_login) - # make sure the view removes test cookie - self.assertEqual(self.client.session.test_cookie_worked(), False) - request = self.client.get('/test_admin/admin/admin_views/article/add/') - self.assertEqual(request.status_code, 403) - # Try POST just to make sure - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) - self.assertEqual(post.status_code, 403) - self.assertEqual(Article.objects.all().count(), 3) - self.client.get('/test_admin/admin/logout/') - - # Add user may login and POST to add view, then redirect to admin root - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.adduser_login) - addpage = self.client.get('/test_admin/admin/admin_views/article/add/') - self.assertEqual(addpage.status_code, 200) - change_list_link = '<a href="../">Articles</a> ›' - self.assertFalse(change_list_link in addpage.content, - 'User restricted to add permission is given link to change list view in breadcrumbs.') - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) - self.assertRedirects(post, '/test_admin/admin/') - self.assertEqual(Article.objects.all().count(), 4) - self.client.get('/test_admin/admin/logout/') - - # Super can add too, but is redirected to the change list view - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.super_login) - addpage = self.client.get('/test_admin/admin/admin_views/article/add/') - self.assertEqual(addpage.status_code, 200) - self.assertFalse(change_list_link not in addpage.content, - 'Unrestricted user is not given link to change list view in breadcrumbs.') - post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) - self.assertRedirects(post, '/test_admin/admin/admin_views/article/') - self.assertEqual(Article.objects.all().count(), 5) - self.client.get('/test_admin/admin/logout/') - - # 8509 - if a normal user is already logged in, it is possible - # to change user into the superuser without error - login = self.client.login(username='joepublic', password='secret') - # Check and make sure that if user expires, data still persists - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.super_login) - # make sure the view removes test cookie - self.assertEqual(self.client.session.test_cookie_worked(), False) - - def testChangeView(self): - """Change view should restrict access and allow users to edit items.""" - - change_dict = {'title' : 'Ikke fordømt', - 'content': '<p>edited article</p>', - 'date_0': '2008-03-18', 'date_1': '10:54:39', - 'section': 1} - - # add user shoud not be able to view the list of article or change any of them - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.adduser_login) - request = self.client.get('/test_admin/admin/admin_views/article/') - self.assertEqual(request.status_code, 403) - request = self.client.get('/test_admin/admin/admin_views/article/1/') - self.assertEqual(request.status_code, 403) - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) - self.assertEqual(post.status_code, 403) - self.client.get('/test_admin/admin/logout/') - - # change user can view all items and edit them - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.changeuser_login) - request = self.client.get('/test_admin/admin/admin_views/article/') - self.assertEqual(request.status_code, 200) - request = self.client.get('/test_admin/admin/admin_views/article/1/') - self.assertEqual(request.status_code, 200) - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) - self.assertRedirects(post, '/test_admin/admin/admin_views/article/') - self.assertEqual(Article.objects.get(pk=1).content, '<p>edited article</p>') - - # one error in form should produce singular error message, multiple errors plural - change_dict['title'] = '' - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) - self.assertEqual(request.status_code, 200) - self.assertTrue('Please correct the error below.' in post.content, - 'Singular error message not found in response to post with one error.') - change_dict['content'] = '' - post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) - self.assertEqual(request.status_code, 200) - self.assertTrue('Please correct the errors below.' in post.content, - 'Plural error message not found in response to post with multiple errors.') - self.client.get('/test_admin/admin/logout/') - - def testCustomModelAdminTemplates(self): - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.super_login) - - # Test custom change list template with custom extra context - request = self.client.get('/test_admin/admin/admin_views/customarticle/') - self.assertEqual(request.status_code, 200) - self.assert_("var hello = 'Hello!';" in request.content) - self.assertTemplateUsed(request, 'custom_admin/change_list.html') - - # Test custom add form template - request = self.client.get('/test_admin/admin/admin_views/customarticle/add/') - self.assertTemplateUsed(request, 'custom_admin/add_form.html') - - # Add an article so we can test delete, change, and history views - post = self.client.post('/test_admin/admin/admin_views/customarticle/add/', { - 'content': '<p>great article</p>', - 'date_0': '2008-03-18', - 'date_1': '10:54:39' - }) - self.assertRedirects(post, '/test_admin/admin/admin_views/customarticle/') - self.assertEqual(CustomArticle.objects.all().count(), 1) - - # Test custom delete, change, and object history templates - # Test custom change form template - request = self.client.get('/test_admin/admin/admin_views/customarticle/1/') - self.assertTemplateUsed(request, 'custom_admin/change_form.html') - request = self.client.get('/test_admin/admin/admin_views/customarticle/1/delete/') - self.assertTemplateUsed(request, 'custom_admin/delete_confirmation.html') - request = self.client.post('/test_admin/admin/admin_views/customarticle/', data={ - 'index': 0, - 'action': ['delete_selected'], - '_selected_action': ['1'], - }) - self.assertTemplateUsed(request, 'custom_admin/delete_selected_confirmation.html') - request = self.client.get('/test_admin/admin/admin_views/customarticle/1/history/') - self.assertTemplateUsed(request, 'custom_admin/object_history.html') - - self.client.get('/test_admin/admin/logout/') - - def testDeleteView(self): - """Delete view should restrict access and actually delete items.""" - - delete_dict = {'post': 'yes'} - - # add user shoud not be able to delete articles - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.adduser_login) - request = self.client.get('/test_admin/admin/admin_views/article/1/delete/') - self.assertEqual(request.status_code, 403) - post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) - self.assertEqual(post.status_code, 403) - self.assertEqual(Article.objects.all().count(), 3) - self.client.get('/test_admin/admin/logout/') - - # Delete user can delete - self.client.get('/test_admin/admin/') - self.client.post('/test_admin/admin/', self.deleteuser_login) - response = self.client.get('/test_admin/admin/admin_views/section/1/delete/') - # test response contains link to related Article - self.assertContains(response, "admin_views/article/1/") - - response = self.client.get('/test_admin/admin/admin_views/article/1/delete/') - self.assertEqual(response.status_code, 200) - post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) - self.assertRedirects(post, '/test_admin/admin/') - self.assertEqual(Article.objects.all().count(), 2) - article_ct = ContentType.objects.get_for_model(Article) - logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION) - self.assertEqual(logged.object_id, u'1') - self.client.get('/test_admin/admin/logout/') - - def testDisabledPermissionsWhenLoggedIn(self): - self.client.login(username='super', password='secret') - superuser = User.objects.get(username='super') - superuser.is_active = False - superuser.save() - - response = self.client.get('/test_admin/admin/') - self.assertContains(response, 'id="login-form"') - self.assertNotContains(response, 'Log out') - - response = self.client.get('/test_admin/admin/secure-view/') - self.assertContains(response, 'id="login-form"') - - -class AdminViewDeletedObjectsTest(TestCase): - fixtures = ['admin-views-users.xml', 'deleted-objects.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_nesting(self): - """ - Objects should be nested to display the relationships that - cause them to be scheduled for deletion. - """ - pattern = re.compile(r"""<li>Plot: <a href=".+/admin_views/plot/1/">World Domination</a>\s*<ul>\s*<li>Plot details: <a href=".+/admin_views/plotdetails/1/">almost finished</a>""") - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) - self.assertTrue(pattern.search(response.content)) - - def test_cyclic(self): - """ - Cyclic relationships should still cause each object to only be - listed once. - - """ - one = """<li>Cyclic one: <a href="/test_admin/admin/admin_views/cyclicone/1/">I am recursive</a>""" - two = """<li>Cyclic two: <a href="/test_admin/admin/admin_views/cyclictwo/1/">I am recursive too</a>""" - response = self.client.get('/test_admin/admin/admin_views/cyclicone/%s/delete/' % quote(1)) - - self.assertContains(response, one, 1) - self.assertContains(response, two, 1) - - def test_perms_needed(self): - self.client.logout() - delete_user = User.objects.get(username='deleteuser') - delete_user.user_permissions.add(get_perm(Plot, - Plot._meta.get_delete_permission())) - - self.assertTrue(self.client.login(username='deleteuser', - password='secret')) - - response = self.client.get('/test_admin/admin/admin_views/plot/%s/delete/' % quote(1)) - self.assertContains(response, "your account doesn't have permission to delete the following types of objects") - self.assertContains(response, "<li>plot details</li>") - - - def test_not_registered(self): - should_contain = """<li>Secret hideout: underground bunker""" - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) - self.assertContains(response, should_contain, 1) - - def test_multiple_fkeys_to_same_model(self): - """ - If a deleted object has two relationships from another model, - both of those should be followed in looking for related - objects to delete. - - """ - should_contain = """<li>Plot: <a href="/test_admin/admin/admin_views/plot/1/">World Domination</a>""" - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(1)) - self.assertContains(response, should_contain) - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(2)) - self.assertContains(response, should_contain) - - def test_multiple_fkeys_to_same_instance(self): - """ - If a deleted object has two relationships pointing to it from - another object, the other object should still only be listed - once. - - """ - should_contain = """<li>Plot: <a href="/test_admin/admin/admin_views/plot/2/">World Peace</a></li>""" - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(2)) - self.assertContains(response, should_contain, 1) - - def test_inheritance(self): - """ - In the case of an inherited model, if either the child or - parent-model instance is deleted, both instances are listed - for deletion, as well as any relationships they have. - - """ - should_contain = [ - """<li>Villain: <a href="/test_admin/admin/admin_views/villain/3/">Bob</a>""", - """<li>Super villain: <a href="/test_admin/admin/admin_views/supervillain/3/">Bob</a>""", - """<li>Secret hideout: floating castle""", - """<li>Super secret hideout: super floating castle!""" - ] - response = self.client.get('/test_admin/admin/admin_views/villain/%s/delete/' % quote(3)) - for should in should_contain: - self.assertContains(response, should, 1) - response = self.client.get('/test_admin/admin/admin_views/supervillain/%s/delete/' % quote(3)) - for should in should_contain: - self.assertContains(response, should, 1) - - def test_generic_relations(self): - """ - If a deleted object has GenericForeignKeys pointing to it, - those objects should be listed for deletion. - - """ - plot = Plot.objects.get(pk=3) - tag = FunkyTag.objects.create(content_object=plot, name='hott') - should_contain = """<li>Funky tag: hott""" - response = self.client.get('/test_admin/admin/admin_views/plot/%s/delete/' % quote(3)) - self.assertContains(response, should_contain) - -class AdminViewStringPrimaryKeyTest(TestCase): - fixtures = ['admin-views-users.xml', 'string-primary-key.xml'] - - def __init__(self, *args): - super(AdminViewStringPrimaryKeyTest, self).__init__(*args) - self.pk = """abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 -_.!~*'() ;/?:@&=+$, <>#%" {}|\^[]`""" - - def setUp(self): - self.client.login(username='super', password='secret') - content_type_pk = ContentType.objects.get_for_model(ModelWithStringPrimaryKey).pk - LogEntry.objects.log_action(100, content_type_pk, self.pk, self.pk, 2, change_message='') - - def tearDown(self): - self.client.logout() - - def test_get_history_view(self): - "Retrieving the history for the object using urlencoded form of primary key should work" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/history/' % quote(self.pk)) - self.assertContains(response, escape(self.pk)) - self.assertEqual(response.status_code, 200) - - def test_get_change_view(self): - "Retrieving the object using urlencoded form of primary key should work" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk)) - self.assertContains(response, escape(self.pk)) - self.assertEqual(response.status_code, 200) - - def test_changelist_to_changeform_link(self): - "The link from the changelist referring to the changeform of the object should be quoted" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/') - should_contain = """<th><a href="%s/">%s</a></th></tr>""" % (quote(self.pk), escape(self.pk)) - self.assertContains(response, should_contain) - - def test_recentactions_link(self): - "The link from the recent actions list referring to the changeform of the object should be quoted" - response = self.client.get('/test_admin/admin/') - should_contain = """<a href="admin_views/modelwithstringprimarykey/%s/">%s</a>""" % (quote(self.pk), escape(self.pk)) - self.assertContains(response, should_contain) - - def test_recentactions_without_content_type(self): - "If a LogEntry is missing content_type it will not display it in span tag under the hyperlink." - response = self.client.get('/test_admin/admin/') - should_contain = """<a href="admin_views/modelwithstringprimarykey/%s/">%s</a>""" % (quote(self.pk), escape(self.pk)) - self.assertContains(response, should_contain) - should_contain = "Model with string primary key" # capitalized in Recent Actions - self.assertContains(response, should_contain) - logentry = LogEntry.objects.get(content_type__name__iexact=should_contain) - # http://code.djangoproject.com/ticket/10275 - # if the log entry doesn't have a content type it should still be - # possible to view the Recent Actions part - logentry.content_type = None - logentry.save() - - counted_presence_before = response.content.count(should_contain) - response = self.client.get('/test_admin/admin/') - counted_presence_after = response.content.count(should_contain) - self.assertEquals(counted_presence_before - 1, - counted_presence_after) - - def test_deleteconfirmation_link(self): - "The link from the delete confirmation page referring back to the changeform of the object should be quoted" - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/delete/' % quote(self.pk)) - # this URL now comes through reverse(), thus iri_to_uri encoding - should_contain = """/%s/">%s</a>""" % (iri_to_uri(quote(self.pk)), escape(self.pk)) - self.assertContains(response, should_contain) - - def test_url_conflicts_with_add(self): - "A model with a primary key that ends with add should be visible" - add_model = ModelWithStringPrimaryKey(id="i have something to add") - add_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(add_model.pk)) - should_contain = """<h1>Change model with string primary key</h1>""" - self.assertContains(response, should_contain) - - def test_url_conflicts_with_delete(self): - "A model with a primary key that ends with delete should be visible" - delete_model = ModelWithStringPrimaryKey(id="delete") - delete_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(delete_model.pk)) - should_contain = """<h1>Change model with string primary key</h1>""" - self.assertContains(response, should_contain) - - def test_url_conflicts_with_history(self): - "A model with a primary key that ends with history should be visible" - history_model = ModelWithStringPrimaryKey(id="history") - history_model.save() - response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(history_model.pk)) - should_contain = """<h1>Change model with string primary key</h1>""" - self.assertContains(response, should_contain) - - -class SecureViewTest(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - # login POST dicts - self.super_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super', - 'password': 'secret'} - self.super_email_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super@example.com', - 'password': 'secret'} - self.super_email_bad_login = { - LOGIN_FORM_KEY: 1, - 'username': 'super@example.com', - 'password': 'notsecret'} - self.adduser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'adduser', - 'password': 'secret'} - self.changeuser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'changeuser', - 'password': 'secret'} - self.deleteuser_login = { - LOGIN_FORM_KEY: 1, - 'username': 'deleteuser', - 'password': 'secret'} - self.joepublic_login = { - LOGIN_FORM_KEY: 1, - 'username': 'joepublic', - 'password': 'secret'} - - def tearDown(self): - self.client.logout() - - def test_secure_view_shows_login_if_not_logged_in(self): - "Ensure that we see the login form" - response = self.client.get('/test_admin/admin/secure-view/' ) - self.assertTemplateUsed(response, 'admin/login.html') - - def test_secure_view_login_successfully_redirects_to_original_url(self): - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - query_string = 'the-answer=42' - redirect_url = '/test_admin/admin/secure-view/?%s' % query_string - new_next = {REDIRECT_FIELD_NAME: redirect_url} - login = self.client.post('/test_admin/admin/secure-view/', dict(self.super_login, **new_next), QUERY_STRING=query_string) - self.assertRedirects(login, redirect_url) - - def test_staff_member_required_decorator_works_as_per_admin_login(self): - """ - Make sure only staff members can log in. - - Successful posts to the login page will redirect to the orignal url. - Unsuccessfull attempts will continue to render the login page with - a 200 status code. - """ - # Super User - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.super_login) - self.assertRedirects(login, '/test_admin/admin/secure-view/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - # make sure the view removes test cookie - self.assertEqual(self.client.session.test_cookie_worked(), False) - - # Test if user enters e-mail address - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login) - self.assertContains(login, "Your e-mail address is not your username") - # only correct passwords get a username hint - login = self.client.post('/test_admin/admin/secure-view/', self.super_email_bad_login) - self.assertContains(login, "Please enter a correct username and password") - new_user = User(username='jondoe', password='secret', email='super@example.com') - new_user.save() - # check to ensure if there are multiple e-mail addresses a user doesn't get a 500 - login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login) - self.assertContains(login, "Please enter a correct username and password") - - # Add User - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.adduser_login) - self.assertRedirects(login, '/test_admin/admin/secure-view/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Change User - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.changeuser_login) - self.assertRedirects(login, '/test_admin/admin/secure-view/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Delete User - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.deleteuser_login) - self.assertRedirects(login, '/test_admin/admin/secure-view/') - self.assertFalse(login.context) - self.client.get('/test_admin/admin/logout/') - - # Regular User should not be able to login. - request = self.client.get('/test_admin/admin/secure-view/') - self.assertEqual(request.status_code, 200) - login = self.client.post('/test_admin/admin/secure-view/', self.joepublic_login) - self.assertEqual(login.status_code, 200) - # Login.context is a list of context dicts we just need to check the first one. - self.assert_(login.context[0].get('error_message')) - - # 8509 - if a normal user is already logged in, it is possible - # to change user into the superuser without error - login = self.client.login(username='joepublic', password='secret') - # Check and make sure that if user expires, data still persists - self.client.get('/test_admin/admin/secure-view/') - self.client.post('/test_admin/admin/secure-view/', self.super_login) - # make sure the view removes test cookie - self.assertEqual(self.client.session.test_cookie_worked(), False) - -class AdminViewUnicodeTest(TestCase): - fixtures = ['admin-views-unicode.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def testUnicodeEdit(self): - """ - A test to ensure that POST on edit_view handles non-ascii characters. - """ - post_data = { - "name": u"Test lærdommer", - # inline data - "chapter_set-TOTAL_FORMS": u"6", - "chapter_set-INITIAL_FORMS": u"3", - "chapter_set-MAX_NUM_FORMS": u"0", - "chapter_set-0-id": u"1", - "chapter_set-0-title": u"Norske bostaver æøå skaper problemer", - "chapter_set-0-content": u"<p>Svært frustrerende med UnicodeDecodeError</p>", - "chapter_set-1-id": u"2", - "chapter_set-1-title": u"Kjærlighet.", - "chapter_set-1-content": u"<p>La kjærligheten til de lidende seire.</p>", - "chapter_set-2-id": u"3", - "chapter_set-2-title": u"Need a title.", - "chapter_set-2-content": u"<p>Newest content</p>", - "chapter_set-3-id": u"", - "chapter_set-3-title": u"", - "chapter_set-3-content": u"", - "chapter_set-4-id": u"", - "chapter_set-4-title": u"", - "chapter_set-4-content": u"", - "chapter_set-5-id": u"", - "chapter_set-5-title": u"", - "chapter_set-5-content": u"", - } - - response = self.client.post('/test_admin/admin/admin_views/book/1/', post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - def testUnicodeDelete(self): - """ - Ensure that the delete_view handles non-ascii characters - """ - delete_dict = {'post': 'yes'} - response = self.client.get('/test_admin/admin/admin_views/book/1/delete/') - self.assertEqual(response.status_code, 200) - response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict) - self.assertRedirects(response, '/test_admin/admin/admin_views/book/') - - -class AdminViewListEditable(TestCase): - fixtures = ['admin-views-users.xml', 'admin-views-person.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_inheritance(self): - Podcast.objects.create(name="This Week in Django", - release_date=datetime.date.today()) - response = self.client.get('/test_admin/admin/admin_views/podcast/') - self.assertEqual(response.status_code, 200) - - def test_inheritance_2(self): - Vodcast.objects.create(name="This Week in Django", released=True) - response = self.client.get('/test_admin/admin/admin_views/vodcast/') - self.assertEqual(response.status_code, 200) - - def test_custom_pk(self): - Language.objects.create(iso='en', name='English', english_name='English') - response = self.client.get('/test_admin/admin/admin_views/language/') - self.assertEqual(response.status_code, 200) - - def test_changelist_input_html(self): - response = self.client.get('/test_admin/admin/admin_views/person/') - # 2 inputs per object(the field and the hidden id field) = 6 - # 3 management hidden fields = 3 - # 4 action inputs (3 regular checkboxes, 1 checkbox to select all) - # main form submit button = 1 - # search field and search submit button = 2 - # CSRF field = 1 - # field to track 'select all' across paginated views = 1 - # 6 + 3 + 4 + 1 + 2 + 1 + 1 = 18 inputs - self.assertEqual(response.content.count("<input"), 18) - # 1 select per object = 3 selects - self.assertEqual(response.content.count("<select"), 4) - - def test_post_messages(self): - # Ticket 12707: Saving inline editable should not show admin - # action warnings - data = { - "form-TOTAL_FORMS": "3", - "form-INITIAL_FORMS": "3", - "form-MAX_NUM_FORMS": "0", - - "form-0-gender": "1", - "form-0-id": "1", - - "form-1-gender": "2", - "form-1-id": "2", - - "form-2-alive": "checked", - "form-2-gender": "1", - "form-2-id": "3", - - "_save": "Save", - } - response = self.client.post('/test_admin/admin/admin_views/person/', - data, follow=True) - self.assertEqual(len(response.context['messages']), 1) - - def test_post_submission(self): - data = { - "form-TOTAL_FORMS": "3", - "form-INITIAL_FORMS": "3", - "form-MAX_NUM_FORMS": "0", - - "form-0-gender": "1", - "form-0-id": "1", - - "form-1-gender": "2", - "form-1-id": "2", - - "form-2-alive": "checked", - "form-2-gender": "1", - "form-2-id": "3", - - "_save": "Save", - } - self.client.post('/test_admin/admin/admin_views/person/', data) - - self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) - self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 2) - - # test a filtered page - data = { - "form-TOTAL_FORMS": "2", - "form-INITIAL_FORMS": "2", - "form-MAX_NUM_FORMS": "0", - - "form-0-id": "1", - "form-0-gender": "1", - "form-0-alive": "checked", - - "form-1-id": "3", - "form-1-gender": "1", - "form-1-alive": "checked", - - "_save": "Save", - } - self.client.post('/test_admin/admin/admin_views/person/?gender__exact=1', data) - - self.assertEqual(Person.objects.get(name="John Mauchly").alive, True) - - # test a searched page - data = { - "form-TOTAL_FORMS": "1", - "form-INITIAL_FORMS": "1", - "form-MAX_NUM_FORMS": "0", - - "form-0-id": "1", - "form-0-gender": "1", - - "_save": "Save", - } - self.client.post('/test_admin/admin/admin_views/person/?q=mauchly', data) - - self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) - - def test_non_form_errors(self): - # test if non-form errors are handled; ticket #12716 - data = { - "form-TOTAL_FORMS": "1", - "form-INITIAL_FORMS": "1", - "form-MAX_NUM_FORMS": "0", - - "form-0-id": "2", - "form-0-alive": "1", - "form-0-gender": "2", - - # Ensure that the form processing understands this as a list_editable "Save" - # and not an action "Go". - "_save": "Save", - } - response = self.client.post('/test_admin/admin/admin_views/person/', data) - self.assertContains(response, "Grace is not a Zombie") - - def test_non_form_errors_is_errorlist(self): - # test if non-form errors are correctly handled; ticket #12878 - data = { - "form-TOTAL_FORMS": "1", - "form-INITIAL_FORMS": "1", - "form-MAX_NUM_FORMS": "0", - - "form-0-id": "2", - "form-0-alive": "1", - "form-0-gender": "2", - - "_save": "Save", - } - response = self.client.post('/test_admin/admin/admin_views/person/', data) - non_form_errors = response.context['cl'].formset.non_form_errors() - self.assert_(isinstance(non_form_errors, ErrorList)) - self.assertEqual(str(non_form_errors), str(ErrorList(["Grace is not a Zombie"]))) - - def test_list_editable_ordering(self): - collector = Collector.objects.create(id=1, name="Frederick Clegg") - - Category.objects.create(id=1, order=1, collector=collector) - Category.objects.create(id=2, order=2, collector=collector) - Category.objects.create(id=3, order=0, collector=collector) - Category.objects.create(id=4, order=0, collector=collector) - - # NB: The order values must be changed so that the items are reordered. - data = { - "form-TOTAL_FORMS": "4", - "form-INITIAL_FORMS": "4", - "form-MAX_NUM_FORMS": "0", - - "form-0-order": "14", - "form-0-id": "1", - "form-0-collector": "1", - - "form-1-order": "13", - "form-1-id": "2", - "form-1-collector": "1", - - "form-2-order": "1", - "form-2-id": "3", - "form-2-collector": "1", - - "form-3-order": "0", - "form-3-id": "4", - "form-3-collector": "1", - - # Ensure that the form processing understands this as a list_editable "Save" - # and not an action "Go". - "_save": "Save", - } - response = self.client.post('/test_admin/admin/admin_views/category/', data) - # Successful post will redirect - self.assertEqual(response.status_code, 302) - - # Check that the order values have been applied to the right objects - self.assertEqual(Category.objects.get(id=1).order, 14) - self.assertEqual(Category.objects.get(id=2).order, 13) - self.assertEqual(Category.objects.get(id=3).order, 1) - self.assertEqual(Category.objects.get(id=4).order, 0) - - def test_list_editable_action_submit(self): - # List editable changes should not be executed if the action "Go" button is - # used to submit the form. - data = { - "form-TOTAL_FORMS": "3", - "form-INITIAL_FORMS": "3", - "form-MAX_NUM_FORMS": "0", - - "form-0-gender": "1", - "form-0-id": "1", - - "form-1-gender": "2", - "form-1-id": "2", - - "form-2-alive": "checked", - "form-2-gender": "1", - "form-2-id": "3", - - "index": "0", - "_selected_action": [u'3'], - "action": [u'', u'delete_selected'], - } - self.client.post('/test_admin/admin/admin_views/person/', data) - - self.assertEqual(Person.objects.get(name="John Mauchly").alive, True) - self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 1) - - def test_list_editable_action_choices(self): - # List editable changes should be executed if the "Save" button is - # used to submit the form - any action choices should be ignored. - data = { - "form-TOTAL_FORMS": "3", - "form-INITIAL_FORMS": "3", - "form-MAX_NUM_FORMS": "0", - - "form-0-gender": "1", - "form-0-id": "1", - - "form-1-gender": "2", - "form-1-id": "2", - - "form-2-alive": "checked", - "form-2-gender": "1", - "form-2-id": "3", - - "_save": "Save", - "_selected_action": [u'1'], - "action": [u'', u'delete_selected'], - } - self.client.post('/test_admin/admin/admin_views/person/', data) - - self.assertEqual(Person.objects.get(name="John Mauchly").alive, False) - self.assertEqual(Person.objects.get(name="Grace Hopper").gender, 2) - - - - -class AdminSearchTest(TestCase): - fixtures = ['admin-views-users','multiple-child-classes'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_search_on_sibling_models(self): - "Check that a search that mentions sibling models" - response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar') - # confirm the search returned 1 object - self.assertContains(response, "\n1 recommendation\n") - -class AdminInheritedInlinesTest(TestCase): - fixtures = ['admin-views-users.xml',] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def testInline(self): - "Ensure that inline models which inherit from a common parent are correctly handled by admin." - - foo_user = u"foo username" - bar_user = u"bar username" - - name_re = re.compile('name="(.*?)"') - - # test the add case - response = self.client.get('/test_admin/admin/admin_views/persona/add/') - names = name_re.findall(response.content) - # make sure we have no duplicate HTML names - self.assertEqual(len(names), len(set(names))) - - # test the add case - post_data = { - "name": u"Test Name", - # inline data - "accounts-TOTAL_FORMS": u"1", - "accounts-INITIAL_FORMS": u"0", - "accounts-MAX_NUM_FORMS": u"0", - "accounts-0-username": foo_user, - "accounts-2-TOTAL_FORMS": u"1", - "accounts-2-INITIAL_FORMS": u"0", - "accounts-2-MAX_NUM_FORMS": u"0", - "accounts-2-0-username": bar_user, - } - - response = self.client.post('/test_admin/admin/admin_views/persona/add/', post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - self.assertEqual(Persona.objects.count(), 1) - self.assertEqual(FooAccount.objects.count(), 1) - self.assertEqual(BarAccount.objects.count(), 1) - self.assertEqual(FooAccount.objects.all()[0].username, foo_user) - self.assertEqual(BarAccount.objects.all()[0].username, bar_user) - self.assertEqual(Persona.objects.all()[0].accounts.count(), 2) - - # test the edit case - - response = self.client.get('/test_admin/admin/admin_views/persona/1/') - names = name_re.findall(response.content) - # make sure we have no duplicate HTML names - self.assertEqual(len(names), len(set(names))) - - post_data = { - "name": u"Test Name", - - "accounts-TOTAL_FORMS": "2", - "accounts-INITIAL_FORMS": u"1", - "accounts-MAX_NUM_FORMS": u"0", - - "accounts-0-username": "%s-1" % foo_user, - "accounts-0-account_ptr": "1", - "accounts-0-persona": "1", - - "accounts-2-TOTAL_FORMS": u"2", - "accounts-2-INITIAL_FORMS": u"1", - "accounts-2-MAX_NUM_FORMS": u"0", - - "accounts-2-0-username": "%s-1" % bar_user, - "accounts-2-0-account_ptr": "2", - "accounts-2-0-persona": "1", - } - response = self.client.post('/test_admin/admin/admin_views/persona/1/', post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Persona.objects.count(), 1) - self.assertEqual(FooAccount.objects.count(), 1) - self.assertEqual(BarAccount.objects.count(), 1) - self.assertEqual(FooAccount.objects.all()[0].username, "%s-1" % foo_user) - self.assertEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user) - self.assertEqual(Persona.objects.all()[0].accounts.count(), 2) - -from django.core import mail - -class AdminActionsTest(TestCase): - fixtures = ['admin-views-users.xml', 'admin-views-actions.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_model_admin_custom_action(self): - "Tests a custom action defined in a ModelAdmin method" - action_data = { - ACTION_CHECKBOX_NAME: [1], - 'action' : 'mail_admin', - 'index': 0, - } - response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) - self.assertEquals(len(mail.outbox), 1) - self.assertEquals(mail.outbox[0].subject, 'Greetings from a ModelAdmin action') - - def test_model_admin_default_delete_action(self): - "Tests the default delete action defined as a ModelAdmin method" - action_data = { - ACTION_CHECKBOX_NAME: [1, 2], - 'action' : 'delete_selected', - 'index': 0, - } - delete_confirmation_data = { - ACTION_CHECKBOX_NAME: [1, 2], - 'action' : 'delete_selected', - 'post': 'yes', - } - confirmation = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) - self.assertContains(confirmation, "Are you sure you want to delete the selected subscriber objects") - self.assertTrue(confirmation.content.count(ACTION_CHECKBOX_NAME) == 2) - response = self.client.post('/test_admin/admin/admin_views/subscriber/', delete_confirmation_data) - self.assertEqual(Subscriber.objects.count(), 0) - - def test_custom_function_mail_action(self): - "Tests a custom action defined in a function" - action_data = { - ACTION_CHECKBOX_NAME: [1], - 'action' : 'external_mail', - 'index': 0, - } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) - self.assertEquals(len(mail.outbox), 1) - self.assertEquals(mail.outbox[0].subject, 'Greetings from a function action') - - def test_custom_function_action_with_redirect(self): - "Tests a custom action defined in a function" - action_data = { - ACTION_CHECKBOX_NAME: [1], - 'action' : 'redirect_to', - 'index': 0, - } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) - self.assertEqual(response.status_code, 302) - - def test_default_redirect(self): - """ - Test that actions which don't return an HttpResponse are redirected to - the same page, retaining the querystring (which may contain changelist - information). - """ - action_data = { - ACTION_CHECKBOX_NAME: [1], - 'action' : 'external_mail', - 'index': 0, - } - url = '/test_admin/admin/admin_views/externalsubscriber/?ot=asc&o=1' - response = self.client.post(url, action_data) - self.assertRedirects(response, url) - - def test_model_without_action(self): - "Tests a ModelAdmin without any action" - response = self.client.get('/test_admin/admin/admin_views/oldsubscriber/') - self.assertEquals(response.context["action_form"], None) - self.assert_( - '<input type="checkbox" class="action-select"' not in response.content, - "Found an unexpected action toggle checkboxbox in response" - ) - self.assert_('action-checkbox-column' not in response.content, - "Found unexpected action-checkbox-column class in response") - - def test_model_without_action_still_has_jquery(self): - "Tests that a ModelAdmin without any actions still gets jQuery included in page" - response = self.client.get('/test_admin/admin/admin_views/oldsubscriber/') - self.assertEquals(response.context["action_form"], None) - self.assert_('jquery.min.js' in response.content, - "jQuery missing from admin pages for model with no admin actions" - ) - - def test_action_column_class(self): - "Tests that the checkbox column class is present in the response" - response = self.client.get('/test_admin/admin/admin_views/subscriber/') - self.assertNotEqual(response.context["action_form"], None) - self.assert_('action-checkbox-column' in response.content, - "Expected an action-checkbox-column in response") - - def test_multiple_actions_form(self): - """ - Test that actions come from the form whose submit button was pressed (#10618). - """ - action_data = { - ACTION_CHECKBOX_NAME: [1], - # Two different actions selected on the two forms... - 'action': ['external_mail', 'delete_selected'], - # ...but we clicked "go" on the top form. - 'index': 0 - } - response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data) - - # Send mail, don't delete. - self.assertEquals(len(mail.outbox), 1) - self.assertEquals(mail.outbox[0].subject, 'Greetings from a function action') - - def test_user_message_on_none_selected(self): - """ - User should see a warning when 'Go' is pressed and no items are selected. - """ - action_data = { - ACTION_CHECKBOX_NAME: [], - 'action' : 'delete_selected', - 'index': 0, - } - response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) - msg = """Items must be selected in order to perform actions on them. No items have been changed.""" - self.assertContains(response, msg) - self.assertEqual(Subscriber.objects.count(), 2) - - def test_user_message_on_no_action(self): - """ - User should see a warning when 'Go' is pressed and no action is selected. - """ - action_data = { - ACTION_CHECKBOX_NAME: [1, 2], - 'action' : '', - 'index': 0, - } - response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data) - msg = """No action selected.""" - self.assertContains(response, msg) - self.assertEqual(Subscriber.objects.count(), 2) - - def test_selection_counter(self): - """ - Check if the selection counter is there. - """ - response = self.client.get('/test_admin/admin/admin_views/subscriber/') - self.assertContains(response, '0 of 2 selected') - - -class TestCustomChangeList(TestCase): - fixtures = ['admin-views-users.xml'] - urlbit = 'admin' - - def setUp(self): - result = self.client.login(username='super', password='secret') - self.assertEqual(result, True) - - def tearDown(self): - self.client.logout() - - def test_custom_changelist(self): - """ - Validate that a custom ChangeList class can be used (#9749) - """ - # Insert some data - post_data = {"name": u"First Gadget"} - response = self.client.post('/test_admin/%s/admin_views/gadget/add/' % self.urlbit, post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - # Hit the page once to get messages out of the queue message list - response = self.client.get('/test_admin/%s/admin_views/gadget/' % self.urlbit) - # Ensure that that data is still not visible on the page - response = self.client.get('/test_admin/%s/admin_views/gadget/' % self.urlbit) - self.assertEqual(response.status_code, 200) - self.assertNotContains(response, 'First Gadget') - - -class TestInlineNotEditable(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - result = self.client.login(username='super', password='secret') - self.assertEqual(result, True) - - def tearDown(self): - self.client.logout() - - def test(self): - """ - InlineModelAdmin broken? - """ - response = self.client.get('/test_admin/admin/admin_views/parent/add/') - self.assertEqual(response.status_code, 200) - -class AdminCustomQuerysetTest(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - self.pks = [EmptyModel.objects.create().id for i in range(3)] - - def test_changelist_view(self): - response = self.client.get('/test_admin/admin/admin_views/emptymodel/') - for i in self.pks: - if i > 1: - self.assertContains(response, 'Primary key = %s' % i) - else: - self.assertNotContains(response, 'Primary key = %s' % i) - - def test_change_view(self): - for i in self.pks: - response = self.client.get('/test_admin/admin/admin_views/emptymodel/%s/' % i) - if i > 1: - self.assertEqual(response.status_code, 200) - else: - self.assertEqual(response.status_code, 404) - -class AdminInlineFileUploadTest(TestCase): - fixtures = ['admin-views-users.xml', 'admin-views-actions.xml'] - urlbit = 'admin' - - def setUp(self): - self.client.login(username='super', password='secret') - - # Set up test Picture and Gallery. - # These must be set up here instead of in fixtures in order to allow Picture - # to use a NamedTemporaryFile. - tdir = tempfile.gettempdir() - file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir) - file1.write('a' * (2 ** 21)) - filename = file1.name - file1.close() - g = Gallery(name="Test Gallery") - g.save() - p = Picture(name="Test Picture", image=filename, gallery=g) - p.save() - - def tearDown(self): - self.client.logout() - - def test_inline_file_upload_edit_validation_error_post(self): - """ - Test that inline file uploads correctly display prior data (#10002). - """ - post_data = { - "name": u"Test Gallery", - "pictures-TOTAL_FORMS": u"2", - "pictures-INITIAL_FORMS": u"1", - "pictures-MAX_NUM_FORMS": u"0", - "pictures-0-id": u"1", - "pictures-0-gallery": u"1", - "pictures-0-name": "Test Picture", - "pictures-0-image": "", - "pictures-1-id": "", - "pictures-1-gallery": "1", - "pictures-1-name": "Test Picture 2", - "pictures-1-image": "", - } - response = self.client.post('/test_admin/%s/admin_views/gallery/1/' % self.urlbit, post_data) - self.assertTrue(response._container[0].find("Currently:") > -1) - - -class AdminInlineTests(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - self.post_data = { - "name": u"Test Name", - - "widget_set-TOTAL_FORMS": "3", - "widget_set-INITIAL_FORMS": u"0", - "widget_set-MAX_NUM_FORMS": u"0", - "widget_set-0-id": "", - "widget_set-0-owner": "1", - "widget_set-0-name": "", - "widget_set-1-id": "", - "widget_set-1-owner": "1", - "widget_set-1-name": "", - "widget_set-2-id": "", - "widget_set-2-owner": "1", - "widget_set-2-name": "", - - "doohickey_set-TOTAL_FORMS": "3", - "doohickey_set-INITIAL_FORMS": u"0", - "doohickey_set-MAX_NUM_FORMS": u"0", - "doohickey_set-0-owner": "1", - "doohickey_set-0-code": "", - "doohickey_set-0-name": "", - "doohickey_set-1-owner": "1", - "doohickey_set-1-code": "", - "doohickey_set-1-name": "", - "doohickey_set-2-owner": "1", - "doohickey_set-2-code": "", - "doohickey_set-2-name": "", - - "grommet_set-TOTAL_FORMS": "3", - "grommet_set-INITIAL_FORMS": u"0", - "grommet_set-MAX_NUM_FORMS": u"0", - "grommet_set-0-code": "", - "grommet_set-0-owner": "1", - "grommet_set-0-name": "", - "grommet_set-1-code": "", - "grommet_set-1-owner": "1", - "grommet_set-1-name": "", - "grommet_set-2-code": "", - "grommet_set-2-owner": "1", - "grommet_set-2-name": "", - - "whatsit_set-TOTAL_FORMS": "3", - "whatsit_set-INITIAL_FORMS": u"0", - "whatsit_set-MAX_NUM_FORMS": u"0", - "whatsit_set-0-owner": "1", - "whatsit_set-0-index": "", - "whatsit_set-0-name": "", - "whatsit_set-1-owner": "1", - "whatsit_set-1-index": "", - "whatsit_set-1-name": "", - "whatsit_set-2-owner": "1", - "whatsit_set-2-index": "", - "whatsit_set-2-name": "", - - "fancydoodad_set-TOTAL_FORMS": "3", - "fancydoodad_set-INITIAL_FORMS": u"0", - "fancydoodad_set-MAX_NUM_FORMS": u"0", - "fancydoodad_set-0-doodad_ptr": "", - "fancydoodad_set-0-owner": "1", - "fancydoodad_set-0-name": "", - "fancydoodad_set-0-expensive": "on", - "fancydoodad_set-1-doodad_ptr": "", - "fancydoodad_set-1-owner": "1", - "fancydoodad_set-1-name": "", - "fancydoodad_set-1-expensive": "on", - "fancydoodad_set-2-doodad_ptr": "", - "fancydoodad_set-2-owner": "1", - "fancydoodad_set-2-name": "", - "fancydoodad_set-2-expensive": "on", - - "category_set-TOTAL_FORMS": "3", - "category_set-INITIAL_FORMS": "0", - "category_set-MAX_NUM_FORMS": "0", - "category_set-0-order": "", - "category_set-0-id": "", - "category_set-0-collector": "1", - "category_set-1-order": "", - "category_set-1-id": "", - "category_set-1-collector": "1", - "category_set-2-order": "", - "category_set-2-id": "", - "category_set-2-collector": "1", - } - - result = self.client.login(username='super', password='secret') - self.assertEqual(result, True) - self.collector = Collector(pk=1,name='John Fowles') - self.collector.save() - - def tearDown(self): - self.client.logout() - - def test_simple_inline(self): - "A simple model can be saved as inlines" - # First add a new inline - self.post_data['widget_set-0-name'] = "Widget 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Widget.objects.count(), 1) - self.assertEqual(Widget.objects.all()[0].name, "Widget 1") - - # Check that the PK link exists on the rendered form - response = self.client.get('/test_admin/admin/admin_views/collector/1/') - self.assertContains(response, 'name="widget_set-0-id"') - - # Now resave that inline - self.post_data['widget_set-INITIAL_FORMS'] = "1" - self.post_data['widget_set-0-id'] = "1" - self.post_data['widget_set-0-name'] = "Widget 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Widget.objects.count(), 1) - self.assertEqual(Widget.objects.all()[0].name, "Widget 1") - - # Now modify that inline - self.post_data['widget_set-INITIAL_FORMS'] = "1" - self.post_data['widget_set-0-id'] = "1" - self.post_data['widget_set-0-name'] = "Widget 1 Updated" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Widget.objects.count(), 1) - self.assertEqual(Widget.objects.all()[0].name, "Widget 1 Updated") - - def test_explicit_autofield_inline(self): - "A model with an explicit autofield primary key can be saved as inlines. Regression for #8093" - # First add a new inline - self.post_data['grommet_set-0-name'] = "Grommet 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Grommet.objects.count(), 1) - self.assertEqual(Grommet.objects.all()[0].name, "Grommet 1") - - # Check that the PK link exists on the rendered form - response = self.client.get('/test_admin/admin/admin_views/collector/1/') - self.assertContains(response, 'name="grommet_set-0-code"') - - # Now resave that inline - self.post_data['grommet_set-INITIAL_FORMS'] = "1" - self.post_data['grommet_set-0-code'] = "1" - self.post_data['grommet_set-0-name'] = "Grommet 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Grommet.objects.count(), 1) - self.assertEqual(Grommet.objects.all()[0].name, "Grommet 1") - - # Now modify that inline - self.post_data['grommet_set-INITIAL_FORMS'] = "1" - self.post_data['grommet_set-0-code'] = "1" - self.post_data['grommet_set-0-name'] = "Grommet 1 Updated" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Grommet.objects.count(), 1) - self.assertEqual(Grommet.objects.all()[0].name, "Grommet 1 Updated") - - def test_char_pk_inline(self): - "A model with a character PK can be saved as inlines. Regression for #10992" - # First add a new inline - self.post_data['doohickey_set-0-code'] = "DH1" - self.post_data['doohickey_set-0-name'] = "Doohickey 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(DooHickey.objects.count(), 1) - self.assertEqual(DooHickey.objects.all()[0].name, "Doohickey 1") - - # Check that the PK link exists on the rendered form - response = self.client.get('/test_admin/admin/admin_views/collector/1/') - self.assertContains(response, 'name="doohickey_set-0-code"') - - # Now resave that inline - self.post_data['doohickey_set-INITIAL_FORMS'] = "1" - self.post_data['doohickey_set-0-code'] = "DH1" - self.post_data['doohickey_set-0-name'] = "Doohickey 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(DooHickey.objects.count(), 1) - self.assertEqual(DooHickey.objects.all()[0].name, "Doohickey 1") - - # Now modify that inline - self.post_data['doohickey_set-INITIAL_FORMS'] = "1" - self.post_data['doohickey_set-0-code'] = "DH1" - self.post_data['doohickey_set-0-name'] = "Doohickey 1 Updated" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(DooHickey.objects.count(), 1) - self.assertEqual(DooHickey.objects.all()[0].name, "Doohickey 1 Updated") - - def test_integer_pk_inline(self): - "A model with an integer PK can be saved as inlines. Regression for #10992" - # First add a new inline - self.post_data['whatsit_set-0-index'] = "42" - self.post_data['whatsit_set-0-name'] = "Whatsit 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Whatsit.objects.count(), 1) - self.assertEqual(Whatsit.objects.all()[0].name, "Whatsit 1") - - # Check that the PK link exists on the rendered form - response = self.client.get('/test_admin/admin/admin_views/collector/1/') - self.assertContains(response, 'name="whatsit_set-0-index"') - - # Now resave that inline - self.post_data['whatsit_set-INITIAL_FORMS'] = "1" - self.post_data['whatsit_set-0-index'] = "42" - self.post_data['whatsit_set-0-name'] = "Whatsit 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Whatsit.objects.count(), 1) - self.assertEqual(Whatsit.objects.all()[0].name, "Whatsit 1") - - # Now modify that inline - self.post_data['whatsit_set-INITIAL_FORMS'] = "1" - self.post_data['whatsit_set-0-index'] = "42" - self.post_data['whatsit_set-0-name'] = "Whatsit 1 Updated" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Whatsit.objects.count(), 1) - self.assertEqual(Whatsit.objects.all()[0].name, "Whatsit 1 Updated") - - def test_inherited_inline(self): - "An inherited model can be saved as inlines. Regression for #11042" - # First add a new inline - self.post_data['fancydoodad_set-0-name'] = "Fancy Doodad 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(FancyDoodad.objects.count(), 1) - self.assertEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1") - - # Check that the PK link exists on the rendered form - response = self.client.get('/test_admin/admin/admin_views/collector/1/') - self.assertContains(response, 'name="fancydoodad_set-0-doodad_ptr"') - - # Now resave that inline - self.post_data['fancydoodad_set-INITIAL_FORMS'] = "1" - self.post_data['fancydoodad_set-0-doodad_ptr'] = "1" - self.post_data['fancydoodad_set-0-name'] = "Fancy Doodad 1" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(FancyDoodad.objects.count(), 1) - self.assertEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1") - - # Now modify that inline - self.post_data['fancydoodad_set-INITIAL_FORMS'] = "1" - self.post_data['fancydoodad_set-0-doodad_ptr'] = "1" - self.post_data['fancydoodad_set-0-name'] = "Fancy Doodad 1 Updated" - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - self.assertEqual(response.status_code, 302) - self.assertEqual(FancyDoodad.objects.count(), 1) - self.assertEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1 Updated") - - def test_ordered_inline(self): - """Check that an inline with an editable ordering fields is - updated correctly. Regression for #10922""" - # Create some objects with an initial ordering - Category.objects.create(id=1, order=1, collector=self.collector) - Category.objects.create(id=2, order=2, collector=self.collector) - Category.objects.create(id=3, order=0, collector=self.collector) - Category.objects.create(id=4, order=0, collector=self.collector) - - # NB: The order values must be changed so that the items are reordered. - self.post_data.update({ - "name": "Frederick Clegg", - - "category_set-TOTAL_FORMS": "7", - "category_set-INITIAL_FORMS": "4", - "category_set-MAX_NUM_FORMS": "0", - - "category_set-0-order": "14", - "category_set-0-id": "1", - "category_set-0-collector": "1", - - "category_set-1-order": "13", - "category_set-1-id": "2", - "category_set-1-collector": "1", - - "category_set-2-order": "1", - "category_set-2-id": "3", - "category_set-2-collector": "1", - - "category_set-3-order": "0", - "category_set-3-id": "4", - "category_set-3-collector": "1", - - "category_set-4-order": "", - "category_set-4-id": "", - "category_set-4-collector": "1", - - "category_set-5-order": "", - "category_set-5-id": "", - "category_set-5-collector": "1", - - "category_set-6-order": "", - "category_set-6-id": "", - "category_set-6-collector": "1", - }) - response = self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data) - # Successful post will redirect - self.assertEqual(response.status_code, 302) - - # Check that the order values have been applied to the right objects - self.assertEqual(self.collector.category_set.count(), 4) - self.assertEqual(Category.objects.get(id=1).order, 14) - self.assertEqual(Category.objects.get(id=2).order, 13) - self.assertEqual(Category.objects.get(id=3).order, 1) - self.assertEqual(Category.objects.get(id=4).order, 0) - - -class NeverCacheTests(TestCase): - fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def testAdminIndex(self): - "Check the never-cache status of the main index" - response = self.client.get('/test_admin/admin/') - self.assertEqual(get_max_age(response), 0) - - def testAppIndex(self): - "Check the never-cache status of an application index" - response = self.client.get('/test_admin/admin/admin_views/') - self.assertEqual(get_max_age(response), 0) - - def testModelIndex(self): - "Check the never-cache status of a model index" - response = self.client.get('/test_admin/admin/admin_views/fabric/') - self.assertEqual(get_max_age(response), 0) - - def testModelAdd(self): - "Check the never-cache status of a model add page" - response = self.client.get('/test_admin/admin/admin_views/fabric/add/') - self.assertEqual(get_max_age(response), 0) - - def testModelView(self): - "Check the never-cache status of a model edit page" - response = self.client.get('/test_admin/admin/admin_views/section/1/') - self.assertEqual(get_max_age(response), 0) - - def testModelHistory(self): - "Check the never-cache status of a model history page" - response = self.client.get('/test_admin/admin/admin_views/section/1/history/') - self.assertEqual(get_max_age(response), 0) - - def testModelDelete(self): - "Check the never-cache status of a model delete page" - response = self.client.get('/test_admin/admin/admin_views/section/1/delete/') - self.assertEqual(get_max_age(response), 0) - - def testLogin(self): - "Check the never-cache status of login views" - self.client.logout() - response = self.client.get('/test_admin/admin/') - self.assertEqual(get_max_age(response), 0) - - def testLogout(self): - "Check the never-cache status of logout view" - response = self.client.get('/test_admin/admin/logout/') - self.assertEqual(get_max_age(response), 0) - - def testPasswordChange(self): - "Check the never-cache status of the password change view" - self.client.logout() - response = self.client.get('/test_admin/password_change/') - self.assertEqual(get_max_age(response), None) - - def testPasswordChangeDone(self): - "Check the never-cache status of the password change done view" - response = self.client.get('/test_admin/admin/password_change/done/') - self.assertEqual(get_max_age(response), None) - - def testJsi18n(self): - "Check the never-cache status of the Javascript i18n view" - response = self.client.get('/test_admin/admin/jsi18n/') - self.assertEqual(get_max_age(response), None) - - -class ReadonlyTest(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_readonly_get(self): - response = self.client.get('/test_admin/admin/admin_views/post/add/') - self.assertEqual(response.status_code, 200) - self.assertNotContains(response, 'name="posted"') - # 3 fields + 2 submit buttons + 4 inline management form fields, + 2 - # hidden fields for inlines + 1 field for the inline + 2 empty form - self.assertEqual(response.content.count("<input"), 14) - self.assertContains(response, formats.localize(datetime.date.today())) - self.assertContains(response, - "<label>Awesomeness level:</label>") - self.assertContains(response, "Very awesome.") - self.assertContains(response, "Unkown coolness.") - self.assertContains(response, "foo") - self.assertContains(response, - formats.localize(datetime.date.today() - datetime.timedelta(days=7)) - ) - - self.assertContains(response, '<div class="form-row coolness">') - self.assertContains(response, '<div class="form-row awesomeness_level">') - self.assertContains(response, '<div class="form-row posted">') - self.assertContains(response, '<div class="form-row value">') - self.assertContains(response, '<div class="form-row ">') - - p = Post.objects.create(title="I worked on readonly_fields", content="Its good stuff") - response = self.client.get('/test_admin/admin/admin_views/post/%d/' % p.pk) - self.assertContains(response, "%d amount of cool" % p.pk) - - def test_readonly_post(self): - data = { - "title": "Django Got Readonly Fields", - "content": "This is an incredible development.", - "link_set-TOTAL_FORMS": "1", - "link_set-INITIAL_FORMS": "0", - "link_set-MAX_NUM_FORMS": "0", - } - response = self.client.post('/test_admin/admin/admin_views/post/add/', data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Post.objects.count(), 1) - p = Post.objects.get() - self.assertEqual(p.posted, datetime.date.today()) - - data["posted"] = "10-8-1990" # some date that's not today - response = self.client.post('/test_admin/admin/admin_views/post/add/', data) - self.assertEqual(response.status_code, 302) - self.assertEqual(Post.objects.count(), 2) - p = Post.objects.order_by('-id')[0] - self.assertEqual(p.posted, datetime.date.today()) - - def test_readonly_manytomany(self): - "Regression test for #13004" - response = self.client.get('/test_admin/admin/admin_views/pizza/add/') - self.assertEqual(response.status_code, 200) - -class UserAdminTest(TestCase): - """ - Tests user CRUD functionality. - """ - fixtures = ['admin-views-users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_save_button(self): - user_count = User.objects.count() - response = self.client.post('/test_admin/admin/auth/user/add/', { - 'username': 'newuser', - 'password1': 'newpassword', - 'password2': 'newpassword', - }) - new_user = User.objects.order_by('-id')[0] - self.assertRedirects(response, '/test_admin/admin/auth/user/%s/' % new_user.pk) - self.assertEqual(User.objects.count(), user_count + 1) - self.assertNotEqual(new_user.password, UNUSABLE_PASSWORD) - - def test_save_continue_editing_button(self): - user_count = User.objects.count() - response = self.client.post('/test_admin/admin/auth/user/add/', { - 'username': 'newuser', - 'password1': 'newpassword', - 'password2': 'newpassword', - '_continue': '1', - }) - new_user = User.objects.order_by('-id')[0] - self.assertRedirects(response, '/test_admin/admin/auth/user/%s/' % new_user.pk) - self.assertEqual(User.objects.count(), user_count + 1) - self.assertNotEqual(new_user.password, UNUSABLE_PASSWORD) - - def test_password_mismatch(self): - response = self.client.post('/test_admin/admin/auth/user/add/', { - 'username': 'newuser', - 'password1': 'newpassword', - 'password2': 'mismatch', - }) - self.assertEqual(response.status_code, 200) - adminform = response.context['adminform'] - self.assertTrue('password' not in adminform.form.errors) - self.assertEqual(adminform.form.errors['password2'], - [u"The two password fields didn't match."]) - - def test_user_fk_popup(self): - response = self.client.get('/test_admin/admin/admin_views/album/add/') - self.assertEqual(response.status_code, 200) - self.assertContains(response, '/test_admin/admin/auth/user/add') - self.assertContains(response, 'class="add-another" id="add_id_owner" onclick="return showAddAnotherPopup(this);"') - response = self.client.get('/test_admin/admin/auth/user/add/?_popup=1') - self.assertNotContains(response, 'name="_continue"') - self.assertNotContains(response, 'name="_addanother"') - - def test_save_add_another_button(self): - user_count = User.objects.count() - response = self.client.post('/test_admin/admin/auth/user/add/', { - 'username': 'newuser', - 'password1': 'newpassword', - 'password2': 'newpassword', - '_addanother': '1', - }) - new_user = User.objects.order_by('-id')[0] - self.assertRedirects(response, '/test_admin/admin/auth/user/add/') - self.assertEqual(User.objects.count(), user_count + 1) - self.assertNotEqual(new_user.password, UNUSABLE_PASSWORD) - -try: - # If docutils isn't installed, skip the AdminDocs tests. - import docutils - - class AdminDocsTest(TestCase): - fixtures = ['admin-views-users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def test_tags(self): - response = self.client.get('/test_admin/admin/doc/tags/') - - # The builtin tag group exists - self.assertContains(response, "<h2>Built-in tags</h2>", count=2) - - # A builtin tag exists in both the index and detail - self.assertContains(response, '<h3 id="built_in-autoescape">autoescape</h3>') - self.assertContains(response, '<li><a href="#built_in-autoescape">autoescape</a></li>') - - # An app tag exists in both the index and detail - self.assertContains(response, '<h3 id="comments-get_comment_count">get_comment_count</h3>') - self.assertContains(response, '<li><a href="#comments-get_comment_count">get_comment_count</a></li>') - - # The admin list tag group exists - self.assertContains(response, "<h2>admin_list</h2>", count=2) - - # An admin list tag exists in both the index and detail - self.assertContains(response, '<h3 id="admin_list-admin_actions">admin_actions</h3>') - self.assertContains(response, '<li><a href="#admin_list-admin_actions">admin_actions</a></li>') - - def test_filters(self): - response = self.client.get('/test_admin/admin/doc/filters/') - - # The builtin filter group exists - self.assertContains(response, "<h2>Built-in filters</h2>", count=2) - - # A builtin filter exists in both the index and detail - self.assertContains(response, '<h3 id="built_in-add">add</h3>') - self.assertContains(response, '<li><a href="#built_in-add">add</a></li>') - -except ImportError: - pass - -class ValidXHTMLTests(TestCase): - fixtures = ['admin-views-users.xml'] - urlbit = 'admin' - - def setUp(self): - self._context_processors = None - self._use_i18n, settings.USE_I18N = settings.USE_I18N, False - if 'django.core.context_processors.i18n' in settings.TEMPLATE_CONTEXT_PROCESSORS: - self._context_processors = settings.TEMPLATE_CONTEXT_PROCESSORS - cp = list(settings.TEMPLATE_CONTEXT_PROCESSORS) - cp.remove('django.core.context_processors.i18n') - settings.TEMPLATE_CONTEXT_PROCESSORS = tuple(cp) - # Force re-evaluation of the contex processor list - django.template.context._standard_context_processors = None - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - if self._context_processors is not None: - settings.TEMPLATE_CONTEXT_PROCESSORS = self._context_processors - # Force re-evaluation of the contex processor list - django.template.context._standard_context_processors = None - settings.USE_I18N = self._use_i18n - - def testLangNamePresent(self): - response = self.client.get('/test_admin/%s/admin_views/' % self.urlbit) - self.assertFalse(' lang=""' in response.content) - self.assertFalse(' xml:lang=""' in response.content) diff --git a/parts/django/tests/regressiontests/admin_views/urls.py b/parts/django/tests/regressiontests/admin_views/urls.py deleted file mode 100644 index f3f1fbd..0000000 --- a/parts/django/tests/regressiontests/admin_views/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.conf.urls.defaults import * -from django.contrib import admin -import views -import customadmin - -urlpatterns = patterns('', - (r'^admin/doc/', include('django.contrib.admindocs.urls')), - (r'^admin/secure-view/$', views.secure_view), - (r'^admin/', include(admin.site.urls)), - (r'^admin2/', include(customadmin.site.urls)), -) diff --git a/parts/django/tests/regressiontests/admin_views/views.py b/parts/django/tests/regressiontests/admin_views/views.py deleted file mode 100644 index 732b253..0000000 --- a/parts/django/tests/regressiontests/admin_views/views.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.contrib.admin.views.decorators import staff_member_required -from django.http import HttpResponse - -def secure_view(request): - return HttpResponse('%s' % request.POST) -secure_view = staff_member_required(secure_view)
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_widgets/__init__.py b/parts/django/tests/regressiontests/admin_widgets/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/admin_widgets/fixtures/admin-widgets-users.xml b/parts/django/tests/regressiontests/admin_widgets/fixtures/admin-widgets-users.xml deleted file mode 100644 index b851562..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/fixtures/admin-widgets-users.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="101" model="auth.user"> - <field type="CharField" name="username">testser</field> - <field type="CharField" name="first_name">Add</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">auser@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">False</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - - <object pk="1" model="admin_widgets.car"> - <field to="auth.user" name="owner" rel="ManyToOneRel">100</field> - <field type="CharField" name="make">Volkswagon</field> - <field type="CharField" name="model">Passat</field> - </object> - <object pk="2" model="admin_widgets.car"> - <field to="auth.user" name="owner" rel="ManyToOneRel">101</field> - <field type="CharField" name="make">BMW</field> - <field type="CharField" name="model">M3</field> - </object> - -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/admin_widgets/models.py b/parts/django/tests/regressiontests/admin_widgets/models.py deleted file mode 100644 index 450c3e6..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/models.py +++ /dev/null @@ -1,68 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User - -class MyFileField(models.FileField): - pass - -class Member(models.Model): - name = models.CharField(max_length=100) - birthdate = models.DateTimeField(blank=True, null=True) - gender = models.CharField(max_length=1, blank=True, choices=[('M','Male'), ('F', 'Female')]) - - def __unicode__(self): - return self.name - -class Band(models.Model): - name = models.CharField(max_length=100) - members = models.ManyToManyField(Member) - - def __unicode__(self): - return self.name - -class Album(models.Model): - band = models.ForeignKey(Band) - name = models.CharField(max_length=100) - cover_art = models.FileField(upload_to='albums') - backside_art = MyFileField(upload_to='albums_back', null=True) - - def __unicode__(self): - return self.name - -class HiddenInventoryManager(models.Manager): - def get_query_set(self): - return super(HiddenInventoryManager, self).get_query_set().filter(hidden=False) - -class Inventory(models.Model): - barcode = models.PositiveIntegerField(unique=True) - parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) - name = models.CharField(blank=False, max_length=20) - hidden = models.BooleanField(default=False) - - # see #9258 - default_manager = models.Manager() - objects = HiddenInventoryManager() - - def __unicode__(self): - return self.name - -class Event(models.Model): - band = models.ForeignKey(Band, limit_choices_to=models.Q(pk__gt=0)) - start_date = models.DateField(blank=True, null=True) - start_time = models.TimeField(blank=True, null=True) - description = models.TextField(blank=True) - link = models.URLField(blank=True) - min_age = models.IntegerField(blank=True, null=True) - -class Car(models.Model): - owner = models.ForeignKey(User) - make = models.CharField(max_length=30) - model = models.CharField(max_length=30) - - def __unicode__(self): - return u"%s %s" % (self.make, self.model) - -class CarTire(models.Model): - """ - A single car tire. This to test that a user can only select their own cars. - """ - car = models.ForeignKey(Car) diff --git a/parts/django/tests/regressiontests/admin_widgets/tests.py b/parts/django/tests/regressiontests/admin_widgets/tests.py deleted file mode 100644 index 51d883f..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/tests.py +++ /dev/null @@ -1,316 +0,0 @@ -# encoding: utf-8 - -from datetime import datetime -from unittest import TestCase - -from django import forms -from django.conf import settings -from django.contrib import admin -from django.contrib.admin import widgets -from django.contrib.admin.widgets import FilteredSelectMultiple, AdminSplitDateTime -from django.contrib.admin.widgets import (AdminFileWidget, ForeignKeyRawIdWidget, - ManyToManyRawIdWidget) -from django.core.files.storage import default_storage -from django.core.files.uploadedfile import SimpleUploadedFile -from django.db.models import DateField -from django.test import TestCase as DjangoTestCase -from django.utils.html import conditional_escape -from django.utils.translation import activate, deactivate - -import models - - -class AdminFormfieldForDBFieldTests(TestCase): - """ - Tests for correct behavior of ModelAdmin.formfield_for_dbfield - """ - - def assertFormfield(self, model, fieldname, widgetclass, **admin_overrides): - """ - Helper to call formfield_for_dbfield for a given model and field name - and verify that the returned formfield is appropriate. - """ - # Override any settings on the model admin - class MyModelAdmin(admin.ModelAdmin): pass - for k in admin_overrides: - setattr(MyModelAdmin, k, admin_overrides[k]) - - # Construct the admin, and ask it for a formfield - ma = MyModelAdmin(model, admin.site) - ff = ma.formfield_for_dbfield(model._meta.get_field(fieldname), request=None) - - # "unwrap" the widget wrapper, if needed - if isinstance(ff.widget, widgets.RelatedFieldWidgetWrapper): - widget = ff.widget.widget - else: - widget = ff.widget - - # Check that we got a field of the right type - self.assert_( - isinstance(widget, widgetclass), - "Wrong widget for %s.%s: expected %s, got %s" % \ - (model.__class__.__name__, fieldname, widgetclass, type(widget)) - ) - - # Return the formfield so that other tests can continue - return ff - - def testDateField(self): - self.assertFormfield(models.Event, 'start_date', widgets.AdminDateWidget) - - def testDateTimeField(self): - self.assertFormfield(models.Member, 'birthdate', widgets.AdminSplitDateTime) - - def testTimeField(self): - self.assertFormfield(models.Event, 'start_time', widgets.AdminTimeWidget) - - def testTextField(self): - self.assertFormfield(models.Event, 'description', widgets.AdminTextareaWidget) - - def testURLField(self): - self.assertFormfield(models.Event, 'link', widgets.AdminURLFieldWidget) - - def testIntegerField(self): - self.assertFormfield(models.Event, 'min_age', widgets.AdminIntegerFieldWidget) - - def testCharField(self): - self.assertFormfield(models.Member, 'name', widgets.AdminTextInputWidget) - - def testFileField(self): - self.assertFormfield(models.Album, 'cover_art', widgets.AdminFileWidget) - - def testForeignKey(self): - self.assertFormfield(models.Event, 'band', forms.Select) - - def testRawIDForeignKey(self): - self.assertFormfield(models.Event, 'band', widgets.ForeignKeyRawIdWidget, - raw_id_fields=['band']) - - def testRadioFieldsForeignKey(self): - ff = self.assertFormfield(models.Event, 'band', widgets.AdminRadioSelect, - radio_fields={'band':admin.VERTICAL}) - self.assertEqual(ff.empty_label, None) - - def testManyToMany(self): - self.assertFormfield(models.Band, 'members', forms.SelectMultiple) - - def testRawIDManyTOMany(self): - self.assertFormfield(models.Band, 'members', widgets.ManyToManyRawIdWidget, - raw_id_fields=['members']) - - def testFilteredManyToMany(self): - self.assertFormfield(models.Band, 'members', widgets.FilteredSelectMultiple, - filter_vertical=['members']) - - def testFormfieldOverrides(self): - self.assertFormfield(models.Event, 'start_date', forms.TextInput, - formfield_overrides={DateField: {'widget': forms.TextInput}}) - - def testFieldWithChoices(self): - self.assertFormfield(models.Member, 'gender', forms.Select) - - def testChoicesWithRadioFields(self): - self.assertFormfield(models.Member, 'gender', widgets.AdminRadioSelect, - radio_fields={'gender':admin.VERTICAL}) - - def testInheritance(self): - self.assertFormfield(models.Album, 'backside_art', widgets.AdminFileWidget) - - -class AdminFormfieldForDBFieldWithRequestTests(DjangoTestCase): - fixtures = ["admin-widgets-users.xml"] - - def testFilterChoicesByRequestUser(self): - """ - Ensure the user can only see their own cars in the foreign key dropdown. - """ - self.client.login(username="super", password="secret") - response = self.client.get("/widget_admin/admin_widgets/cartire/add/") - self.assert_("BMW M3" not in response.content) - self.assert_("Volkswagon Passat" in response.content) - - -class AdminForeignKeyWidgetChangeList(DjangoTestCase): - fixtures = ["admin-widgets-users.xml"] - admin_root = '/widget_admin' - - def setUp(self): - self.client.login(username="super", password="secret") - - def tearDown(self): - self.client.logout() - - def test_changelist_foreignkey(self): - response = self.client.get('%s/admin_widgets/car/' % self.admin_root) - self.assertTrue('%s/auth/user/add/' % self.admin_root in response.content) - - -class AdminForeignKeyRawIdWidget(DjangoTestCase): - fixtures = ["admin-widgets-users.xml"] - admin_root = '/widget_admin' - - def setUp(self): - self.client.login(username="super", password="secret") - - def tearDown(self): - self.client.logout() - - def test_nonexistent_target_id(self): - band = models.Band.objects.create(name='Bogey Blues') - pk = band.pk - band.delete() - post_data = { - "band": u'%s' % pk, - } - # Try posting with a non-existent pk in a raw id field: this - # should result in an error message, not a server exception. - response = self.client.post('%s/admin_widgets/event/add/' % self.admin_root, - post_data) - self.assertContains(response, - 'Select a valid choice. That choice is not one of the available choices.') - - def test_invalid_target_id(self): - - for test_str in ('Iñtërnâtiônàlizætiøn', "1234'", -1234): - # This should result in an error message, not a server exception. - response = self.client.post('%s/admin_widgets/event/add/' % self.admin_root, - {"band": test_str}) - - self.assertContains(response, - 'Select a valid choice. That choice is not one of the available choices.') - - -class FilteredSelectMultipleWidgetTest(TestCase): - def test_render(self): - w = FilteredSelectMultiple('test', False) - self.assertEqual( - conditional_escape(w.render('test', 'test')), - '<select multiple="multiple" name="test" class="selectfilter">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 0, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX} - ) - - def test_stacked_render(self): - w = FilteredSelectMultiple('test', True) - self.assertEqual( - conditional_escape(w.render('test', 'test')), - '<select multiple="multiple" name="test" class="selectfilterstacked">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 1, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX} - ) - - -class AdminSplitDateTimeWidgetTest(TestCase): - def test_render(self): - w = AdminSplitDateTime() - self.assertEqual( - conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))), - '<p class="datetime">Date: <input value="2007-12-01" type="text" class="vDateField" name="test_0" size="10" /><br />Time: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>', - ) - - def test_localization(self): - w = AdminSplitDateTime() - - activate('de-at') - old_USE_L10N = settings.USE_L10N - settings.USE_L10N = True - w.is_localized = True - self.assertEqual( - conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))), - '<p class="datetime">Datum: <input value="01.12.2007" type="text" class="vDateField" name="test_0" size="10" /><br />Zeit: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>', - ) - deactivate() - settings.USE_L10N = old_USE_L10N - - -class AdminFileWidgetTest(DjangoTestCase): - def test_render(self): - band = models.Band.objects.create(name='Linkin Park') - album = band.album_set.create( - name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg' - ) - - w = AdminFileWidget() - self.assertEqual( - conditional_escape(w.render('test', album.cover_art)), - 'Currently: <a target="_blank" href="%(STORAGE_URL)salbums/hybrid_theory.jpg">albums\hybrid_theory.jpg</a> <br />Change: <input type="file" name="test" />' % {'STORAGE_URL': default_storage.url('')}, - ) - - self.assertEqual( - conditional_escape(w.render('test', SimpleUploadedFile('test', 'content'))), - '<input type="file" name="test" />', - ) - - -class ForeignKeyRawIdWidgetTest(DjangoTestCase): - def test_render(self): - band = models.Band.objects.create(name='Linkin Park') - band.album_set.create( - name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg' - ) - rel = models.Album._meta.get_field('band').rel - - w = ForeignKeyRawIdWidget(rel) - self.assertEqual( - conditional_escape(w.render('test', band.pk, attrs={})), - '<input type="text" name="test" value="%(bandpk)s" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/band/?t=id" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a> <strong>Linkin Park</strong>' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "bandpk": band.pk}, - ) - - def test_relations_to_non_primary_key(self): - # Check that ForeignKeyRawIdWidget works with fields which aren't - # related to the model's primary key. - apple = models.Inventory.objects.create(barcode=86, name='Apple') - models.Inventory.objects.create(barcode=22, name='Pear') - core = models.Inventory.objects.create( - barcode=87, name='Core', parent=apple - ) - rel = models.Inventory._meta.get_field('parent').rel - w = ForeignKeyRawIdWidget(rel) - self.assertEqual( - w.render('test', core.parent_id, attrs={}), - '<input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a> <strong>Apple</strong>' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX}, - ) - - - def test_proper_manager_for_label_lookup(self): - # see #9258 - rel = models.Inventory._meta.get_field('parent').rel - w = ForeignKeyRawIdWidget(rel) - - hidden = models.Inventory.objects.create( - barcode=93, name='Hidden', hidden=True - ) - child_of_hidden = models.Inventory.objects.create( - barcode=94, name='Child of hidden', parent=hidden - ) - self.assertEqual( - w.render('test', child_of_hidden.parent_id, attrs={}), - '<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a> <strong>Hidden</strong>' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX}, - ) - - -class ManyToManyRawIdWidgetTest(DjangoTestCase): - def test_render(self): - band = models.Band.objects.create(name='Linkin Park') - band.album_set.create( - name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg' - ) - - m1 = models.Member.objects.create(name='Chester') - m2 = models.Member.objects.create(name='Mike') - band.members.add(m1, m2) - rel = models.Band._meta.get_field('members').rel - - w = ManyToManyRawIdWidget(rel) - self.assertEqual( - conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})), - '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "m1pk": m1.pk, "m2pk": m2.pk}, - ) - - self.assertEqual( - conditional_escape(w.render('test', [m1.pk])), - '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "m1pk": m1.pk}, - ) - - self.assertEqual(w._has_changed(None, None), False) - self.assertEqual(w._has_changed([], None), False) - self.assertEqual(w._has_changed(None, [u'1']), True) - self.assertEqual(w._has_changed([1, 2], [u'1', u'2']), False) - self.assertEqual(w._has_changed([1, 2], [u'1']), True) - self.assertEqual(w._has_changed([1, 2], [u'1', u'3']), True) diff --git a/parts/django/tests/regressiontests/admin_widgets/urls.py b/parts/django/tests/regressiontests/admin_widgets/urls.py deleted file mode 100644 index af73d53..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/urls.py +++ /dev/null @@ -1,7 +0,0 @@ - -from django.conf.urls.defaults import * -import widgetadmin - -urlpatterns = patterns('', - (r'^', include(widgetadmin.site.urls)), -) diff --git a/parts/django/tests/regressiontests/admin_widgets/widgetadmin.py b/parts/django/tests/regressiontests/admin_widgets/widgetadmin.py deleted file mode 100644 index 6f15d92..0000000 --- a/parts/django/tests/regressiontests/admin_widgets/widgetadmin.py +++ /dev/null @@ -1,30 +0,0 @@ -""" - -""" -from django.contrib import admin - -import models - -class WidgetAdmin(admin.AdminSite): - pass - -class CarAdmin(admin.ModelAdmin): - list_display = ['make', 'model', 'owner'] - list_editable = ['owner'] - -class CarTireAdmin(admin.ModelAdmin): - def formfield_for_foreignkey(self, db_field, request, **kwargs): - if db_field.name == "car": - kwargs["queryset"] = models.Car.objects.filter(owner=request.user) - return db_field.formfield(**kwargs) - return super(CarTireAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) - -class EventAdmin(admin.ModelAdmin): - raw_id_fields = ['band'] - -site = WidgetAdmin(name='widget-admin') - -site.register(models.User) -site.register(models.Car, CarAdmin) -site.register(models.CarTire, CarTireAdmin) -site.register(models.Event, EventAdmin) diff --git a/parts/django/tests/regressiontests/aggregation_regress/__init__.py b/parts/django/tests/regressiontests/aggregation_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/aggregation_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/aggregation_regress/fixtures/initial_data.json b/parts/django/tests/regressiontests/aggregation_regress/fixtures/initial_data.json deleted file mode 100644 index 597ac04..0000000 --- a/parts/django/tests/regressiontests/aggregation_regress/fixtures/initial_data.json +++ /dev/null @@ -1,257 +0,0 @@ -[ - { - "pk": 1, - "model": "aggregation_regress.publisher", - "fields": { - "name": "Apress", - "num_awards": 3 - } - }, - { - "pk": 2, - "model": "aggregation_regress.publisher", - "fields": { - "name": "Sams", - "num_awards": 1 - } - }, - { - "pk": 3, - "model": "aggregation_regress.publisher", - "fields": { - "name": "Prentice Hall", - "num_awards": 7 - } - }, - { - "pk": 4, - "model": "aggregation_regress.publisher", - "fields": { - "name": "Morgan Kaufmann", - "num_awards": 9 - } - }, - { - "pk": 5, - "model": "aggregation_regress.publisher", - "fields": { - "name": "Jonno's House of Books", - "num_awards": 0 - } - }, - { - "pk": 1, - "model": "aggregation_regress.book", - "fields": { - "publisher": 1, - "isbn": "159059725", - "name": "The Definitive Guide to Django: Web Development Done Right", - "price": "30.00", - "rating": 4.5, - "authors": [1, 2], - "contact": 1, - "pages": 447, - "pubdate": "2007-12-6" - } - }, - { - "pk": 2, - "model": "aggregation_regress.book", - "fields": { - "publisher": 2, - "isbn": "067232959", - "name": "Sams Teach Yourself Django in 24 Hours", - "price": "23.09", - "rating": 3.0, - "authors": [3], - "contact": 3, - "pages": 528, - "pubdate": "2008-3-3" - } - }, - { - "pk": 3, - "model": "aggregation_regress.book", - "fields": { - "publisher": 1, - "isbn": "159059996", - "name": "Practical Django Projects", - "price": "29.69", - "rating": 4.0, - "authors": [4], - "contact": 4, - "pages": 300, - "pubdate": "2008-6-23" - } - }, - { - "pk": 4, - "model": "aggregation_regress.book", - "fields": { - "publisher": 3, - "isbn": "013235613", - "name": "Python Web Development with Django", - "price": "29.69", - "rating": 4.0, - "authors": [5, 6, 7], - "contact": 5, - "pages": 350, - "pubdate": "2008-11-3" - } - }, - { - "pk": 5, - "model": "aggregation_regress.book", - "fields": { - "publisher": 3, - "isbn": "013790395", - "name": "Artificial Intelligence: A Modern Approach", - "price": "82.80", - "rating": 4.0, - "authors": [8, 9], - "contact": 8, - "pages": 1132, - "pubdate": "1995-1-15" - } - }, - { - "pk": 6, - "model": "aggregation_regress.book", - "fields": { - "publisher": 4, - "isbn": "155860191", - "name": "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", - "price": "75.00", - "rating": 5.0, - "authors": [8], - "contact": 8, - "pages": 946, - "pubdate": "1991-10-15" - } - }, - { - "pk": 1, - "model": "aggregation_regress.store", - "fields": { - "books": [1, 2, 3, 4, 5, 6], - "name": "Amazon.com", - "original_opening": "1994-4-23 9:17:42", - "friday_night_closing": "23:59:59" - } - }, - { - "pk": 2, - "model": "aggregation_regress.store", - "fields": { - "books": [1, 3, 5, 6], - "name": "Books.com", - "original_opening": "2001-3-15 11:23:37", - "friday_night_closing": "23:59:59" - } - }, - { - "pk": 3, - "model": "aggregation_regress.store", - "fields": { - "books": [3, 4, 6], - "name": "Mamma and Pappa's Books", - "original_opening": "1945-4-25 16:24:14", - "friday_night_closing": "21:30:00" - } - }, - { - "pk": 1, - "model": "aggregation_regress.author", - "fields": { - "age": 34, - "friends": [2, 4], - "name": "Adrian Holovaty" - } - }, - { - "pk": 2, - "model": "aggregation_regress.author", - "fields": { - "age": 35, - "friends": [1, 7], - "name": "Jacob Kaplan-Moss" - } - }, - { - "pk": 3, - "model": "aggregation_regress.author", - "fields": { - "age": 45, - "friends": [], - "name": "Brad Dayley" - } - }, - { - "pk": 4, - "model": "aggregation_regress.author", - "fields": { - "age": 29, - "friends": [1], - "name": "James Bennett" - } - }, - { - "pk": 5, - "model": "aggregation_regress.author", - "fields": { - "age": 37, - "friends": [6, 7], - "name": "Jeffrey Forcier" - } - }, - { - "pk": 6, - "model": "aggregation_regress.author", - "fields": { - "age": 29, - "friends": [5, 7], - "name": "Paul Bissex" - } - }, - { - "pk": 7, - "model": "aggregation_regress.author", - "fields": { - "age": 25, - "friends": [2, 5, 6], - "name": "Wesley J. Chun" - } - }, - { - "pk": 8, - "model": "aggregation_regress.author", - "fields": { - "age": 57, - "friends": [9], - "name": "Peter Norvig" - } - }, - { - "pk": 9, - "model": "aggregation_regress.author", - "fields": { - "age": 46, - "friends": [8], - "name": "Stuart Russell" - } - }, - { - "pk": 5, - "model": "aggregation_regress.hardbackbook", - "fields": { - "weight": 4.5 - } - }, - { - "pk": 6, - "model": "aggregation_regress.hardbackbook", - "fields": { - "weight": 3.7 - } - } -] diff --git a/parts/django/tests/regressiontests/aggregation_regress/models.py b/parts/django/tests/regressiontests/aggregation_regress/models.py deleted file mode 100644 index ccef9a5..0000000 --- a/parts/django/tests/regressiontests/aggregation_regress/models.py +++ /dev/null @@ -1,65 +0,0 @@ -# coding: utf-8 -from django.db import models - - -class Author(models.Model): - name = models.CharField(max_length=100) - age = models.IntegerField() - friends = models.ManyToManyField('self', blank=True) - - def __unicode__(self): - return self.name - - -class Publisher(models.Model): - name = models.CharField(max_length=255) - num_awards = models.IntegerField() - - def __unicode__(self): - return self.name - - -class Book(models.Model): - isbn = models.CharField(max_length=9) - name = models.CharField(max_length=255) - pages = models.IntegerField() - rating = models.FloatField() - price = models.DecimalField(decimal_places=2, max_digits=6) - authors = models.ManyToManyField(Author) - contact = models.ForeignKey(Author, related_name='book_contact_set') - publisher = models.ForeignKey(Publisher) - pubdate = models.DateField() - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - -class Store(models.Model): - name = models.CharField(max_length=255) - books = models.ManyToManyField(Book) - original_opening = models.DateTimeField() - friday_night_closing = models.TimeField() - - def __unicode__(self): - return self.name - -class Entries(models.Model): - EntryID = models.AutoField(primary_key=True, db_column='Entry ID') - Entry = models.CharField(unique=True, max_length=50) - Exclude = models.BooleanField() - - -class Clues(models.Model): - ID = models.AutoField(primary_key=True) - EntryID = models.ForeignKey(Entries, verbose_name='Entry', db_column = 'Entry ID') - Clue = models.CharField(max_length=150) - - -class HardbackBook(Book): - weight = models.FloatField() - - def __unicode__(self): - return "%s (hardback): %s" % (self.name, self.weight) diff --git a/parts/django/tests/regressiontests/aggregation_regress/tests.py b/parts/django/tests/regressiontests/aggregation_regress/tests.py deleted file mode 100644 index 4d5a2a0..0000000 --- a/parts/django/tests/regressiontests/aggregation_regress/tests.py +++ /dev/null @@ -1,757 +0,0 @@ -import datetime -import pickle -from decimal import Decimal -from operator import attrgetter - -from django.conf import settings -from django.core.exceptions import FieldError -from django.db import DEFAULT_DB_ALIAS -from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F -from django.test import TestCase, Approximate - -from models import Author, Book, Publisher, Clues, Entries, HardbackBook - - -def run_stddev_tests(): - """Check to see if StdDev/Variance tests should be run. - - Stddev and Variance are not guaranteed to be available for SQLite, and - are not available for PostgreSQL before 8.2. - """ - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.sqlite3': - return False - - class StdDevPop(object): - sql_function = 'STDDEV_POP' - - try: - connection.ops.check_aggregate_support(StdDevPop()) - except: - return False - return True - - -class AggregationTests(TestCase): - def assertObjectAttrs(self, obj, **kwargs): - for attr, value in kwargs.iteritems(): - self.assertEqual(getattr(obj, attr), value) - - def test_aggregates_in_where_clause(self): - """ - Regression test for #12822: DatabaseError: aggregates not allowed in - WHERE clause - - Tests that the subselect works and returns results equivalent to a - query with the IDs listed. - - Before the corresponding fix for this bug, this test passed in 1.1 and - failed in 1.2-beta (trunk). - """ - qs = Book.objects.values('contact').annotate(Max('id')) - qs = qs.order_by('contact').values_list('id__max', flat=True) - # don't do anything with the queryset (qs) before including it as a - # subquery - books = Book.objects.order_by('id') - qs1 = books.filter(id__in=qs) - qs2 = books.filter(id__in=list(qs)) - self.assertEqual(list(qs1), list(qs2)) - - def test_aggregates_in_where_clause_pre_eval(self): - """ - Regression test for #12822: DatabaseError: aggregates not allowed in - WHERE clause - - Same as the above test, but evaluates the queryset for the subquery - before it's used as a subquery. - - Before the corresponding fix for this bug, this test failed in both - 1.1 and 1.2-beta (trunk). - """ - qs = Book.objects.values('contact').annotate(Max('id')) - qs = qs.order_by('contact').values_list('id__max', flat=True) - # force the queryset (qs) for the subquery to be evaluated in its - # current state - list(qs) - books = Book.objects.order_by('id') - qs1 = books.filter(id__in=qs) - qs2 = books.filter(id__in=list(qs)) - self.assertEqual(list(qs1), list(qs2)) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': - def test_annotate_with_extra(self): - """ - Regression test for #11916: Extra params + aggregation creates - incorrect SQL. - """ - #oracle doesn't support subqueries in group by clause - shortest_book_sql = """ - SELECT name - FROM aggregation_regress_book b - WHERE b.publisher_id = aggregation_regress_publisher.id - ORDER BY b.pages - LIMIT 1 - """ - # tests that this query does not raise a DatabaseError due to the full - # subselect being (erroneously) added to the GROUP BY parameters - qs = Publisher.objects.extra(select={ - 'name_of_shortest_book': shortest_book_sql, - }).annotate(total_books=Count('book')) - # force execution of the query - list(qs) - - def test_aggregate(self): - # Ordering requests are ignored - self.assertEqual( - Author.objects.order_by("name").aggregate(Avg("age")), - {"age__avg": Approximate(37.444, places=1)} - ) - - # Implicit ordering is also ignored - self.assertEqual( - Book.objects.aggregate(Sum("pages")), - {"pages__sum": 3703}, - ) - - # Baseline results - self.assertEqual( - Book.objects.aggregate(Sum('pages'), Avg('pages')), - {'pages__sum': 3703, 'pages__avg': Approximate(617.166, places=2)} - ) - - # Empty values query doesn't affect grouping or results - self.assertEqual( - Book.objects.values().aggregate(Sum('pages'), Avg('pages')), - {'pages__sum': 3703, 'pages__avg': Approximate(617.166, places=2)} - ) - - # Aggregate overrides extra selected column - self.assertEqual( - Book.objects.extra(select={'price_per_page' : 'price / pages'}).aggregate(Sum('pages')), - {'pages__sum': 3703} - ) - - def test_annotation(self): - # Annotations get combined with extra select clauses - obj = Book.objects.annotate(mean_auth_age=Avg("authors__age")).extra(select={"manufacture_cost": "price * .5"}).get(pk=2) - self.assertObjectAttrs(obj, - contact_id=3, - id=2, - isbn=u'067232959', - mean_auth_age=45.0, - name='Sams Teach Yourself Django in 24 Hours', - pages=528, - price=Decimal("23.09"), - pubdate=datetime.date(2008, 3, 3), - publisher_id=2, - rating=3.0 - ) - # Different DB backends return different types for the extra select computation - self.assertTrue(obj.manufacture_cost == 11.545 or obj.manufacture_cost == Decimal('11.545')) - - # Order of the annotate/extra in the query doesn't matter - obj = Book.objects.extra(select={'manufacture_cost' : 'price * .5'}).annotate(mean_auth_age=Avg('authors__age')).get(pk=2) - self.assertObjectAttrs(obj, - contact_id=3, - id=2, - isbn=u'067232959', - mean_auth_age=45.0, - name=u'Sams Teach Yourself Django in 24 Hours', - pages=528, - price=Decimal("23.09"), - pubdate=datetime.date(2008, 3, 3), - publisher_id=2, - rating=3.0 - ) - # Different DB backends return different types for the extra select computation - self.assertTrue(obj.manufacture_cost == 11.545 or obj.manufacture_cost == Decimal('11.545')) - - # Values queries can be combined with annotate and extra - obj = Book.objects.annotate(mean_auth_age=Avg('authors__age')).extra(select={'manufacture_cost' : 'price * .5'}).values().get(pk=2) - manufacture_cost = obj['manufacture_cost'] - self.assertTrue(manufacture_cost == 11.545 or manufacture_cost == Decimal('11.545')) - del obj['manufacture_cost'] - self.assertEqual(obj, { - "contact_id": 3, - "id": 2, - "isbn": u"067232959", - "mean_auth_age": 45.0, - "name": u"Sams Teach Yourself Django in 24 Hours", - "pages": 528, - "price": Decimal("23.09"), - "pubdate": datetime.date(2008, 3, 3), - "publisher_id": 2, - "rating": 3.0, - }) - - # The order of the (empty) values, annotate and extra clauses doesn't - # matter - obj = Book.objects.values().annotate(mean_auth_age=Avg('authors__age')).extra(select={'manufacture_cost' : 'price * .5'}).get(pk=2) - manufacture_cost = obj['manufacture_cost'] - self.assertTrue(manufacture_cost == 11.545 or manufacture_cost == Decimal('11.545')) - del obj['manufacture_cost'] - self.assertEqual(obj, { - 'contact_id': 3, - 'id': 2, - 'isbn': u'067232959', - 'mean_auth_age': 45.0, - 'name': u'Sams Teach Yourself Django in 24 Hours', - 'pages': 528, - 'price': Decimal("23.09"), - 'pubdate': datetime.date(2008, 3, 3), - 'publisher_id': 2, - 'rating': 3.0 - }) - - # If the annotation precedes the values clause, it won't be included - # unless it is explicitly named - obj = Book.objects.annotate(mean_auth_age=Avg('authors__age')).extra(select={'price_per_page' : 'price / pages'}).values('name').get(pk=1) - self.assertEqual(obj, { - "name": u'The Definitive Guide to Django: Web Development Done Right', - }) - - obj = Book.objects.annotate(mean_auth_age=Avg('authors__age')).extra(select={'price_per_page' : 'price / pages'}).values('name','mean_auth_age').get(pk=1) - self.assertEqual(obj, { - 'mean_auth_age': 34.5, - 'name': u'The Definitive Guide to Django: Web Development Done Right', - }) - - # If an annotation isn't included in the values, it can still be used - # in a filter - qs = Book.objects.annotate(n_authors=Count('authors')).values('name').filter(n_authors__gt=2) - self.assertQuerysetEqual( - qs, [ - {"name": u'Python Web Development with Django'} - ], - lambda b: b, - ) - - # The annotations are added to values output if values() precedes - # annotate() - obj = Book.objects.values('name').annotate(mean_auth_age=Avg('authors__age')).extra(select={'price_per_page' : 'price / pages'}).get(pk=1) - self.assertEqual(obj, { - 'mean_auth_age': 34.5, - 'name': u'The Definitive Guide to Django: Web Development Done Right', - }) - - # Check that all of the objects are getting counted (allow_nulls) and - # that values respects the amount of objects - self.assertEqual( - len(Author.objects.annotate(Avg('friends__age')).values()), - 9 - ) - - # Check that consecutive calls to annotate accumulate in the query - qs = Book.objects.values('price').annotate(oldest=Max('authors__age')).order_by('oldest', 'price').annotate(Max('publisher__num_awards')) - self.assertQuerysetEqual( - qs, [ - {'price': Decimal("30"), 'oldest': 35, 'publisher__num_awards__max': 3}, - {'price': Decimal("29.69"), 'oldest': 37, 'publisher__num_awards__max': 7}, - {'price': Decimal("23.09"), 'oldest': 45, 'publisher__num_awards__max': 1}, - {'price': Decimal("75"), 'oldest': 57, 'publisher__num_awards__max': 9}, - {'price': Decimal("82.8"), 'oldest': 57, 'publisher__num_awards__max': 7} - ], - lambda b: b, - ) - - def test_aggrate_annotation(self): - # Aggregates can be composed over annotations. - # The return type is derived from the composed aggregate - vals = Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('pages'), Max('price'), Sum('num_authors'), Avg('num_authors')) - self.assertEqual(vals, { - 'num_authors__sum': 10, - 'num_authors__avg': Approximate(1.666, places=2), - 'pages__max': 1132, - 'price__max': Decimal("82.80") - }) - - def test_field_error(self): - # Bad field requests in aggregates are caught and reported - self.assertRaises( - FieldError, - lambda: Book.objects.all().aggregate(num_authors=Count('foo')) - ) - - self.assertRaises( - FieldError, - lambda: Book.objects.all().annotate(num_authors=Count('foo')) - ) - - self.assertRaises( - FieldError, - lambda: Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo')) - ) - - def test_more(self): - # Old-style count aggregations can be mixed with new-style - self.assertEqual( - Book.objects.annotate(num_authors=Count('authors')).count(), - 6 - ) - - # Non-ordinal, non-computed Aggregates over annotations correctly - # inherit the annotation's internal type if the annotation is ordinal - # or computed - vals = Book.objects.annotate(num_authors=Count('authors')).aggregate(Max('num_authors')) - self.assertEqual( - vals, - {'num_authors__max': 3} - ) - - vals = Publisher.objects.annotate(avg_price=Avg('book__price')).aggregate(Max('avg_price')) - self.assertEqual( - vals, - {'avg_price__max': 75.0} - ) - - # Aliases are quoted to protected aliases that might be reserved names - vals = Book.objects.aggregate(number=Max('pages'), select=Max('pages')) - self.assertEqual( - vals, - {'number': 1132, 'select': 1132} - ) - - # Regression for #10064: select_related() plays nice with aggregates - obj = Book.objects.select_related('publisher').annotate(num_authors=Count('authors')).values()[0] - self.assertEqual(obj, { - 'contact_id': 8, - 'id': 5, - 'isbn': u'013790395', - 'name': u'Artificial Intelligence: A Modern Approach', - 'num_authors': 2, - 'pages': 1132, - 'price': Decimal("82.8"), - 'pubdate': datetime.date(1995, 1, 15), - 'publisher_id': 3, - 'rating': 4.0, - }) - - # Regression for #10010: exclude on an aggregate field is correctly - # negated - self.assertEqual( - len(Book.objects.annotate(num_authors=Count('authors'))), - 6 - ) - self.assertEqual( - len(Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=2)), - 1 - ) - self.assertEqual( - len(Book.objects.annotate(num_authors=Count('authors')).exclude(num_authors__gt=2)), - 5 - ) - - self.assertEqual( - len(Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__lt=3).exclude(num_authors__lt=2)), - 2 - ) - self.assertEqual( - len(Book.objects.annotate(num_authors=Count('authors')).exclude(num_authors__lt=2).filter(num_authors__lt=3)), - 2 - ) - - def test_aggregate_fexpr(self): - # Aggregates can be used with F() expressions - # ... where the F() is pushed into the HAVING clause - qs = Publisher.objects.annotate(num_books=Count('book')).filter(num_books__lt=F('num_awards')/2).order_by('name').values('name','num_books','num_awards') - self.assertQuerysetEqual( - qs, [ - {'num_books': 1, 'name': u'Morgan Kaufmann', 'num_awards': 9}, - {'num_books': 2, 'name': u'Prentice Hall', 'num_awards': 7} - ], - lambda p: p, - ) - - qs = Publisher.objects.annotate(num_books=Count('book')).exclude(num_books__lt=F('num_awards')/2).order_by('name').values('name','num_books','num_awards') - self.assertQuerysetEqual( - qs, [ - {'num_books': 2, 'name': u'Apress', 'num_awards': 3}, - {'num_books': 0, 'name': u"Jonno's House of Books", 'num_awards': 0}, - {'num_books': 1, 'name': u'Sams', 'num_awards': 1} - ], - lambda p: p, - ) - - # ... and where the F() references an aggregate - qs = Publisher.objects.annotate(num_books=Count('book')).filter(num_awards__gt=2*F('num_books')).order_by('name').values('name','num_books','num_awards') - self.assertQuerysetEqual( - qs, [ - {'num_books': 1, 'name': u'Morgan Kaufmann', 'num_awards': 9}, - {'num_books': 2, 'name': u'Prentice Hall', 'num_awards': 7} - ], - lambda p: p, - ) - - qs = Publisher.objects.annotate(num_books=Count('book')).exclude(num_books__lt=F('num_awards')/2).order_by('name').values('name','num_books','num_awards') - self.assertQuerysetEqual( - qs, [ - {'num_books': 2, 'name': u'Apress', 'num_awards': 3}, - {'num_books': 0, 'name': u"Jonno's House of Books", 'num_awards': 0}, - {'num_books': 1, 'name': u'Sams', 'num_awards': 1} - ], - lambda p: p, - ) - - def test_db_col_table(self): - # Tests on fields with non-default table and column names. - qs = Clues.objects.values('EntryID__Entry').annotate(Appearances=Count('EntryID'), Distinct_Clues=Count('Clue', distinct=True)) - self.assertQuerysetEqual(qs, []) - - qs = Entries.objects.annotate(clue_count=Count('clues__ID')) - self.assertQuerysetEqual(qs, []) - - def test_empty(self): - # Regression for #10089: Check handling of empty result sets with - # aggregates - self.assertEqual( - Book.objects.filter(id__in=[]).count(), - 0 - ) - - vals = Book.objects.filter(id__in=[]).aggregate(num_authors=Count('authors'), avg_authors=Avg('authors'), max_authors=Max('authors'), max_price=Max('price'), max_rating=Max('rating')) - self.assertEqual( - vals, - {'max_authors': None, 'max_rating': None, 'num_authors': 0, 'avg_authors': None, 'max_price': None} - ) - - qs = Publisher.objects.filter(pk=5).annotate(num_authors=Count('book__authors'), avg_authors=Avg('book__authors'), max_authors=Max('book__authors'), max_price=Max('book__price'), max_rating=Max('book__rating')).values() - self.assertQuerysetEqual( - qs, [ - {'max_authors': None, 'name': u"Jonno's House of Books", 'num_awards': 0, 'max_price': None, 'num_authors': 0, 'max_rating': None, 'id': 5, 'avg_authors': None} - ], - lambda p: p - ) - - def test_more_more(self): - # Regression for #10113 - Fields mentioned in order_by() must be - # included in the GROUP BY. This only becomes a problem when the - # order_by introduces a new join. - self.assertQuerysetEqual( - Book.objects.annotate(num_authors=Count('authors')).order_by('publisher__name', 'name'), [ - "Practical Django Projects", - "The Definitive Guide to Django: Web Development Done Right", - "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", - "Artificial Intelligence: A Modern Approach", - "Python Web Development with Django", - "Sams Teach Yourself Django in 24 Hours", - ], - lambda b: b.name - ) - - # Regression for #10127 - Empty select_related() works with annotate - qs = Book.objects.filter(rating__lt=4.5).select_related().annotate(Avg('authors__age')) - self.assertQuerysetEqual( - qs, [ - (u'Artificial Intelligence: A Modern Approach', 51.5, u'Prentice Hall', u'Peter Norvig'), - (u'Practical Django Projects', 29.0, u'Apress', u'James Bennett'), - (u'Python Web Development with Django', Approximate(30.333, places=2), u'Prentice Hall', u'Jeffrey Forcier'), - (u'Sams Teach Yourself Django in 24 Hours', 45.0, u'Sams', u'Brad Dayley') - ], - lambda b: (b.name, b.authors__age__avg, b.publisher.name, b.contact.name) - ) - - # Regression for #10132 - If the values() clause only mentioned extra - # (select=) columns, those columns are used for grouping - qs = Book.objects.extra(select={'pub':'publisher_id'}).values('pub').annotate(Count('id')).order_by('pub') - self.assertQuerysetEqual( - qs, [ - {'pub': 1, 'id__count': 2}, - {'pub': 2, 'id__count': 1}, - {'pub': 3, 'id__count': 2}, - {'pub': 4, 'id__count': 1} - ], - lambda b: b - ) - - qs = Book.objects.extra(select={'pub':'publisher_id', 'foo':'pages'}).values('pub').annotate(Count('id')).order_by('pub') - self.assertQuerysetEqual( - qs, [ - {'pub': 1, 'id__count': 2}, - {'pub': 2, 'id__count': 1}, - {'pub': 3, 'id__count': 2}, - {'pub': 4, 'id__count': 1} - ], - lambda b: b - ) - - # Regression for #10182 - Queries with aggregate calls are correctly - # realiased when used in a subquery - ids = Book.objects.filter(pages__gt=100).annotate(n_authors=Count('authors')).filter(n_authors__gt=2).order_by('n_authors') - self.assertQuerysetEqual( - Book.objects.filter(id__in=ids), [ - "Python Web Development with Django", - ], - lambda b: b.name - ) - - def test_duplicate_alias(self): - # Regression for #11256 - duplicating a default alias raises ValueError. - self.assertRaises(ValueError, Book.objects.all().annotate, Avg('authors__age'), authors__age__avg=Avg('authors__age')) - - def test_field_name_conflict(self): - # Regression for #11256 - providing an aggregate name that conflicts with a field name on the model raises ValueError - self.assertRaises(ValueError, Author.objects.annotate, age=Avg('friends__age')) - - def test_m2m_name_conflict(self): - # Regression for #11256 - providing an aggregate name that conflicts with an m2m name on the model raises ValueError - self.assertRaises(ValueError, Author.objects.annotate, friends=Count('friends')) - - def test_reverse_relation_name_conflict(self): - # Regression for #11256 - providing an aggregate name that conflicts with a reverse-related name on the model raises ValueError - self.assertRaises(ValueError, Author.objects.annotate, book_contact_set=Avg('friends__age')) - - def test_pickle(self): - # Regression for #10197 -- Queries with aggregates can be pickled. - # First check that pickling is possible at all. No crash = success - qs = Book.objects.annotate(num_authors=Count('authors')) - pickle.dumps(qs) - - # Then check that the round trip works. - query = qs.query.get_compiler(qs.db).as_sql()[0] - qs2 = pickle.loads(pickle.dumps(qs)) - self.assertEqual( - qs2.query.get_compiler(qs2.db).as_sql()[0], - query, - ) - - def test_more_more_more(self): - # Regression for #10199 - Aggregate calls clone the original query so - # the original query can still be used - books = Book.objects.all() - books.aggregate(Avg("authors__age")) - self.assertQuerysetEqual( - books.all(), [ - u'Artificial Intelligence: A Modern Approach', - u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', - u'Practical Django Projects', - u'Python Web Development with Django', - u'Sams Teach Yourself Django in 24 Hours', - u'The Definitive Guide to Django: Web Development Done Right' - ], - lambda b: b.name - ) - - # Regression for #10248 - Annotations work with DateQuerySets - qs = Book.objects.annotate(num_authors=Count('authors')).filter(num_authors=2).dates('pubdate', 'day') - self.assertQuerysetEqual( - qs, [ - datetime.datetime(1995, 1, 15, 0, 0), - datetime.datetime(2007, 12, 6, 0, 0) - ], - lambda b: b - ) - - # Regression for #10290 - extra selects with parameters can be used for - # grouping. - qs = Book.objects.annotate(mean_auth_age=Avg('authors__age')).extra(select={'sheets' : '(pages + %s) / %s'}, select_params=[1, 2]).order_by('sheets').values('sheets') - self.assertQuerysetEqual( - qs, [ - 150, - 175, - 224, - 264, - 473, - 566 - ], - lambda b: int(b["sheets"]) - ) - - # Regression for 10425 - annotations don't get in the way of a count() - # clause - self.assertEqual( - Book.objects.values('publisher').annotate(Count('publisher')).count(), - 4 - ) - self.assertEqual( - Book.objects.annotate(Count('publisher')).values('publisher').count(), - 6 - ) - - publishers = Publisher.objects.filter(id__in=[1, 2]) - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Sams" - ], - lambda p: p.name - ) - - publishers = publishers.annotate(n_books=Count("book")) - self.assertEqual( - publishers[0].n_books, - 2 - ) - - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Sams", - ], - lambda p: p.name - ) - - books = Book.objects.filter(publisher__in=publishers) - self.assertQuerysetEqual( - books, [ - "Practical Django Projects", - "Sams Teach Yourself Django in 24 Hours", - "The Definitive Guide to Django: Web Development Done Right", - ], - lambda b: b.name - ) - self.assertQuerysetEqual( - publishers, [ - "Apress", - "Sams", - ], - lambda p: p.name - ) - - # Regression for 10666 - inherited fields work with annotations and - # aggregations - self.assertEqual( - HardbackBook.objects.aggregate(n_pages=Sum('book_ptr__pages')), - {'n_pages': 2078} - ) - - self.assertEqual( - HardbackBook.objects.aggregate(n_pages=Sum('pages')), - {'n_pages': 2078}, - ) - - qs = HardbackBook.objects.annotate(n_authors=Count('book_ptr__authors')).values('name', 'n_authors') - self.assertQuerysetEqual( - qs, [ - {'n_authors': 2, 'name': u'Artificial Intelligence: A Modern Approach'}, - {'n_authors': 1, 'name': u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp'} - ], - lambda h: h - ) - - qs = HardbackBook.objects.annotate(n_authors=Count('authors')).values('name', 'n_authors') - self.assertQuerysetEqual( - qs, [ - {'n_authors': 2, 'name': u'Artificial Intelligence: A Modern Approach'}, - {'n_authors': 1, 'name': u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp'} - ], - lambda h: h, - ) - - # Regression for #10766 - Shouldn't be able to reference an aggregate - # fields in an an aggregate() call. - self.assertRaises( - FieldError, - lambda: Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age')) - ) - - def test_empty_filter_count(self): - self.assertEqual( - Author.objects.filter(id__in=[]).annotate(Count("friends")).count(), - 0 - ) - - def test_empty_filter_aggregate(self): - self.assertEqual( - Author.objects.filter(id__in=[]).annotate(Count("friends")).aggregate(Count("pk")), - {"pk__count": None} - ) - - def test_annotate_and_join(self): - self.assertEqual( - Author.objects.annotate(c=Count("friends__name")).exclude(friends__name="Joe").count(), - Author.objects.count() - ) - - def test_f_expression_annotation(self): - # Books with less than 200 pages per author. - qs = Book.objects.values("name").annotate( - n_authors=Count("authors") - ).filter( - pages__lt=F("n_authors") * 200 - ).values_list("pk") - self.assertQuerysetEqual( - Book.objects.filter(pk__in=qs), [ - "Python Web Development with Django" - ], - attrgetter("name") - ) - - def test_values_annotate_values(self): - qs = Book.objects.values("name").annotate( - n_authors=Count("authors") - ).values_list("pk", flat=True) - self.assertEqual(list(qs), list(Book.objects.values_list("pk", flat=True))) - - def test_having_group_by(self): - # Test that when a field occurs on the LHS of a HAVING clause that it - # appears correctly in the GROUP BY clause - qs = Book.objects.values_list("name").annotate( - n_authors=Count("authors") - ).filter( - pages__gt=F("n_authors") - ).values_list("name", flat=True) - # Results should be the same, all Books have more pages than authors - self.assertEqual( - list(qs), list(Book.objects.values_list("name", flat=True)) - ) - - if run_stddev_tests(): - def test_stddev(self): - self.assertEqual( - Book.objects.aggregate(StdDev('pages')), - {'pages__stddev': Approximate(311.46, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(StdDev('rating')), - {'rating__stddev': Approximate(0.60, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(StdDev('price')), - {'price__stddev': Approximate(24.16, 2)} - ) - - self.assertEqual( - Book.objects.aggregate(StdDev('pages', sample=True)), - {'pages__stddev': Approximate(341.19, 2)} - ) - - self.assertEqual( - Book.objects.aggregate(StdDev('rating', sample=True)), - {'rating__stddev': Approximate(0.66, 2)} - ) - - self.assertEqual( - Book.objects.aggregate(StdDev('price', sample=True)), - {'price__stddev': Approximate(26.46, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('pages')), - {'pages__variance': Approximate(97010.80, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('rating')), - {'rating__variance': Approximate(0.36, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('price')), - {'price__variance': Approximate(583.77, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('pages', sample=True)), - {'pages__variance': Approximate(116412.96, 1)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('rating', sample=True)), - {'rating__variance': Approximate(0.44, 2)} - ) - - self.assertEqual( - Book.objects.aggregate(Variance('price', sample=True)), - {'price__variance': Approximate(700.53, 2)} - ) diff --git a/parts/django/tests/regressiontests/app_loading/__init__.py b/parts/django/tests/regressiontests/app_loading/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/eggs/brokenapp.egg b/parts/django/tests/regressiontests/app_loading/eggs/brokenapp.egg Binary files differdeleted file mode 100755 index 8aca671..0000000 --- a/parts/django/tests/regressiontests/app_loading/eggs/brokenapp.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/eggs/modelapp.egg b/parts/django/tests/regressiontests/app_loading/eggs/modelapp.egg Binary files differdeleted file mode 100755 index c2370b5..0000000 --- a/parts/django/tests/regressiontests/app_loading/eggs/modelapp.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/eggs/nomodelapp.egg b/parts/django/tests/regressiontests/app_loading/eggs/nomodelapp.egg Binary files differdeleted file mode 100755 index 5b8d217..0000000 --- a/parts/django/tests/regressiontests/app_loading/eggs/nomodelapp.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/eggs/omelet.egg b/parts/django/tests/regressiontests/app_loading/eggs/omelet.egg Binary files differdeleted file mode 100755 index bd1c687..0000000 --- a/parts/django/tests/regressiontests/app_loading/eggs/omelet.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/models.py b/parts/django/tests/regressiontests/app_loading/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/parent/__init__.py b/parts/django/tests/regressiontests/app_loading/parent/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/parent/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/parent/app/__init__.py b/parts/django/tests/regressiontests/app_loading/parent/app/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/parent/app/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/parent/app1/__init__.py b/parts/django/tests/regressiontests/app_loading/parent/app1/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/parent/app1/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/parent/app_2/__init__.py b/parts/django/tests/regressiontests/app_loading/parent/app_2/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/app_loading/parent/app_2/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/app_loading/test_settings.py b/parts/django/tests/regressiontests/app_loading/test_settings.py deleted file mode 100644 index e956311..0000000 --- a/parts/django/tests/regressiontests/app_loading/test_settings.py +++ /dev/null @@ -1,3 +0,0 @@ -INSTALLED_APPS = ( - 'parent.*', -) diff --git a/parts/django/tests/regressiontests/app_loading/tests.py b/parts/django/tests/regressiontests/app_loading/tests.py deleted file mode 100644 index 4fb60b2..0000000 --- a/parts/django/tests/regressiontests/app_loading/tests.py +++ /dev/null @@ -1,83 +0,0 @@ -import copy -import os -import sys -import time -from unittest import TestCase - -from django.conf import Settings -from django.db.models.loading import cache, load_app - - -class InstalledAppsGlobbingTest(TestCase): - def setUp(self): - self.OLD_SYS_PATH = sys.path[:] - sys.path.append(os.path.dirname(os.path.abspath(__file__))) - self.OLD_TZ = os.environ.get("TZ") - - def test_globbing(self): - settings = Settings('test_settings') - self.assertEquals(settings.INSTALLED_APPS, ['parent.app', 'parent.app1', 'parent.app_2']) - - def tearDown(self): - sys.path = self.OLD_SYS_PATH - if hasattr(time, "tzset") and self.OLD_TZ: - os.environ["TZ"] = self.OLD_TZ - time.tzset() - - -class EggLoadingTest(TestCase): - - def setUp(self): - self.old_path = sys.path[:] - self.egg_dir = '%s/eggs' % os.path.dirname(__file__) - - # This test adds dummy applications to the app cache. These - # need to be removed in order to prevent bad interactions - # with the flush operation in other tests. - self.old_app_models = copy.deepcopy(cache.app_models) - self.old_app_store = copy.deepcopy(cache.app_store) - - def tearDown(self): - sys.path = self.old_path - cache.app_models = self.old_app_models - cache.app_store = self.old_app_store - - def test_egg1(self): - """Models module can be loaded from an app in an egg""" - egg_name = '%s/modelapp.egg' % self.egg_dir - sys.path.append(egg_name) - models = load_app('app_with_models') - self.assertFalse(models is None) - - def test_egg2(self): - """Loading an app from an egg that has no models returns no models (and no error)""" - egg_name = '%s/nomodelapp.egg' % self.egg_dir - sys.path.append(egg_name) - models = load_app('app_no_models') - self.assertTrue(models is None) - - def test_egg3(self): - """Models module can be loaded from an app located under an egg's top-level package""" - egg_name = '%s/omelet.egg' % self.egg_dir - sys.path.append(egg_name) - models = load_app('omelet.app_with_models') - self.assertFalse(models is None) - - def test_egg4(self): - """Loading an app with no models from under the top-level egg package generates no error""" - egg_name = '%s/omelet.egg' % self.egg_dir - sys.path.append(egg_name) - models = load_app('omelet.app_no_models') - self.assertTrue(models is None) - - def test_egg5(self): - """Loading an app from an egg that has an import error in its models module raises that error""" - egg_name = '%s/brokenapp.egg' % self.egg_dir - sys.path.append(egg_name) - self.assertRaises(ImportError, load_app, 'broken_app') - try: - load_app('broken_app') - except ImportError, e: - # Make sure the message is indicating the actual - # problem in the broken app. - self.assertTrue("modelz" in e.args[0]) diff --git a/parts/django/tests/regressiontests/backends/__init__.py b/parts/django/tests/regressiontests/backends/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/backends/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/backends/models.py b/parts/django/tests/regressiontests/backends/models.py deleted file mode 100644 index ea7ff96..0000000 --- a/parts/django/tests/regressiontests/backends/models.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.db import models - -class Square(models.Model): - root = models.IntegerField() - square = models.PositiveIntegerField() - - def __unicode__(self): - return "%s ** 2 == %s" % (self.root, self.square) - -class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=20) - - def __unicode__(self): - return u'%s %s' % (self.first_name, self.last_name) - -class SchoolClass(models.Model): - year = models.PositiveIntegerField() - day = models.CharField(max_length=9, blank=True) - last_updated = models.DateTimeField() - - -class Reporter(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - reporter = models.ForeignKey(Reporter) - - def __unicode__(self): - return self.headline diff --git a/parts/django/tests/regressiontests/backends/tests.py b/parts/django/tests/regressiontests/backends/tests.py deleted file mode 100644 index 10cec89..0000000 --- a/parts/django/tests/regressiontests/backends/tests.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- coding: utf-8 -*- -# Unit and doctests for specific database backends. -import datetime -import unittest - -from django.conf import settings -from django.db import backend, connection, DEFAULT_DB_ALIAS, IntegrityError -from django.db.backends.signals import connection_created -from django.db.backends.postgresql import version as pg_version -from django.test import TestCase, TransactionTestCase - -import models - -class OracleChecks(unittest.TestCase): - - def test_dbms_session(self): - # If the backend is Oracle, test that we can call a standard - # stored procedure through our cursor wrapper. - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - convert_unicode = backend.convert_unicode - cursor = connection.cursor() - cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'), - [convert_unicode('_django_testing!'),]) - return True - else: - return True - - def test_cursor_var(self): - # If the backend is Oracle, test that we can pass cursor variables - # as query parameters. - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - cursor = connection.cursor() - var = cursor.var(backend.Database.STRING) - cursor.execute("BEGIN %s := 'X'; END; ", [var]) - self.assertEqual(var.getvalue(), 'X') - - def test_long_string(self): - # If the backend is Oracle, test that we can save a text longer - # than 4000 chars and read it properly - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - c = connection.cursor() - c.execute('CREATE TABLE ltext ("TEXT" NCLOB)') - long_str = ''.join([unicode(x) for x in xrange(4000)]) - c.execute('INSERT INTO ltext VALUES (%s)',[long_str]) - c.execute('SELECT text FROM ltext') - row = c.fetchone() - self.assertEquals(long_str, row[0].read()) - c.execute('DROP TABLE ltext') - - def test_client_encoding(self): - # If the backend is Oracle, test that the client encoding is set - # correctly. This was broken under Cygwin prior to r14781. - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - c = connection.cursor() # Ensure the connection is initialized. - self.assertEqual(connection.connection.encoding, "UTF-8") - self.assertEqual(connection.connection.nencoding, "UTF-8") - -class DateQuotingTest(TestCase): - - def test_django_date_trunc(self): - """ - Test the custom ``django_date_trunc method``, in particular against - fields which clash with strings passed to it (e.g. 'year') - see - #12818__. - - __: http://code.djangoproject.com/ticket/12818 - - """ - updated = datetime.datetime(2010, 2, 20) - models.SchoolClass.objects.create(year=2009, last_updated=updated) - years = models.SchoolClass.objects.dates('last_updated', 'year') - self.assertEqual(list(years), [datetime.datetime(2010, 1, 1, 0, 0)]) - - def test_django_extract(self): - """ - Test the custom ``django_extract method``, in particular against fields - which clash with strings passed to it (e.g. 'day') - see #12818__. - - __: http://code.djangoproject.com/ticket/12818 - - """ - updated = datetime.datetime(2010, 2, 20) - models.SchoolClass.objects.create(year=2009, last_updated=updated) - classes = models.SchoolClass.objects.filter(last_updated__day=20) - self.assertEqual(len(classes), 1) - -class ParameterHandlingTest(TestCase): - def test_bad_parameter_count(self): - "An executemany call with too many/not enough parameters will raise an exception (Refs #12612)" - cursor = connection.cursor() - query = ('INSERT INTO %s (%s, %s) VALUES (%%s, %%s)' % ( - connection.introspection.table_name_converter('backends_square'), - connection.ops.quote_name('root'), - connection.ops.quote_name('square') - )) - self.assertRaises(Exception, cursor.executemany, query, [(1,2,3),]) - self.assertRaises(Exception, cursor.executemany, query, [(1,),]) - -class PostgresVersionTest(TestCase): - def assert_parses(self, version_string, version): - self.assertEqual(pg_version._parse_version(version_string), version) - - def test_parsing(self): - self.assert_parses("PostgreSQL 8.3 beta4", (8, 3, None)) - self.assert_parses("PostgreSQL 8.3", (8, 3, None)) - self.assert_parses("EnterpriseDB 8.3", (8, 3, None)) - self.assert_parses("PostgreSQL 8.3.6", (8, 3, 6)) - self.assert_parses("PostgreSQL 8.4beta1", (8, 4, None)) - self.assert_parses("PostgreSQL 8.3.1 on i386-apple-darwin9.2.2, compiled by GCC i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5478)", (8, 3, 1)) - -# Unfortunately with sqlite3 the in-memory test database cannot be -# closed, and so it cannot be re-opened during testing, and so we -# sadly disable this test for now. -if settings.DATABASES[DEFAULT_DB_ALIAS]["ENGINE"] != "django.db.backends.sqlite3": - class ConnectionCreatedSignalTest(TestCase): - def test_signal(self): - data = {} - def receiver(sender, connection, **kwargs): - data["connection"] = connection - - connection_created.connect(receiver) - connection.close() - cursor = connection.cursor() - self.assertTrue(data["connection"] is connection) - - connection_created.disconnect(receiver) - data.clear() - cursor = connection.cursor() - self.assertTrue(data == {}) - - -class BackendTestCase(TestCase): - def test_cursor_executemany(self): - #4896: Test cursor.executemany - cursor = connection.cursor() - qn = connection.ops.quote_name - opts = models.Square._meta - f1, f2 = opts.get_field('root'), opts.get_field('square') - query = ('INSERT INTO %s (%s, %s) VALUES (%%s, %%s)' - % (connection.introspection.table_name_converter(opts.db_table), qn(f1.column), qn(f2.column))) - cursor.executemany(query, [(i, i**2) for i in range(-5, 6)]) - self.assertEqual(models.Square.objects.count(), 11) - for i in range(-5, 6): - square = models.Square.objects.get(root=i) - self.assertEqual(square.square, i**2) - - #4765: executemany with params=[] does nothing - cursor.executemany(query, []) - self.assertEqual(models.Square.objects.count(), 11) - - -# We don't make these tests conditional because that means we would need to -# check and differentiate between: -# * MySQL+InnoDB, MySQL+MYISAM (something we currently can't do). -# * if sqlite3 (if/once we get #14204 fixed) has referential integrity turned -# on or not, something that would be controlled by runtime support and user -# preference. -# verify if its type is django.database.db.IntegrityError. - -class FkConstraintsTests(TransactionTestCase): - - def setUp(self): - # Create a Reporter. - self.r = models.Reporter.objects.create(first_name='John', last_name='Smith') - - def test_integrity_checks_on_creation(self): - """ - Try to create a model instance that violates a FK constraint. If it - fails it should fail with IntegrityError. - """ - a = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30) - try: - a.save() - except IntegrityError: - pass - - def test_integrity_checks_on_update(self): - """ - Try to update a model instance introducing a FK constraint violation. - If it fails it should fail with IntegrityError. - """ - # Create an Article. - models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) - # Retrive it from the DB - a = models.Article.objects.get(headline="Test article") - a.reporter_id = 30 - try: - a.save() - except IntegrityError: - pass - def test_unicode_fetches(self): - #6254: fetchone, fetchmany, fetchall return strings as unicode objects - qn = connection.ops.quote_name - models.Person(first_name="John", last_name="Doe").save() - models.Person(first_name="Jane", last_name="Doe").save() - models.Person(first_name="Mary", last_name="Agnelline").save() - models.Person(first_name="Peter", last_name="Parker").save() - models.Person(first_name="Clark", last_name="Kent").save() - opts2 = models.Person._meta - f3, f4 = opts2.get_field('first_name'), opts2.get_field('last_name') - query2 = ('SELECT %s, %s FROM %s ORDER BY %s' - % (qn(f3.column), qn(f4.column), connection.introspection.table_name_converter(opts2.db_table), - qn(f3.column))) - cursor = connection.cursor() - cursor.execute(query2) - self.assertEqual(cursor.fetchone(), (u'Clark', u'Kent')) - self.assertEqual(list(cursor.fetchmany(2)), [(u'Jane', u'Doe'), (u'John', u'Doe')]) - self.assertEqual(list(cursor.fetchall()), [(u'Mary', u'Agnelline'), (u'Peter', u'Parker')]) diff --git a/parts/django/tests/regressiontests/bash_completion/__init__.py b/parts/django/tests/regressiontests/bash_completion/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/bash_completion/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/bash_completion/management/__init__.py b/parts/django/tests/regressiontests/bash_completion/management/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/bash_completion/management/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py b/parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/bash_completion/management/commands/test_command.py b/parts/django/tests/regressiontests/bash_completion/management/commands/test_command.py deleted file mode 100644 index 5cb8820..0000000 --- a/parts/django/tests/regressiontests/bash_completion/management/commands/test_command.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys, os -from optparse import OptionParser, make_option - -from django.core.management.base import BaseCommand - - -class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option("--list", action="store_true", dest="list", - help="Print all options"), - ) - - def handle(self, *args, **options): - pass diff --git a/parts/django/tests/regressiontests/bash_completion/models.py b/parts/django/tests/regressiontests/bash_completion/models.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/bash_completion/models.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/bash_completion/tests.py b/parts/django/tests/regressiontests/bash_completion/tests.py deleted file mode 100644 index 24c8b1d..0000000 --- a/parts/django/tests/regressiontests/bash_completion/tests.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -A series of tests to establish that the command-line bash completion works. -""" -import os -import unittest -import sys -import StringIO - -from django.conf import settings -from django.core.management import ManagementUtility - -class BashCompletionTests(unittest.TestCase): - """ - Testing the Python level bash completion code. - This requires setting up the environment as if we got passed data - from bash. - """ - - def setUp(self): - self.old_DJANGO_AUTO_COMPLETE = os.environ.get('DJANGO_AUTO_COMPLETE') - os.environ['DJANGO_AUTO_COMPLETE'] = '1' - self.output = StringIO.StringIO() - self.old_stdout = sys.stdout - sys.stdout = self.output - - def tearDown(self): - sys.stdout = self.old_stdout - if self.old_DJANGO_AUTO_COMPLETE: - os.environ['DJANGO_AUTO_COMPLETE'] = self.old_DJANGO_AUTO_COMPLETE - else: - del os.environ['DJANGO_AUTO_COMPLETE'] - - def _user_input(self, input_str): - os.environ['COMP_WORDS'] = input_str - os.environ['COMP_CWORD'] = str(len(input_str.split()) - 1) - sys.argv = input_str.split(' ') - - def _run_autocomplete(self): - util = ManagementUtility(argv=sys.argv) - try: - util.autocomplete() - except SystemExit: - pass - return self.output.getvalue().strip().split('\n') - - def test_django_admin_py(self): - "django_admin.py will autocomplete option flags" - self._user_input('django-admin.py sqlall --v') - output = self._run_autocomplete() - self.assertEqual(output, ['--verbosity=']) - - def test_manage_py(self): - "manage.py will autocomplete option flags" - self._user_input('manage.py sqlall --v') - output = self._run_autocomplete() - self.assertEqual(output, ['--verbosity=']) - - def test_custom_command(self): - "A custom command can autocomplete option flags" - self._user_input('django-admin.py test_command --l') - output = self._run_autocomplete() - self.assertEqual(output, ['--list']) - - def test_subcommands(self): - "Subcommands can be autocompleted" - self._user_input('django-admin.py sql') - output = self._run_autocomplete() - self.assertEqual(output, ['sql sqlall sqlclear sqlcustom sqlflush sqlindexes sqlinitialdata sqlreset sqlsequencereset']) - - def test_help(self): - "No errors, just an empty list if there are no autocomplete options" - self._user_input('django-admin.py help --') - output = self._run_autocomplete() - self.assertEqual(output, ['']) - - def test_runfcgi(self): - "Command arguments will be autocompleted" - self._user_input('django-admin.py runfcgi h') - output = self._run_autocomplete() - self.assertEqual(output, ['host=']) - - def test_app_completion(self): - "Application names will be autocompleted for an AppCommand" - self._user_input('django-admin.py sqlall a') - output = self._run_autocomplete() - app_labels = [name.split('.')[-1] for name in settings.INSTALLED_APPS] - self.assertEqual(output, sorted(label for label in app_labels if label.startswith('a'))) diff --git a/parts/django/tests/regressiontests/bug639/__init__.py b/parts/django/tests/regressiontests/bug639/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/bug639/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/bug639/models.py b/parts/django/tests/regressiontests/bug639/models.py deleted file mode 100644 index b7e3880..0000000 --- a/parts/django/tests/regressiontests/bug639/models.py +++ /dev/null @@ -1,26 +0,0 @@ -import tempfile - -from django.db import models -from django.core.files.storage import FileSystemStorage -from django.forms import ModelForm - -temp_storage_dir = tempfile.mkdtemp() -temp_storage = FileSystemStorage(temp_storage_dir) - -class Photo(models.Model): - title = models.CharField(max_length=30) - image = models.FileField(storage=temp_storage, upload_to='tests') - - # Support code for the tests; this keeps track of how many times save() - # gets called on each instance. - def __init__(self, *args, **kwargs): - super(Photo, self).__init__(*args, **kwargs) - self._savecount = 0 - - def save(self, force_insert=False, force_update=False): - super(Photo, self).save(force_insert, force_update) - self._savecount += 1 - -class PhotoForm(ModelForm): - class Meta: - model = Photo diff --git a/parts/django/tests/regressiontests/bug639/test.jpg b/parts/django/tests/regressiontests/bug639/test.jpg Binary files differdeleted file mode 100644 index 391b57a..0000000 --- a/parts/django/tests/regressiontests/bug639/test.jpg +++ /dev/null diff --git a/parts/django/tests/regressiontests/bug639/tests.py b/parts/django/tests/regressiontests/bug639/tests.py deleted file mode 100644 index 2cc3a8a..0000000 --- a/parts/django/tests/regressiontests/bug639/tests.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -Tests for file field behavior, and specifically #639, in which Model.save() -gets called *again* for each FileField. This test will fail if calling a -ModelForm's save() method causes Model.save() to be called more than once. -""" - -import os -import shutil -import unittest - -from django.core.files.uploadedfile import SimpleUploadedFile -from regressiontests.bug639.models import Photo, PhotoForm, temp_storage_dir - -class Bug639Test(unittest.TestCase): - - def testBug639(self): - """ - Simulate a file upload and check how many times Model.save() gets - called. - """ - # Grab an image for testing. - filename = os.path.join(os.path.dirname(__file__), "test.jpg") - img = open(filename, "rb").read() - - # Fake a POST QueryDict and FILES MultiValueDict. - data = {'title': 'Testing'} - files = {"image": SimpleUploadedFile('test.jpg', img, 'image/jpeg')} - - form = PhotoForm(data=data, files=files) - p = form.save() - - # Check the savecount stored on the object (see the model). - self.assertEqual(p._savecount, 1) - - def tearDown(self): - """ - Make sure to delete the "uploaded" file to avoid clogging /tmp. - """ - p = Photo.objects.get() - p.image.delete(save=False) - shutil.rmtree(temp_storage_dir) diff --git a/parts/django/tests/regressiontests/bug8245/__init__.py b/parts/django/tests/regressiontests/bug8245/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/bug8245/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/bug8245/admin.py b/parts/django/tests/regressiontests/bug8245/admin.py deleted file mode 100644 index 1812269..0000000 --- a/parts/django/tests/regressiontests/bug8245/admin.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.contrib import admin - -from models import Story - - -admin.site.register(Story) -raise Exception("Bad admin module") diff --git a/parts/django/tests/regressiontests/bug8245/models.py b/parts/django/tests/regressiontests/bug8245/models.py deleted file mode 100644 index 5643955..0000000 --- a/parts/django/tests/regressiontests/bug8245/models.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.db import models - -class Story(models.Model): - title = models.CharField(max_length=10) diff --git a/parts/django/tests/regressiontests/bug8245/tests.py b/parts/django/tests/regressiontests/bug8245/tests.py deleted file mode 100644 index 5aa4a94..0000000 --- a/parts/django/tests/regressiontests/bug8245/tests.py +++ /dev/null @@ -1,29 +0,0 @@ -from unittest import TestCase - -from django.contrib import admin - - -class Bug8245Test(TestCase): - """ - Test for bug #8245 - don't raise an AlreadyRegistered exception when using - autodiscover() and an admin.py module contains an error. - """ - def test_bug_8245(self): - # The first time autodiscover is called, we should get our real error. - try: - admin.autodiscover() - except Exception, e: - self.assertEqual(str(e), "Bad admin module") - else: - self.fail( - 'autodiscover should have raised a "Bad admin module" error.') - - # Calling autodiscover again should raise the very same error it did - # the first time, not an AlreadyRegistered error. - try: - admin.autodiscover() - except Exception, e: - self.assertEqual(str(e), "Bad admin module") - else: - self.fail( - 'autodiscover should have raised a "Bad admin module" error.') diff --git a/parts/django/tests/regressiontests/builtin_server/__init__.py b/parts/django/tests/regressiontests/builtin_server/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/builtin_server/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/builtin_server/models.py b/parts/django/tests/regressiontests/builtin_server/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/builtin_server/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/builtin_server/tests.py b/parts/django/tests/regressiontests/builtin_server/tests.py deleted file mode 100644 index c3cfef1..0000000 --- a/parts/django/tests/regressiontests/builtin_server/tests.py +++ /dev/null @@ -1,51 +0,0 @@ -from unittest import TestCase -from StringIO import StringIO -from django.core.servers.basehttp import ServerHandler - -# -# Tests for #9659: wsgi.file_wrapper in the builtin server. -# We need to mock a couple of of handlers and keep track of what -# gets called when using a couple kinds of WSGI apps. -# - -class DummyHandler(object): - def log_request(*args, **kwargs): - pass - -class FileWrapperHandler(ServerHandler): - def __init__(self, *args, **kwargs): - ServerHandler.__init__(self, *args, **kwargs) - self.request_handler = DummyHandler() - self._used_sendfile = False - - def sendfile(self): - self._used_sendfile = True - return True - -def wsgi_app(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - return ['Hello World!'] - -def wsgi_app_file_wrapper(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - return environ['wsgi.file_wrapper'](StringIO('foo')) - -class WSGIFileWrapperTests(TestCase): - """ - Test that the wsgi.file_wrapper works for the builting server. - """ - - def test_file_wrapper_uses_sendfile(self): - env = {'SERVER_PROTOCOL': 'HTTP/1.0'} - err = StringIO() - handler = FileWrapperHandler(None, StringIO(), err, env) - handler.run(wsgi_app_file_wrapper) - self.assert_(handler._used_sendfile) - - def test_file_wrapper_no_sendfile(self): - env = {'SERVER_PROTOCOL': 'HTTP/1.0'} - err = StringIO() - handler = FileWrapperHandler(None, StringIO(), err, env) - handler.run(wsgi_app) - self.assertFalse(handler._used_sendfile) - self.assertEqual(handler.stdout.getvalue().splitlines()[-1],'Hello World!') diff --git a/parts/django/tests/regressiontests/cache/__init__.py b/parts/django/tests/regressiontests/cache/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/cache/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/cache/liberal_backend.py b/parts/django/tests/regressiontests/cache/liberal_backend.py deleted file mode 100644 index 5c7e312..0000000 --- a/parts/django/tests/regressiontests/cache/liberal_backend.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.core.cache.backends.locmem import CacheClass as LocMemCacheClass - -class LiberalKeyValidationMixin(object): - def validate_key(self, key): - pass - -class CacheClass(LiberalKeyValidationMixin, LocMemCacheClass): - pass - diff --git a/parts/django/tests/regressiontests/cache/models.py b/parts/django/tests/regressiontests/cache/models.py deleted file mode 100644 index 643fd22..0000000 --- a/parts/django/tests/regressiontests/cache/models.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.db import models -from datetime import datetime - -def expensive_calculation(): - expensive_calculation.num_runs += 1 - return datetime.now() - -class Poll(models.Model): - question = models.CharField(max_length=200) - answer = models.CharField(max_length=200) - pub_date = models.DateTimeField('date published', default=expensive_calculation) diff --git a/parts/django/tests/regressiontests/cache/tests.py b/parts/django/tests/regressiontests/cache/tests.py deleted file mode 100644 index 7167e2f..0000000 --- a/parts/django/tests/regressiontests/cache/tests.py +++ /dev/null @@ -1,652 +0,0 @@ -# -*- coding: utf-8 -*- - -# Unit tests for cache framework -# Uses whatever cache backend is set in the test settings file. - -import os -import shutil -import tempfile -import time -import unittest -import warnings - -from django.conf import settings -from django.core import management -from django.core.cache import get_cache -from django.core.cache.backends.base import InvalidCacheBackendError, CacheKeyWarning -from django.http import HttpResponse, HttpRequest -from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware -from django.test.utils import get_warnings_state, restore_warnings_state -from django.utils import translation -from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key -from django.utils.hashcompat import md5_constructor -from regressiontests.cache.models import Poll, expensive_calculation - -# functions/classes for complex data type tests -def f(): - return 42 -class C: - def m(n): - return 24 - -class DummyCacheTests(unittest.TestCase): - # The Dummy cache backend doesn't really behave like a test backend, - # so it has different test requirements. - def setUp(self): - self.cache = get_cache('dummy://') - - def test_simple(self): - "Dummy cache backend ignores cache set calls" - self.cache.set("key", "value") - self.assertEqual(self.cache.get("key"), None) - - def test_add(self): - "Add doesn't do anything in dummy cache backend" - self.cache.add("addkey1", "value") - result = self.cache.add("addkey1", "newvalue") - self.assertEqual(result, True) - self.assertEqual(self.cache.get("addkey1"), None) - - def test_non_existent(self): - "Non-existent keys aren't found in the dummy cache backend" - self.assertEqual(self.cache.get("does_not_exist"), None) - self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!") - - def test_get_many(self): - "get_many returns nothing for the dummy cache backend" - self.cache.set('a', 'a') - self.cache.set('b', 'b') - self.cache.set('c', 'c') - self.cache.set('d', 'd') - self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {}) - self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {}) - - def test_delete(self): - "Cache deletion is transparently ignored on the dummy cache backend" - self.cache.set("key1", "spam") - self.cache.set("key2", "eggs") - self.assertEqual(self.cache.get("key1"), None) - self.cache.delete("key1") - self.assertEqual(self.cache.get("key1"), None) - self.assertEqual(self.cache.get("key2"), None) - - def test_has_key(self): - "The has_key method doesn't ever return True for the dummy cache backend" - self.cache.set("hello1", "goodbye1") - self.assertEqual(self.cache.has_key("hello1"), False) - self.assertEqual(self.cache.has_key("goodbye1"), False) - - def test_in(self): - "The in operator doesn't ever return True for the dummy cache backend" - self.cache.set("hello2", "goodbye2") - self.assertEqual("hello2" in self.cache, False) - self.assertEqual("goodbye2" in self.cache, False) - - def test_incr(self): - "Dummy cache values can't be incremented" - self.cache.set('answer', 42) - self.assertRaises(ValueError, self.cache.incr, 'answer') - self.assertRaises(ValueError, self.cache.incr, 'does_not_exist') - - def test_decr(self): - "Dummy cache values can't be decremented" - self.cache.set('answer', 42) - self.assertRaises(ValueError, self.cache.decr, 'answer') - self.assertRaises(ValueError, self.cache.decr, 'does_not_exist') - - def test_data_types(self): - "All data types are ignored equally by the dummy cache" - stuff = { - 'string' : 'this is a string', - 'int' : 42, - 'list' : [1, 2, 3, 4], - 'tuple' : (1, 2, 3, 4), - 'dict' : {'A': 1, 'B' : 2}, - 'function' : f, - 'class' : C, - } - self.cache.set("stuff", stuff) - self.assertEqual(self.cache.get("stuff"), None) - - def test_expiration(self): - "Expiration has no effect on the dummy cache" - self.cache.set('expire1', 'very quickly', 1) - self.cache.set('expire2', 'very quickly', 1) - self.cache.set('expire3', 'very quickly', 1) - - time.sleep(2) - self.assertEqual(self.cache.get("expire1"), None) - - self.cache.add("expire2", "newvalue") - self.assertEqual(self.cache.get("expire2"), None) - self.assertEqual(self.cache.has_key("expire3"), False) - - def test_unicode(self): - "Unicode values are ignored by the dummy cache" - stuff = { - u'ascii': u'ascii_value', - u'unicode_ascii': u'Iñtërnâtiônàlizætiøn1', - u'Iñtërnâtiônàlizætiøn': u'Iñtërnâtiônàlizætiøn2', - u'ascii': {u'x' : 1 } - } - for (key, value) in stuff.items(): - self.cache.set(key, value) - self.assertEqual(self.cache.get(key), None) - - def test_set_many(self): - "set_many does nothing for the dummy cache backend" - self.cache.set_many({'a': 1, 'b': 2}) - - def test_delete_many(self): - "delete_many does nothing for the dummy cache backend" - self.cache.delete_many(['a', 'b']) - - def test_clear(self): - "clear does nothing for the dummy cache backend" - self.cache.clear() - - -class BaseCacheTests(object): - # A common set of tests to apply to all cache backends - def tearDown(self): - self.cache.clear() - - def test_simple(self): - # Simple cache set/get works - self.cache.set("key", "value") - self.assertEqual(self.cache.get("key"), "value") - - def test_add(self): - # A key can be added to a cache - self.cache.add("addkey1", "value") - result = self.cache.add("addkey1", "newvalue") - self.assertEqual(result, False) - self.assertEqual(self.cache.get("addkey1"), "value") - - def test_non_existent(self): - # Non-existent cache keys return as None/default - # get with non-existent keys - self.assertEqual(self.cache.get("does_not_exist"), None) - self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!") - - def test_get_many(self): - # Multiple cache keys can be returned using get_many - self.cache.set('a', 'a') - self.cache.set('b', 'b') - self.cache.set('c', 'c') - self.cache.set('d', 'd') - self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {'a' : 'a', 'c' : 'c', 'd' : 'd'}) - self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {'a' : 'a', 'b' : 'b'}) - - def test_delete(self): - # Cache keys can be deleted - self.cache.set("key1", "spam") - self.cache.set("key2", "eggs") - self.assertEqual(self.cache.get("key1"), "spam") - self.cache.delete("key1") - self.assertEqual(self.cache.get("key1"), None) - self.assertEqual(self.cache.get("key2"), "eggs") - - def test_has_key(self): - # The cache can be inspected for cache keys - self.cache.set("hello1", "goodbye1") - self.assertEqual(self.cache.has_key("hello1"), True) - self.assertEqual(self.cache.has_key("goodbye1"), False) - - def test_in(self): - # The in operator can be used to inspet cache contents - self.cache.set("hello2", "goodbye2") - self.assertEqual("hello2" in self.cache, True) - self.assertEqual("goodbye2" in self.cache, False) - - def test_incr(self): - # Cache values can be incremented - self.cache.set('answer', 41) - self.assertEqual(self.cache.incr('answer'), 42) - self.assertEqual(self.cache.get('answer'), 42) - self.assertEqual(self.cache.incr('answer', 10), 52) - self.assertEqual(self.cache.get('answer'), 52) - self.assertRaises(ValueError, self.cache.incr, 'does_not_exist') - - def test_decr(self): - # Cache values can be decremented - self.cache.set('answer', 43) - self.assertEqual(self.cache.decr('answer'), 42) - self.assertEqual(self.cache.get('answer'), 42) - self.assertEqual(self.cache.decr('answer', 10), 32) - self.assertEqual(self.cache.get('answer'), 32) - self.assertRaises(ValueError, self.cache.decr, 'does_not_exist') - - def test_data_types(self): - # Many different data types can be cached - stuff = { - 'string' : 'this is a string', - 'int' : 42, - 'list' : [1, 2, 3, 4], - 'tuple' : (1, 2, 3, 4), - 'dict' : {'A': 1, 'B' : 2}, - 'function' : f, - 'class' : C, - } - self.cache.set("stuff", stuff) - self.assertEqual(self.cache.get("stuff"), stuff) - - def test_cache_read_for_model_instance(self): - # Don't want fields with callable as default to be called on cache read - expensive_calculation.num_runs = 0 - Poll.objects.all().delete() - my_poll = Poll.objects.create(question="Well?") - self.assertEqual(Poll.objects.count(), 1) - pub_date = my_poll.pub_date - self.cache.set('question', my_poll) - cached_poll = self.cache.get('question') - self.assertEqual(cached_poll.pub_date, pub_date) - # We only want the default expensive calculation run once - self.assertEqual(expensive_calculation.num_runs, 1) - - def test_cache_write_for_model_instance_with_deferred(self): - # Don't want fields with callable as default to be called on cache write - expensive_calculation.num_runs = 0 - Poll.objects.all().delete() - my_poll = Poll.objects.create(question="What?") - self.assertEqual(expensive_calculation.num_runs, 1) - defer_qs = Poll.objects.all().defer('question') - self.assertEqual(defer_qs.count(), 1) - self.assertEqual(expensive_calculation.num_runs, 1) - self.cache.set('deferred_queryset', defer_qs) - # cache set should not re-evaluate default functions - self.assertEqual(expensive_calculation.num_runs, 1) - - def test_cache_read_for_model_instance_with_deferred(self): - # Don't want fields with callable as default to be called on cache read - expensive_calculation.num_runs = 0 - Poll.objects.all().delete() - my_poll = Poll.objects.create(question="What?") - self.assertEqual(expensive_calculation.num_runs, 1) - defer_qs = Poll.objects.all().defer('question') - self.assertEqual(defer_qs.count(), 1) - self.cache.set('deferred_queryset', defer_qs) - self.assertEqual(expensive_calculation.num_runs, 1) - runs_before_cache_read = expensive_calculation.num_runs - cached_polls = self.cache.get('deferred_queryset') - # We only want the default expensive calculation run on creation and set - self.assertEqual(expensive_calculation.num_runs, runs_before_cache_read) - - def test_expiration(self): - # Cache values can be set to expire - self.cache.set('expire1', 'very quickly', 1) - self.cache.set('expire2', 'very quickly', 1) - self.cache.set('expire3', 'very quickly', 1) - - time.sleep(2) - self.assertEqual(self.cache.get("expire1"), None) - - self.cache.add("expire2", "newvalue") - self.assertEqual(self.cache.get("expire2"), "newvalue") - self.assertEqual(self.cache.has_key("expire3"), False) - - def test_unicode(self): - # Unicode values can be cached - stuff = { - u'ascii': u'ascii_value', - u'unicode_ascii': u'Iñtërnâtiônàlizætiøn1', - u'Iñtërnâtiônàlizætiøn': u'Iñtërnâtiônàlizætiøn2', - u'ascii': {u'x' : 1 } - } - for (key, value) in stuff.items(): - self.cache.set(key, value) - self.assertEqual(self.cache.get(key), value) - - def test_binary_string(self): - # Binary strings should be cachable - from zlib import compress, decompress - value = 'value_to_be_compressed' - compressed_value = compress(value) - self.cache.set('binary1', compressed_value) - compressed_result = self.cache.get('binary1') - self.assertEqual(compressed_value, compressed_result) - self.assertEqual(value, decompress(compressed_result)) - - def test_set_many(self): - # Multiple keys can be set using set_many - self.cache.set_many({"key1": "spam", "key2": "eggs"}) - self.assertEqual(self.cache.get("key1"), "spam") - self.assertEqual(self.cache.get("key2"), "eggs") - - def test_set_many_expiration(self): - # set_many takes a second ``timeout`` parameter - self.cache.set_many({"key1": "spam", "key2": "eggs"}, 1) - time.sleep(2) - self.assertEqual(self.cache.get("key1"), None) - self.assertEqual(self.cache.get("key2"), None) - - def test_delete_many(self): - # Multiple keys can be deleted using delete_many - self.cache.set("key1", "spam") - self.cache.set("key2", "eggs") - self.cache.set("key3", "ham") - self.cache.delete_many(["key1", "key2"]) - self.assertEqual(self.cache.get("key1"), None) - self.assertEqual(self.cache.get("key2"), None) - self.assertEqual(self.cache.get("key3"), "ham") - - def test_clear(self): - # The cache can be emptied using clear - self.cache.set("key1", "spam") - self.cache.set("key2", "eggs") - self.cache.clear() - self.assertEqual(self.cache.get("key1"), None) - self.assertEqual(self.cache.get("key2"), None) - - def test_long_timeout(self): - ''' - Using a timeout greater than 30 days makes memcached think - it is an absolute expiration timestamp instead of a relative - offset. Test that we honour this convention. Refs #12399. - ''' - self.cache.set('key1', 'eggs', 60*60*24*30 + 1) #30 days + 1 second - self.assertEqual(self.cache.get('key1'), 'eggs') - - self.cache.add('key2', 'ham', 60*60*24*30 + 1) - self.assertEqual(self.cache.get('key2'), 'ham') - - self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 60*60*24*30 + 1) - self.assertEqual(self.cache.get('key3'), 'sausage') - self.assertEqual(self.cache.get('key4'), 'lobster bisque') - - def perform_cull_test(self, initial_count, final_count): - """This is implemented as a utility method, because only some of the backends - implement culling. The culling algorithm also varies slightly, so the final - number of entries will vary between backends""" - # Create initial cache key entries. This will overflow the cache, causing a cull - for i in range(1, initial_count): - self.cache.set('cull%d' % i, 'value', 1000) - count = 0 - # Count how many keys are left in the cache. - for i in range(1, initial_count): - if self.cache.has_key('cull%d' % i): - count = count + 1 - self.assertEqual(count, final_count) - - def test_invalid_keys(self): - """ - All the builtin backends (except memcached, see below) should warn on - keys that would be refused by memcached. This encourages portable - caching code without making it too difficult to use production backends - with more liberal key rules. Refs #6447. - - """ - # On Python 2.6+ we could use the catch_warnings context - # manager to test this warning nicely. Since we can't do that - # yet, the cleanest option is to temporarily ask for - # CacheKeyWarning to be raised as an exception. - _warnings_state = get_warnings_state() - warnings.simplefilter("error", CacheKeyWarning) - - try: - # memcached does not allow whitespace or control characters in keys - self.assertRaises(CacheKeyWarning, self.cache.set, 'key with spaces', 'value') - # memcached limits key length to 250 - self.assertRaises(CacheKeyWarning, self.cache.set, 'a' * 251, 'value') - finally: - restore_warnings_state(_warnings_state) - -class DBCacheTests(unittest.TestCase, BaseCacheTests): - def setUp(self): - # Spaces are used in the table name to ensure quoting/escaping is working - self._table_name = 'test cache table' - management.call_command('createcachetable', self._table_name, verbosity=0, interactive=False) - self.cache = get_cache('db://%s?max_entries=30' % self._table_name) - - def tearDown(self): - from django.db import connection - cursor = connection.cursor() - cursor.execute('DROP TABLE %s' % connection.ops.quote_name(self._table_name)) - - def test_cull(self): - self.perform_cull_test(50, 29) - -class LocMemCacheTests(unittest.TestCase, BaseCacheTests): - def setUp(self): - self.cache = get_cache('locmem://?max_entries=30') - - def test_cull(self): - self.perform_cull_test(50, 29) - -# memcached backend isn't guaranteed to be available. -# To check the memcached backend, the test settings file will -# need to contain a CACHE_BACKEND setting that points at -# your memcache server. -if settings.CACHE_BACKEND.startswith('memcached://'): - class MemcachedCacheTests(unittest.TestCase, BaseCacheTests): - def setUp(self): - self.cache = get_cache(settings.CACHE_BACKEND) - - def test_invalid_keys(self): - """ - On memcached, we don't introduce a duplicate key validation - step (for speed reasons), we just let the memcached API - library raise its own exception on bad keys. Refs #6447. - - In order to be memcached-API-library agnostic, we only assert - that a generic exception of some kind is raised. - - """ - # memcached does not allow whitespace or control characters in keys - self.assertRaises(Exception, self.cache.set, 'key with spaces', 'value') - # memcached limits key length to 250 - self.assertRaises(Exception, self.cache.set, 'a' * 251, 'value') - - -class FileBasedCacheTests(unittest.TestCase, BaseCacheTests): - """ - Specific test cases for the file-based cache. - """ - def setUp(self): - self.dirname = tempfile.mkdtemp() - self.cache = get_cache('file://%s?max_entries=30' % self.dirname) - - def test_hashing(self): - """Test that keys are hashed into subdirectories correctly""" - self.cache.set("foo", "bar") - keyhash = md5_constructor("foo").hexdigest() - keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:]) - self.assert_(os.path.exists(keypath)) - - def test_subdirectory_removal(self): - """ - Make sure that the created subdirectories are correctly removed when empty. - """ - self.cache.set("foo", "bar") - keyhash = md5_constructor("foo").hexdigest() - keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:]) - self.assert_(os.path.exists(keypath)) - - self.cache.delete("foo") - self.assert_(not os.path.exists(keypath)) - self.assert_(not os.path.exists(os.path.dirname(keypath))) - self.assert_(not os.path.exists(os.path.dirname(os.path.dirname(keypath)))) - - def test_cull(self): - self.perform_cull_test(50, 28) - -class CustomCacheKeyValidationTests(unittest.TestCase): - """ - Tests for the ability to mixin a custom ``validate_key`` method to - a custom cache backend that otherwise inherits from a builtin - backend, and override the default key validation. Refs #6447. - - """ - def test_custom_key_validation(self): - cache = get_cache('regressiontests.cache.liberal_backend://') - - # this key is both longer than 250 characters, and has spaces - key = 'some key with spaces' * 15 - val = 'a value' - cache.set(key, val) - self.assertEqual(cache.get(key), val) - -class CacheUtils(unittest.TestCase): - """TestCase for django.utils.cache functions.""" - - def setUp(self): - self.path = '/cache/test/' - self.old_settings_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX - self.old_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS - self.orig_use_i18n = settings.USE_I18N - settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix' - settings.CACHE_MIDDLEWARE_SECONDS = 1 - settings.USE_I18N = False - - def tearDown(self): - settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.old_settings_key_prefix - settings.CACHE_MIDDLEWARE_SECONDS = self.old_middleware_seconds - settings.USE_I18N = self.orig_use_i18n - - def _get_request(self, path): - request = HttpRequest() - request.META = { - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - } - request.path = request.path_info = "/cache/%s" % path - return request - - def test_patch_vary_headers(self): - headers = ( - # Initial vary, new headers, resulting vary. - (None, ('Accept-Encoding',), 'Accept-Encoding'), - ('Accept-Encoding', ('accept-encoding',), 'Accept-Encoding'), - ('Accept-Encoding', ('ACCEPT-ENCODING',), 'Accept-Encoding'), - ('Cookie', ('Accept-Encoding',), 'Cookie, Accept-Encoding'), - ('Cookie, Accept-Encoding', ('Accept-Encoding',), 'Cookie, Accept-Encoding'), - ('Cookie, Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'), - (None, ('Accept-Encoding', 'COOKIE'), 'Accept-Encoding, COOKIE'), - ('Cookie, Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'), - ('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'), - ) - for initial_vary, newheaders, resulting_vary in headers: - response = HttpResponse() - if initial_vary is not None: - response['Vary'] = initial_vary - patch_vary_headers(response, newheaders) - self.assertEqual(response['Vary'], resulting_vary) - - def test_get_cache_key(self): - request = self._get_request(self.path) - response = HttpResponse() - key_prefix = 'localprefix' - # Expect None if no headers have been set yet. - self.assertEqual(get_cache_key(request), None) - # Set headers to an empty list. - learn_cache_key(request, response) - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e') - # Verify that a specified key_prefix is taken in to account. - learn_cache_key(request, response, key_prefix=key_prefix) - self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e') - - def test_learn_cache_key(self): - request = self._get_request(self.path) - response = HttpResponse() - response['Vary'] = 'Pony' - # Make sure that the Vary header is added to the key hash - learn_cache_key(request, response) - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e') - -class CacheI18nTest(unittest.TestCase): - - def setUp(self): - self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS - self.orig_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX - self.orig_cache_backend = settings.CACHE_BACKEND - self.orig_use_i18n = settings.USE_I18N - self.orig_languages = settings.LANGUAGES - settings.LANGUAGES = ( - ('en', 'English'), - ('es', 'Spanish'), - ) - settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix' - self.path = '/cache/test/' - - def tearDown(self): - settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds - settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.orig_cache_middleware_key_prefix - settings.CACHE_BACKEND = self.orig_cache_backend - settings.USE_I18N = self.orig_use_i18n - settings.LANGUAGES = self.orig_languages - translation.deactivate() - - def _get_request(self): - request = HttpRequest() - request.META = { - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - } - request.path = request.path_info = self.path - return request - - def _get_request_cache(self): - request = HttpRequest() - request.META = { - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - } - request.path = request.path_info = self.path - request._cache_update_cache = True - request.method = 'GET' - request.session = {} - return request - - def test_cache_key_i18n(self): - settings.USE_I18N = True - request = self._get_request() - lang = translation.get_language() - response = HttpResponse() - key = learn_cache_key(request, response) - self.assertTrue(key.endswith(lang), "Cache keys should include the language name when i18n is active") - key2 = get_cache_key(request) - self.assertEqual(key, key2) - - def test_cache_key_no_i18n (self): - settings.USE_I18N = False - request = self._get_request() - lang = translation.get_language() - response = HttpResponse() - key = learn_cache_key(request, response) - self.assertFalse(key.endswith(lang), "Cache keys shouldn't include the language name when i18n is inactive") - - def test_middleware(self): - def set_cache(request, lang, msg): - translation.activate(lang) - response = HttpResponse() - response.content= msg - return UpdateCacheMiddleware().process_response(request, response) - - settings.CACHE_MIDDLEWARE_SECONDS = 60 - settings.CACHE_MIDDLEWARE_KEY_PREFIX="test" - settings.CACHE_BACKEND='locmem:///' - settings.USE_I18N = True - en_message ="Hello world!" - es_message ="Hola mundo!" - - request = self._get_request_cache() - set_cache(request, 'en', en_message) - get_cache_data = FetchFromCacheMiddleware().process_request(request) - # Check that we can recover the cache - self.assertNotEqual(get_cache_data.content, None) - self.assertEqual(en_message, get_cache_data.content) - # change the session language and set content - request = self._get_request_cache() - set_cache(request, 'es', es_message) - # change again the language - translation.activate('en') - # retrieve the content from cache - get_cache_data = FetchFromCacheMiddleware().process_request(request) - self.assertEqual(get_cache_data.content, en_message) - # change again the language - translation.activate('es') - get_cache_data = FetchFromCacheMiddleware().process_request(request) - self.assertEqual(get_cache_data.content, es_message) - -if __name__ == '__main__': - unittest.main() diff --git a/parts/django/tests/regressiontests/comment_tests/__init__.py b/parts/django/tests/regressiontests/comment_tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/comment_tests/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/comment_tests/custom_comments/__init__.py b/parts/django/tests/regressiontests/comment_tests/custom_comments/__init__.py deleted file mode 100644 index 598927e..0000000 --- a/parts/django/tests/regressiontests/comment_tests/custom_comments/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.core import urlresolvers -from regressiontests.comment_tests.custom_comments.models import CustomComment -from regressiontests.comment_tests.custom_comments.forms import CustomCommentForm - -def get_model(): - return CustomComment - -def get_form(): - return CustomCommentForm - -def get_form_target(): - return urlresolvers.reverse( - "regressiontests.comment_tests.custom_comments.views.custom_submit_comment" - ) - -def get_flag_url(c): - return urlresolvers.reverse( - "regressiontests.comment_tests.custom_comments.views.custom_flag_comment", - args=(c.id,) - ) - -def get_delete_url(c): - return urlresolvers.reverse( - "regressiontests.comment_tests.custom_comments.views.custom_delete_comment", - args=(c.id,) - ) - -def get_approve_url(c): - return urlresolvers.reverse( - "regressiontests.comment_tests.custom_comments.views.custom_approve_comment", - args=(c.id,) - ) diff --git a/parts/django/tests/regressiontests/comment_tests/custom_comments/forms.py b/parts/django/tests/regressiontests/comment_tests/custom_comments/forms.py deleted file mode 100644 index b788cdc..0000000 --- a/parts/django/tests/regressiontests/comment_tests/custom_comments/forms.py +++ /dev/null @@ -1,4 +0,0 @@ -from django import forms - -class CustomCommentForm(forms.Form): - pass diff --git a/parts/django/tests/regressiontests/comment_tests/custom_comments/models.py b/parts/django/tests/regressiontests/comment_tests/custom_comments/models.py deleted file mode 100644 index 592ad79..0000000 --- a/parts/django/tests/regressiontests/comment_tests/custom_comments/models.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.db import models - -class CustomComment(models.Model): - pass diff --git a/parts/django/tests/regressiontests/comment_tests/custom_comments/views.py b/parts/django/tests/regressiontests/comment_tests/custom_comments/views.py deleted file mode 100644 index 93cea9d..0000000 --- a/parts/django/tests/regressiontests/comment_tests/custom_comments/views.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.http import HttpResponse - -def custom_submit_comment(request): - return HttpResponse("Hello from the custom submit comment view.") - -def custom_flag_comment(request, comment_id): - return HttpResponse("Hello from the custom flag view.") - -def custom_delete_comment(request, comment_id): - return HttpResponse("Hello from the custom delete view.") - -def custom_approve_comment(request, comment_id): - return HttpResponse("Hello from the custom approve view.") diff --git a/parts/django/tests/regressiontests/comment_tests/fixtures/comment_tests.json b/parts/django/tests/regressiontests/comment_tests/fixtures/comment_tests.json deleted file mode 100644 index 55e2161..0000000 --- a/parts/django/tests/regressiontests/comment_tests/fixtures/comment_tests.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - { - "model" : "comment_tests.book", - "pk" : 1, - "fields" : { - "dewey_decimal" : "12.34" - } - }, - { - "model" : "comment_tests.author", - "pk" : 1, - "fields" : { - "first_name" : "John", - "last_name" : "Smith" - } - }, - { - "model" : "comment_tests.author", - "pk" : 2, - "fields" : { - "first_name" : "Peter", - "last_name" : "Jones" - } - }, - { - "model" : "comment_tests.article", - "pk" : 1, - "fields" : { - "author" : 1, - "headline" : "Man Bites Dog" - } - }, - { - "model" : "comment_tests.article", - "pk" : 2, - "fields" : { - "author" : 2, - "headline" : "Dog Bites Man" - } - }, - - { - "model" : "auth.user", - "pk" : 100, - "fields" : { - "username" : "normaluser", - "password" : "34ea4aaaf24efcbb4b30d27302f8657f", - "first_name": "Joe", - "last_name": "Normal", - "email": "joe.normal@example.com" - } - } -] diff --git a/parts/django/tests/regressiontests/comment_tests/fixtures/comment_utils.xml b/parts/django/tests/regressiontests/comment_tests/fixtures/comment_utils.xml deleted file mode 100644 index a39bbf6..0000000 --- a/parts/django/tests/regressiontests/comment_tests/fixtures/comment_utils.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="comment_tests.entry"> - <field type="CharField" name="title">ABC</field> - <field type="TextField" name="body">This is the body</field> - <field type="DateField" name="pub_date">2008-01-01</field> - <field type="BooleanField" name="enable_comments">True</field> - </object> - <object pk="2" model="comment_tests.entry"> - <field type="CharField" name="title">XYZ</field> - <field type="TextField" name="body">Text here</field> - <field type="DateField" name="pub_date">2008-01-02</field> - <field type="BooleanField" name="enable_comments">False</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/comment_tests/models.py b/parts/django/tests/regressiontests/comment_tests/models.py deleted file mode 100644 index 8877ea1..0000000 --- a/parts/django/tests/regressiontests/comment_tests/models.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -Comments may be attached to any object. See the comment documentation for -more information. -""" - -from django.db import models -from django.test import TestCase - -class Author(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - - def __str__(self): - return '%s %s' % (self.first_name, self.last_name) - -class Article(models.Model): - author = models.ForeignKey(Author) - headline = models.CharField(max_length=100) - - def __str__(self): - return self.headline - -class Entry(models.Model): - title = models.CharField(max_length=250) - body = models.TextField() - pub_date = models.DateField() - enable_comments = models.BooleanField() - - def __str__(self): - return self.title - -class Book(models.Model): - dewey_decimal = models.DecimalField(primary_key = True, decimal_places=2, max_digits=5) -
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/comment_tests/tests/__init__.py b/parts/django/tests/regressiontests/comment_tests/tests/__init__.py deleted file mode 100644 index 449fea4..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/__init__.py +++ /dev/null @@ -1,89 +0,0 @@ -from django.contrib.auth.models import User -from django.contrib.comments.forms import CommentForm -from django.contrib.comments.models import Comment -from django.contrib.contenttypes.models import ContentType -from django.contrib.sites.models import Site -from django.test import TestCase -from regressiontests.comment_tests.models import Article, Author - -# Shortcut -CT = ContentType.objects.get_for_model - -# Helper base class for comment tests that need data. -class CommentTestCase(TestCase): - fixtures = ["comment_tests"] - urls = 'django.contrib.comments.urls' - - def createSomeComments(self): - # Two anonymous comments on two different objects - c1 = Comment.objects.create( - content_type = CT(Article), - object_pk = "1", - user_name = "Joe Somebody", - user_email = "jsomebody@example.com", - user_url = "http://example.com/~joe/", - comment = "First!", - site = Site.objects.get_current(), - ) - c2 = Comment.objects.create( - content_type = CT(Author), - object_pk = "1", - user_name = "Joe Somebody", - user_email = "jsomebody@example.com", - user_url = "http://example.com/~joe/", - comment = "First here, too!", - site = Site.objects.get_current(), - ) - - # Two authenticated comments: one on the same Article, and - # one on a different Author - user = User.objects.create( - username = "frank_nobody", - first_name = "Frank", - last_name = "Nobody", - email = "fnobody@example.com", - password = "", - is_staff = False, - is_active = True, - is_superuser = False, - ) - c3 = Comment.objects.create( - content_type = CT(Article), - object_pk = "1", - user = user, - user_url = "http://example.com/~frank/", - comment = "Damn, I wanted to be first.", - site = Site.objects.get_current(), - ) - c4 = Comment.objects.create( - content_type = CT(Author), - object_pk = "2", - user = user, - user_url = "http://example.com/~frank/", - comment = "You get here first, too?", - site = Site.objects.get_current(), - ) - - return c1, c2, c3, c4 - - def getData(self): - return { - 'name' : 'Jim Bob', - 'email' : 'jim.bob@example.com', - 'url' : '', - 'comment' : 'This is my comment', - } - - def getValidData(self, obj): - f = CommentForm(obj) - d = self.getData() - d.update(f.initial) - return d - -from regressiontests.comment_tests.tests.app_api_tests import * -from regressiontests.comment_tests.tests.model_tests import * -from regressiontests.comment_tests.tests.comment_form_tests import * -from regressiontests.comment_tests.tests.templatetag_tests import * -from regressiontests.comment_tests.tests.comment_view_tests import * -from regressiontests.comment_tests.tests.moderation_view_tests import * -from regressiontests.comment_tests.tests.comment_utils_moderators_tests import * diff --git a/parts/django/tests/regressiontests/comment_tests/tests/app_api_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/app_api_tests.py deleted file mode 100644 index c4d9ebf..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/app_api_tests.py +++ /dev/null @@ -1,71 +0,0 @@ -from django.conf import settings -from django.contrib import comments -from django.contrib.comments.models import Comment -from django.contrib.comments.forms import CommentForm -from regressiontests.comment_tests.tests import CommentTestCase - -class CommentAppAPITests(CommentTestCase): - """Tests for the "comment app" API""" - - def testGetCommentApp(self): - self.assertEqual(comments.get_comment_app(), comments) - - def testGetForm(self): - self.assertEqual(comments.get_form(), CommentForm) - - def testGetFormTarget(self): - self.assertEqual(comments.get_form_target(), "/post/") - - def testGetFlagURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_flag_url(c), "/flag/12345/") - - def getGetDeleteURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_delete_url(c), "/delete/12345/") - - def getGetApproveURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_approve_url(c), "/approve/12345/") - - -class CustomCommentTest(CommentTestCase): - urls = 'regressiontests.comment_tests.urls' - - def setUp(self): - self.old_comments_app = getattr(settings, 'COMMENTS_APP', None) - settings.COMMENTS_APP = 'regressiontests.comment_tests.custom_comments' - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + [settings.COMMENTS_APP,] - - def tearDown(self): - del settings.INSTALLED_APPS[-1] - settings.COMMENTS_APP = self.old_comments_app - if settings.COMMENTS_APP is None: - delattr(settings._wrapped, 'COMMENTS_APP') - - def testGetCommentApp(self): - from regressiontests.comment_tests import custom_comments - self.assertEqual(comments.get_comment_app(), custom_comments) - - def testGetModel(self): - from regressiontests.comment_tests.custom_comments.models import CustomComment - self.assertEqual(comments.get_model(), CustomComment) - - def testGetForm(self): - from regressiontests.comment_tests.custom_comments.forms import CustomCommentForm - self.assertEqual(comments.get_form(), CustomCommentForm) - - def testGetFormTarget(self): - self.assertEqual(comments.get_form_target(), "/post/") - - def testGetFlagURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_flag_url(c), "/flag/12345/") - - def getGetDeleteURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_delete_url(c), "/delete/12345/") - - def getGetApproveURL(self): - c = Comment(id=12345) - self.assertEqual(comments.get_approve_url(c), "/approve/12345/") diff --git a/parts/django/tests/regressiontests/comment_tests/tests/comment_form_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/comment_form_tests.py deleted file mode 100644 index 8dfcc07..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/comment_form_tests.py +++ /dev/null @@ -1,84 +0,0 @@ -import time - -from django.conf import settings -from django.contrib.comments.forms import CommentForm -from django.contrib.comments.models import Comment -from django.utils.hashcompat import sha_constructor - -from regressiontests.comment_tests.models import Article -from regressiontests.comment_tests.tests import CommentTestCase - - -class CommentFormTests(CommentTestCase): - def testInit(self): - f = CommentForm(Article.objects.get(pk=1)) - self.assertEqual(f.initial['content_type'], str(Article._meta)) - self.assertEqual(f.initial['object_pk'], "1") - self.assertNotEqual(f.initial['security_hash'], None) - self.assertNotEqual(f.initial['timestamp'], None) - - def testValidPost(self): - a = Article.objects.get(pk=1) - f = CommentForm(a, data=self.getValidData(a)) - self.assert_(f.is_valid(), f.errors) - return f - - def tamperWithForm(self, **kwargs): - a = Article.objects.get(pk=1) - d = self.getValidData(a) - d.update(kwargs) - f = CommentForm(Article.objects.get(pk=1), data=d) - self.assertFalse(f.is_valid()) - return f - - def testHoneypotTampering(self): - self.tamperWithForm(honeypot="I am a robot") - - def testTimestampTampering(self): - self.tamperWithForm(timestamp=str(time.time() - 28800)) - - def testSecurityHashTampering(self): - self.tamperWithForm(security_hash="Nobody expects the Spanish Inquisition!") - - def testContentTypeTampering(self): - self.tamperWithForm(content_type="auth.user") - - def testObjectPKTampering(self): - self.tamperWithForm(object_pk="3") - - def testSecurityErrors(self): - f = self.tamperWithForm(honeypot="I am a robot") - self.assert_("honeypot" in f.security_errors()) - - def testGetCommentObject(self): - f = self.testValidPost() - c = f.get_comment_object() - self.assert_(isinstance(c, Comment)) - self.assertEqual(c.content_object, Article.objects.get(pk=1)) - self.assertEqual(c.comment, "This is my comment") - c.save() - self.assertEqual(Comment.objects.count(), 1) - - def testProfanities(self): - """Test COMMENTS_ALLOW_PROFANITIES and PROFANITIES_LIST settings""" - a = Article.objects.get(pk=1) - d = self.getValidData(a) - - # Save settings in case other tests need 'em - saved = settings.PROFANITIES_LIST, settings.COMMENTS_ALLOW_PROFANITIES - - # Don't wanna swear in the unit tests if we don't have to... - settings.PROFANITIES_LIST = ["rooster"] - - # Try with COMMENTS_ALLOW_PROFANITIES off - settings.COMMENTS_ALLOW_PROFANITIES = False - f = CommentForm(a, data=dict(d, comment="What a rooster!")) - self.assertFalse(f.is_valid()) - - # Now with COMMENTS_ALLOW_PROFANITIES on - settings.COMMENTS_ALLOW_PROFANITIES = True - f = CommentForm(a, data=dict(d, comment="What a rooster!")) - self.assertTrue(f.is_valid()) - - # Restore settings - settings.PROFANITIES_LIST, settings.COMMENTS_ALLOW_PROFANITIES = saved diff --git a/parts/django/tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py deleted file mode 100644 index 2e93b8b..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/comment_utils_moderators_tests.py +++ /dev/null @@ -1,75 +0,0 @@ -from regressiontests.comment_tests.tests import CommentTestCase, CT, Site -from django.contrib.comments.forms import CommentForm -from django.contrib.comments.models import Comment -from django.contrib.comments.moderation import moderator, CommentModerator, AlreadyModerated -from regressiontests.comment_tests.models import Entry -from django.core import mail - -class EntryModerator1(CommentModerator): - email_notification = True - -class EntryModerator2(CommentModerator): - enable_field = 'enable_comments' - -class EntryModerator3(CommentModerator): - auto_close_field = 'pub_date' - close_after = 7 - -class EntryModerator4(CommentModerator): - auto_moderate_field = 'pub_date' - moderate_after = 7 - -class CommentUtilsModeratorTests(CommentTestCase): - fixtures = ["comment_utils.xml"] - - def createSomeComments(self): - # Tests for the moderation signals must actually post data - # through the comment views, because only the comment views - # emit the custom signals moderation listens for. - e = Entry.objects.get(pk=1) - data = self.getValidData(e) - - self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4") - - # We explicitly do a try/except to get the comment we've just - # posted because moderation may have disallowed it, in which - # case we can just return it as None. - try: - c1 = Comment.objects.all()[0] - except IndexError: - c1 = None - - self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4") - - try: - c2 = Comment.objects.all()[0] - except IndexError: - c2 = None - return c1, c2 - - def tearDown(self): - moderator.unregister(Entry) - - def testRegisterExistingModel(self): - moderator.register(Entry, EntryModerator1) - self.assertRaises(AlreadyModerated, moderator.register, Entry, EntryModerator1) - - def testEmailNotification(self): - moderator.register(Entry, EntryModerator1) - self.createSomeComments() - self.assertEquals(len(mail.outbox), 2) - - def testCommentsEnabled(self): - moderator.register(Entry, EntryModerator2) - self.createSomeComments() - self.assertEquals(Comment.objects.all().count(), 1) - - def testAutoCloseField(self): - moderator.register(Entry, EntryModerator3) - self.createSomeComments() - self.assertEquals(Comment.objects.all().count(), 0) - - def testAutoModerateField(self): - moderator.register(Entry, EntryModerator4) - c1, c2 = self.createSomeComments() - self.assertEquals(c2.is_public, False) diff --git a/parts/django/tests/regressiontests/comment_tests/tests/comment_view_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/comment_view_tests.py deleted file mode 100644 index b8a62b4..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/comment_view_tests.py +++ /dev/null @@ -1,258 +0,0 @@ -import re -from django.conf import settings -from django.contrib.auth.models import User -from django.contrib.comments import signals -from django.contrib.comments.models import Comment -from regressiontests.comment_tests.models import Article, Book -from regressiontests.comment_tests.tests import CommentTestCase - -post_redirect_re = re.compile(r'^http://testserver/posted/\?c=(?P<pk>\d+$)') - -class CommentViewTests(CommentTestCase): - - def testPostCommentHTTPMethods(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - response = self.client.get("/post/", data) - self.assertEqual(response.status_code, 405) - self.assertEqual(response["Allow"], "POST") - - def testPostCommentMissingCtype(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - del data["content_type"] - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testPostCommentBadCtype(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["content_type"] = "Nobody expects the Spanish Inquisition!" - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testPostCommentMissingObjectPK(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - del data["object_pk"] - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testPostCommentBadObjectPK(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["object_pk"] = "14" - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testPostInvalidIntegerPK(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["comment"] = "This is another comment" - data["object_pk"] = u'\ufffd' - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testPostInvalidDecimalPK(self): - b = Book.objects.get(pk='12.34') - data = self.getValidData(b) - data["comment"] = "This is another comment" - data["object_pk"] = 'cookies' - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testCommentPreview(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["preview"] = "Preview" - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "comments/preview.html") - - def testHashTampering(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["security_hash"] = "Nobody expects the Spanish Inquisition!" - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - - def testDebugCommentErrors(self): - """The debug error template should be shown only if DEBUG is True""" - olddebug = settings.DEBUG - - settings.DEBUG = True - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["security_hash"] = "Nobody expects the Spanish Inquisition!" - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - self.assertTemplateUsed(response, "comments/400-debug.html") - - settings.DEBUG = False - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - self.assertTemplateNotUsed(response, "comments/400-debug.html") - - settings.DEBUG = olddebug - - def testCreateValidComment(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4") - self.assertEqual(self.response.status_code, 302) - self.assertEqual(Comment.objects.count(), 1) - c = Comment.objects.all()[0] - self.assertEqual(c.ip_address, "1.2.3.4") - self.assertEqual(c.comment, "This is my comment") - - def testPostAsAuthenticatedUser(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data['name'] = data['email'] = '' - self.client.login(username="normaluser", password="normaluser") - self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4") - self.assertEqual(self.response.status_code, 302) - self.assertEqual(Comment.objects.count(), 1) - c = Comment.objects.all()[0] - self.assertEqual(c.ip_address, "1.2.3.4") - u = User.objects.get(username='normaluser') - self.assertEqual(c.user, u) - self.assertEqual(c.user_name, u.get_full_name()) - self.assertEqual(c.user_email, u.email) - - def testPostAsAuthenticatedUserWithoutFullname(self): - """ - Check that the user's name in the comment is populated for - authenticated users without first_name and last_name. - """ - user = User.objects.create_user(username='jane_other', - email='jane@example.com', password='jane_other') - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data['name'] = data['email'] = '' - self.client.login(username="jane_other", password="jane_other") - self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4") - c = Comment.objects.get(user=user) - self.assertEqual(c.ip_address, "1.2.3.4") - self.assertEqual(c.user_name, 'jane_other') - user.delete() - - def testPreventDuplicateComments(self): - """Prevent posting the exact same comment twice""" - a = Article.objects.get(pk=1) - data = self.getValidData(a) - self.client.post("/post/", data) - self.client.post("/post/", data) - self.assertEqual(Comment.objects.count(), 1) - - # This should not trigger the duplicate prevention - self.client.post("/post/", dict(data, comment="My second comment.")) - self.assertEqual(Comment.objects.count(), 2) - - def testCommentSignals(self): - """Test signals emitted by the comment posting view""" - - # callback - def receive(sender, **kwargs): - self.assertEqual(kwargs['comment'].comment, "This is my comment") - self.assert_('request' in kwargs) - received_signals.append(kwargs.get('signal')) - - # Connect signals and keep track of handled ones - received_signals = [] - expected_signals = [ - signals.comment_will_be_posted, signals.comment_was_posted - ] - for signal in expected_signals: - signal.connect(receive) - - # Post a comment and check the signals - self.testCreateValidComment() - self.assertEqual(received_signals, expected_signals) - - for signal in expected_signals: - signal.disconnect(receive) - - def testWillBePostedSignal(self): - """ - Test that the comment_will_be_posted signal can prevent the comment from - actually getting saved - """ - def receive(sender, **kwargs): return False - signals.comment_will_be_posted.connect(receive, dispatch_uid="comment-test") - a = Article.objects.get(pk=1) - data = self.getValidData(a) - response = self.client.post("/post/", data) - self.assertEqual(response.status_code, 400) - self.assertEqual(Comment.objects.count(), 0) - signals.comment_will_be_posted.disconnect(dispatch_uid="comment-test") - - def testWillBePostedSignalModifyComment(self): - """ - Test that the comment_will_be_posted signal can modify a comment before - it gets posted - """ - def receive(sender, **kwargs): - # a bad but effective spam filter :)... - kwargs['comment'].is_public = False - - signals.comment_will_be_posted.connect(receive) - self.testCreateValidComment() - c = Comment.objects.all()[0] - self.assertFalse(c.is_public) - - def testCommentNext(self): - """Test the different "next" actions the comment view can take""" - a = Article.objects.get(pk=1) - data = self.getValidData(a) - response = self.client.post("/post/", data) - location = response["Location"] - match = post_redirect_re.match(location) - self.assertTrue(match != None, "Unexpected redirect location: %s" % location) - - data["next"] = "/somewhere/else/" - data["comment"] = "This is another comment" - response = self.client.post("/post/", data) - location = response["Location"] - match = re.search(r"^http://testserver/somewhere/else/\?c=\d+$", location) - self.assertTrue(match != None, "Unexpected redirect location: %s" % location) - - def testCommentDoneView(self): - a = Article.objects.get(pk=1) - data = self.getValidData(a) - response = self.client.post("/post/", data) - location = response["Location"] - match = post_redirect_re.match(location) - self.assertTrue(match != None, "Unexpected redirect location: %s" % location) - pk = int(match.group('pk')) - response = self.client.get(location) - self.assertTemplateUsed(response, "comments/posted.html") - self.assertEqual(response.context[0]["comment"], Comment.objects.get(pk=pk)) - - def testCommentNextWithQueryString(self): - """ - The `next` key needs to handle already having a query string (#10585) - """ - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["next"] = "/somewhere/else/?foo=bar" - data["comment"] = "This is another comment" - response = self.client.post("/post/", data) - location = response["Location"] - match = re.search(r"^http://testserver/somewhere/else/\?foo=bar&c=\d+$", location) - self.assertTrue(match != None, "Unexpected redirect location: %s" % location) - - def testCommentPostRedirectWithInvalidIntegerPK(self): - """ - Tests that attempting to retrieve the location specified in the - post redirect, after adding some invalid data to the expected - querystring it ends with, doesn't cause a server error. - """ - a = Article.objects.get(pk=1) - data = self.getValidData(a) - data["comment"] = "This is another comment" - response = self.client.post("/post/", data) - location = response["Location"] - broken_location = location + u"\ufffd" - response = self.client.get(broken_location) - self.assertEqual(response.status_code, 200) diff --git a/parts/django/tests/regressiontests/comment_tests/tests/model_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/model_tests.py deleted file mode 100644 index 2cbf66f..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/model_tests.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.contrib.comments.models import Comment - -from regressiontests.comment_tests.models import Author, Article -from regressiontests.comment_tests.tests import CommentTestCase - - -class CommentModelTests(CommentTestCase): - def testSave(self): - for c in self.createSomeComments(): - self.assertNotEqual(c.submit_date, None) - - def testUserProperties(self): - c1, c2, c3, c4 = self.createSomeComments() - self.assertEqual(c1.name, "Joe Somebody") - self.assertEqual(c2.email, "jsomebody@example.com") - self.assertEqual(c3.name, "Frank Nobody") - self.assertEqual(c3.url, "http://example.com/~frank/") - self.assertEqual(c1.user, None) - self.assertEqual(c3.user, c4.user) - -class CommentManagerTests(CommentTestCase): - - def testInModeration(self): - """Comments that aren't public are considered in moderation""" - c1, c2, c3, c4 = self.createSomeComments() - c1.is_public = False - c2.is_public = False - c1.save() - c2.save() - moderated_comments = list(Comment.objects.in_moderation().order_by("id")) - self.assertEqual(moderated_comments, [c1, c2]) - - def testRemovedCommentsNotInModeration(self): - """Removed comments are not considered in moderation""" - c1, c2, c3, c4 = self.createSomeComments() - c1.is_public = False - c2.is_public = False - c2.is_removed = True - c1.save() - c2.save() - moderated_comments = list(Comment.objects.in_moderation()) - self.assertEqual(moderated_comments, [c1]) - - def testForModel(self): - c1, c2, c3, c4 = self.createSomeComments() - article_comments = list(Comment.objects.for_model(Article).order_by("id")) - author_comments = list(Comment.objects.for_model(Author.objects.get(pk=1))) - self.assertEqual(article_comments, [c1, c3]) - self.assertEqual(author_comments, [c2]) diff --git a/parts/django/tests/regressiontests/comment_tests/tests/moderation_view_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/moderation_view_tests.py deleted file mode 100644 index e5094ab..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/moderation_view_tests.py +++ /dev/null @@ -1,203 +0,0 @@ -from django.contrib.auth.models import User, Permission -from django.contrib.comments import signals -from django.contrib.comments.models import Comment, CommentFlag -from django.contrib.contenttypes.models import ContentType - -from regressiontests.comment_tests.tests import CommentTestCase - - -class FlagViewTests(CommentTestCase): - - def testFlagGet(self): - """GET the flag view: render a confirmation page.""" - comments = self.createSomeComments() - pk = comments[0].pk - self.client.login(username="normaluser", password="normaluser") - response = self.client.get("/flag/%d/" % pk) - self.assertTemplateUsed(response, "comments/flag.html") - - def testFlagPost(self): - """POST the flag view: actually flag the view (nice for XHR)""" - comments = self.createSomeComments() - pk = comments[0].pk - self.client.login(username="normaluser", password="normaluser") - response = self.client.post("/flag/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/flagged/?c=%d" % pk) - c = Comment.objects.get(pk=pk) - self.assertEqual(c.flags.filter(flag=CommentFlag.SUGGEST_REMOVAL).count(), 1) - return c - - def testFlagPostTwice(self): - """Users don't get to flag comments more than once.""" - c = self.testFlagPost() - self.client.post("/flag/%d/" % c.pk) - self.client.post("/flag/%d/" % c.pk) - self.assertEqual(c.flags.filter(flag=CommentFlag.SUGGEST_REMOVAL).count(), 1) - - def testFlagAnon(self): - """GET/POST the flag view while not logged in: redirect to log in.""" - comments = self.createSomeComments() - pk = comments[0].pk - response = self.client.get("/flag/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/%d/" % pk) - response = self.client.post("/flag/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/%d/" % pk) - - def testFlaggedView(self): - comments = self.createSomeComments() - pk = comments[0].pk - response = self.client.get("/flagged/", data={"c":pk}) - self.assertTemplateUsed(response, "comments/flagged.html") - - def testFlagSignals(self): - """Test signals emitted by the comment flag view""" - - # callback - def receive(sender, **kwargs): - self.assertEqual(kwargs['flag'].flag, CommentFlag.SUGGEST_REMOVAL) - self.assertEqual(kwargs['request'].user.username, "normaluser") - received_signals.append(kwargs.get('signal')) - - # Connect signals and keep track of handled ones - received_signals = [] - signals.comment_was_flagged.connect(receive) - - # Post a comment and check the signals - self.testFlagPost() - self.assertEqual(received_signals, [signals.comment_was_flagged]) - -def makeModerator(username): - u = User.objects.get(username=username) - ct = ContentType.objects.get_for_model(Comment) - p = Permission.objects.get(content_type=ct, codename="can_moderate") - u.user_permissions.add(p) - -class DeleteViewTests(CommentTestCase): - - def testDeletePermissions(self): - """The delete view should only be accessible to 'moderators'""" - comments = self.createSomeComments() - pk = comments[0].pk - self.client.login(username="normaluser", password="normaluser") - response = self.client.get("/delete/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/delete/%d/" % pk) - - makeModerator("normaluser") - response = self.client.get("/delete/%d/" % pk) - self.assertEqual(response.status_code, 200) - - def testDeletePost(self): - """POSTing the delete view should mark the comment as removed""" - comments = self.createSomeComments() - pk = comments[0].pk - makeModerator("normaluser") - self.client.login(username="normaluser", password="normaluser") - response = self.client.post("/delete/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/deleted/?c=%d" % pk) - c = Comment.objects.get(pk=pk) - self.assertTrue(c.is_removed) - self.assertEqual(c.flags.filter(flag=CommentFlag.MODERATOR_DELETION, user__username="normaluser").count(), 1) - - def testDeleteSignals(self): - def receive(sender, **kwargs): - received_signals.append(kwargs.get('signal')) - - # Connect signals and keep track of handled ones - received_signals = [] - signals.comment_was_flagged.connect(receive) - - # Post a comment and check the signals - self.testDeletePost() - self.assertEqual(received_signals, [signals.comment_was_flagged]) - - def testDeletedView(self): - comments = self.createSomeComments() - pk = comments[0].pk - response = self.client.get("/deleted/", data={"c":pk}) - self.assertTemplateUsed(response, "comments/deleted.html") - -class ApproveViewTests(CommentTestCase): - - def testApprovePermissions(self): - """The delete view should only be accessible to 'moderators'""" - comments = self.createSomeComments() - pk = comments[0].pk - self.client.login(username="normaluser", password="normaluser") - response = self.client.get("/approve/%d/" % pk) - self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/approve/%d/" % pk) - - makeModerator("normaluser") - response = self.client.get("/approve/%d/" % pk) - self.assertEqual(response.status_code, 200) - - def testApprovePost(self): - """POSTing the delete view should mark the comment as removed""" - c1, c2, c3, c4 = self.createSomeComments() - c1.is_public = False; c1.save() - - makeModerator("normaluser") - self.client.login(username="normaluser", password="normaluser") - response = self.client.post("/approve/%d/" % c1.pk) - self.assertEqual(response["Location"], "http://testserver/approved/?c=%d" % c1.pk) - c = Comment.objects.get(pk=c1.pk) - self.assertTrue(c.is_public) - self.assertEqual(c.flags.filter(flag=CommentFlag.MODERATOR_APPROVAL, user__username="normaluser").count(), 1) - - def testApproveSignals(self): - def receive(sender, **kwargs): - received_signals.append(kwargs.get('signal')) - - # Connect signals and keep track of handled ones - received_signals = [] - signals.comment_was_flagged.connect(receive) - - # Post a comment and check the signals - self.testApprovePost() - self.assertEqual(received_signals, [signals.comment_was_flagged]) - - def testApprovedView(self): - comments = self.createSomeComments() - pk = comments[0].pk - response = self.client.get("/approved/", data={"c":pk}) - self.assertTemplateUsed(response, "comments/approved.html") - -class AdminActionsTests(CommentTestCase): - urls = "regressiontests.comment_tests.urls_admin" - - def setUp(self): - super(AdminActionsTests, self).setUp() - - # Make "normaluser" a moderator - u = User.objects.get(username="normaluser") - u.is_staff = True - perms = Permission.objects.filter( - content_type__app_label = 'comments', - codename__endswith = 'comment' - ) - for perm in perms: - u.user_permissions.add(perm) - u.save() - - def testActionsNonModerator(self): - comments = self.createSomeComments() - self.client.login(username="normaluser", password="normaluser") - response = self.client.get("/admin/comments/comment/") - self.assertEquals("approve_comments" in response.content, False) - - def testActionsModerator(self): - comments = self.createSomeComments() - makeModerator("normaluser") - self.client.login(username="normaluser", password="normaluser") - response = self.client.get("/admin/comments/comment/") - self.assertEquals("approve_comments" in response.content, True) - - def testActionsDisabledDelete(self): - "Tests a CommentAdmin where 'delete_selected' has been disabled." - comments = self.createSomeComments() - self.client.login(username="normaluser", password="normaluser") - response = self.client.get('/admin2/comments/comment/') - self.assertEqual(response.status_code, 200) - self.assert_( - '<option value="delete_selected">' not in response.content, - "Found an unexpected delete_selected in response" - ) diff --git a/parts/django/tests/regressiontests/comment_tests/tests/templatetag_tests.py b/parts/django/tests/regressiontests/comment_tests/tests/templatetag_tests.py deleted file mode 100644 index 29a097a..0000000 --- a/parts/django/tests/regressiontests/comment_tests/tests/templatetag_tests.py +++ /dev/null @@ -1,97 +0,0 @@ -from django.contrib.comments.forms import CommentForm -from django.contrib.comments.models import Comment -from django.contrib.contenttypes.models import ContentType -from django.template import Template, Context -from regressiontests.comment_tests.models import Article, Author -from regressiontests.comment_tests.tests import CommentTestCase - -class CommentTemplateTagTests(CommentTestCase): - - def render(self, t, **c): - ctx = Context(c) - out = Template(t).render(ctx) - return ctx, out - - def testCommentFormTarget(self): - ctx, out = self.render("{% load comments %}{% comment_form_target %}") - self.assertEqual(out, "/post/") - - def testGetCommentForm(self, tag=None): - t = "{% load comments %}" + (tag or "{% get_comment_form for comment_tests.article a.id as form %}") - ctx, out = self.render(t, a=Article.objects.get(pk=1)) - self.assertEqual(out, "") - self.assert_(isinstance(ctx["form"], CommentForm)) - - def testGetCommentFormFromLiteral(self): - self.testGetCommentForm("{% get_comment_form for comment_tests.article 1 as form %}") - - def testGetCommentFormFromObject(self): - self.testGetCommentForm("{% get_comment_form for a as form %}") - - def testRenderCommentForm(self, tag=None): - t = "{% load comments %}" + (tag or "{% render_comment_form for comment_tests.article a.id %}") - ctx, out = self.render(t, a=Article.objects.get(pk=1)) - self.assert_(out.strip().startswith("<form action=")) - self.assert_(out.strip().endswith("</form>")) - - def testRenderCommentFormFromLiteral(self): - self.testRenderCommentForm("{% render_comment_form for comment_tests.article 1 %}") - - def testRenderCommentFormFromObject(self): - self.testRenderCommentForm("{% render_comment_form for a %}") - - def testGetCommentCount(self, tag=None): - self.createSomeComments() - t = "{% load comments %}" + (tag or "{% get_comment_count for comment_tests.article a.id as cc %}") + "{{ cc }}" - ctx, out = self.render(t, a=Article.objects.get(pk=1)) - self.assertEqual(out, "2") - - def testGetCommentCountFromLiteral(self): - self.testGetCommentCount("{% get_comment_count for comment_tests.article 1 as cc %}") - - def testGetCommentCountFromObject(self): - self.testGetCommentCount("{% get_comment_count for a as cc %}") - - def testGetCommentList(self, tag=None): - c1, c2, c3, c4 = self.createSomeComments() - t = "{% load comments %}" + (tag or "{% get_comment_list for comment_tests.author a.id as cl %}") - ctx, out = self.render(t, a=Author.objects.get(pk=1)) - self.assertEqual(out, "") - self.assertEqual(list(ctx["cl"]), [c2]) - - def testGetCommentListFromLiteral(self): - self.testGetCommentList("{% get_comment_list for comment_tests.author 1 as cl %}") - - def testGetCommentListFromObject(self): - self.testGetCommentList("{% get_comment_list for a as cl %}") - - def testGetCommentPermalink(self): - c1, c2, c3, c4 = self.createSomeComments() - t = "{% load comments %}{% get_comment_list for comment_tests.author author.id as cl %}" - t += "{% get_comment_permalink cl.0 %}" - ct = ContentType.objects.get_for_model(Author) - author = Author.objects.get(pk=1) - ctx, out = self.render(t, author=author) - self.assertEqual(out, "/cr/%s/%s/#c%s" % (ct.id, author.id, c2.id)) - - def testGetCommentPermalinkFormatted(self): - c1, c2, c3, c4 = self.createSomeComments() - t = "{% load comments %}{% get_comment_list for comment_tests.author author.id as cl %}" - t += "{% get_comment_permalink cl.0 '#c%(id)s-by-%(user_name)s' %}" - ct = ContentType.objects.get_for_model(Author) - author = Author.objects.get(pk=1) - ctx, out = self.render(t, author=author) - self.assertEqual(out, "/cr/%s/%s/#c%s-by-Joe Somebody" % (ct.id, author.id, c2.id)) - - def testRenderCommentList(self, tag=None): - t = "{% load comments %}" + (tag or "{% render_comment_list for comment_tests.article a.id %}") - ctx, out = self.render(t, a=Article.objects.get(pk=1)) - self.assert_(out.strip().startswith("<dl id=\"comments\">")) - self.assert_(out.strip().endswith("</dl>")) - - def testRenderCommentListFromLiteral(self): - self.testRenderCommentList("{% render_comment_list for comment_tests.article 1 %}") - - def testRenderCommentListFromObject(self): - self.testRenderCommentList("{% render_comment_list for a %}") - diff --git a/parts/django/tests/regressiontests/comment_tests/urls.py b/parts/django/tests/regressiontests/comment_tests/urls.py deleted file mode 100644 index 0058689..0000000 --- a/parts/django/tests/regressiontests/comment_tests/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('regressiontests.comment_tests.custom_comments.views', - url(r'^post/$', 'custom_submit_comment'), - url(r'^flag/(\d+)/$', 'custom_flag_comment'), - url(r'^delete/(\d+)/$', 'custom_delete_comment'), - url(r'^approve/(\d+)/$', 'custom_approve_comment'), -) - diff --git a/parts/django/tests/regressiontests/comment_tests/urls_admin.py b/parts/django/tests/regressiontests/comment_tests/urls_admin.py deleted file mode 100644 index d7e1a4e..0000000 --- a/parts/django/tests/regressiontests/comment_tests/urls_admin.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.conf.urls.defaults import * -from django.contrib import admin -from django.contrib.comments.admin import CommentsAdmin -from django.contrib.comments.models import Comment - -# Make a new AdminSite to avoid picking up the deliberately broken admin -# modules in other tests. -admin_site = admin.AdminSite() -admin_site.register(Comment, CommentsAdmin) - -# To demonstrate proper functionality even when ``delete_selected`` is removed. -admin_site2 = admin.AdminSite() -admin_site2.disable_action('delete_selected') -admin_site2.register(Comment, CommentsAdmin) - -urlpatterns = patterns('', - (r'^admin/', include(admin_site.urls)), - (r'^admin2/', include(admin_site2.urls)), -) diff --git a/parts/django/tests/regressiontests/conditional_processing/__init__.py b/parts/django/tests/regressiontests/conditional_processing/__init__.py deleted file mode 100644 index 380474e..0000000 --- a/parts/django/tests/regressiontests/conditional_processing/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# -*- coding:utf-8 -*- diff --git a/parts/django/tests/regressiontests/conditional_processing/models.py b/parts/django/tests/regressiontests/conditional_processing/models.py deleted file mode 100644 index b291aed..0000000 --- a/parts/django/tests/regressiontests/conditional_processing/models.py +++ /dev/null @@ -1,128 +0,0 @@ -# -*- coding:utf-8 -*- -from datetime import datetime, timedelta -from calendar import timegm - -from django.test import TestCase -from django.utils.http import parse_etags, quote_etag - -FULL_RESPONSE = 'Test conditional get response' -LAST_MODIFIED = datetime(2007, 10, 21, 23, 21, 47) -LAST_MODIFIED_STR = 'Sun, 21 Oct 2007 23:21:47 GMT' -EXPIRED_LAST_MODIFIED_STR = 'Sat, 20 Oct 2007 23:21:47 GMT' -ETAG = 'b4246ffc4f62314ca13147c9d4f76974' -EXPIRED_ETAG = '7fae4cd4b0f81e7d2914700043aa8ed6' - -class ConditionalGet(TestCase): - def assertFullResponse(self, response, check_last_modified=True, check_etag=True): - self.assertEquals(response.status_code, 200) - self.assertEquals(response.content, FULL_RESPONSE) - if check_last_modified: - self.assertEquals(response['Last-Modified'], LAST_MODIFIED_STR) - if check_etag: - self.assertEquals(response['ETag'], '"%s"' % ETAG) - - def assertNotModified(self, response): - self.assertEquals(response.status_code, 304) - self.assertEquals(response.content, '') - - def testWithoutConditions(self): - response = self.client.get('/condition/') - self.assertFullResponse(response) - - def testIfModifiedSince(self): - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR - response = self.client.get('/condition/') - self.assertNotModified(response) - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR - response = self.client.get('/condition/') - self.assertFullResponse(response) - - def testIfNoneMatch(self): - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG - response = self.client.get('/condition/') - self.assertNotModified(response) - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG - response = self.client.get('/condition/') - self.assertFullResponse(response) - - # Several etags in If-None-Match is a bit exotic but why not? - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s", "%s"' % (ETAG, EXPIRED_ETAG) - response = self.client.get('/condition/') - self.assertNotModified(response) - - def testIfMatch(self): - self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % ETAG - response = self.client.put('/condition/etag/', {'data': ''}) - self.assertEquals(response.status_code, 200) - self.client.defaults['HTTP_IF_MATCH'] = '"%s"' % EXPIRED_ETAG - response = self.client.put('/condition/etag/', {'data': ''}) - self.assertEquals(response.status_code, 412) - - def testBothHeaders(self): - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG - response = self.client.get('/condition/') - self.assertNotModified(response) - - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG - response = self.client.get('/condition/') - self.assertFullResponse(response) - - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG - response = self.client.get('/condition/') - self.assertFullResponse(response) - - def testSingleCondition1(self): - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR - response = self.client.get('/condition/last_modified/') - self.assertNotModified(response) - response = self.client.get('/condition/etag/') - self.assertFullResponse(response, check_last_modified=False) - - def testSingleCondition2(self): - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG - response = self.client.get('/condition/etag/') - self.assertNotModified(response) - response = self.client.get('/condition/last_modified/') - self.assertFullResponse(response, check_etag=False) - - def testSingleCondition3(self): - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR - response = self.client.get('/condition/last_modified/') - self.assertFullResponse(response, check_etag=False) - - def testSingleCondition4(self): - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % EXPIRED_ETAG - response = self.client.get('/condition/etag/') - self.assertFullResponse(response, check_last_modified=False) - - def testSingleCondition5(self): - self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR - response = self.client.get('/condition/last_modified2/') - self.assertNotModified(response) - response = self.client.get('/condition/etag2/') - self.assertFullResponse(response, check_last_modified=False) - - def testSingleCondition6(self): - self.client.defaults['HTTP_IF_NONE_MATCH'] = '"%s"' % ETAG - response = self.client.get('/condition/etag2/') - self.assertNotModified(response) - response = self.client.get('/condition/last_modified2/') - self.assertFullResponse(response, check_etag=False) - - def testInvalidETag(self): - self.client.defaults['HTTP_IF_NONE_MATCH'] = r'"\"' - response = self.client.get('/condition/etag/') - self.assertFullResponse(response, check_last_modified=False) - - -class ETagProcesing(TestCase): - def testParsing(self): - etags = parse_etags(r'"", "etag", "e\"t\"ag", "e\\tag", W/"weak"') - self.assertEquals(etags, ['', 'etag', 'e"t"ag', r'e\tag', 'weak']) - - def testQuoting(self): - quoted_etag = quote_etag(r'e\t"ag') - self.assertEquals(quoted_etag, r'"e\\t\"ag"') diff --git a/parts/django/tests/regressiontests/conditional_processing/urls.py b/parts/django/tests/regressiontests/conditional_processing/urls.py deleted file mode 100644 index 4dbe11a..0000000 --- a/parts/django/tests/regressiontests/conditional_processing/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.conf.urls.defaults import * -import views - -urlpatterns = patterns('', - ('^$', views.index), - ('^last_modified/$', views.last_modified_view1), - ('^last_modified2/$', views.last_modified_view2), - ('^etag/$', views.etag_view1), - ('^etag2/$', views.etag_view2), -) diff --git a/parts/django/tests/regressiontests/conditional_processing/views.py b/parts/django/tests/regressiontests/conditional_processing/views.py deleted file mode 100644 index df49281..0000000 --- a/parts/django/tests/regressiontests/conditional_processing/views.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding:utf-8 -*- -from django.views.decorators.http import condition, etag, last_modified -from django.http import HttpResponse - -from models import FULL_RESPONSE, LAST_MODIFIED, ETAG - -def index(request): - return HttpResponse(FULL_RESPONSE) -index = condition(lambda r: ETAG, lambda r: LAST_MODIFIED)(index) - -def last_modified_view1(request): - return HttpResponse(FULL_RESPONSE) -last_modified_view1 = condition(last_modified_func=lambda r: LAST_MODIFIED)(last_modified_view1) - -def last_modified_view2(request): - return HttpResponse(FULL_RESPONSE) -last_modified_view2 = last_modified(lambda r: LAST_MODIFIED)(last_modified_view2) - -def etag_view1(request): - return HttpResponse(FULL_RESPONSE) -etag_view1 = condition(etag_func=lambda r: ETAG)(etag_view1) - -def etag_view2(request): - return HttpResponse(FULL_RESPONSE) -etag_view2 = etag(lambda r: ETAG)(etag_view2) - diff --git a/parts/django/tests/regressiontests/context_processors/__init__.py b/parts/django/tests/regressiontests/context_processors/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/context_processors/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/context_processors/fixtures/context-processors-users.xml b/parts/django/tests/regressiontests/context_processors/fixtures/context-processors-users.xml deleted file mode 100644 index aba8f4a..0000000 --- a/parts/django/tests/regressiontests/context_processors/fixtures/context-processors-users.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/context_processors/models.py b/parts/django/tests/regressiontests/context_processors/models.py deleted file mode 100644 index cde172d..0000000 --- a/parts/django/tests/regressiontests/context_processors/models.py +++ /dev/null @@ -1 +0,0 @@ -# Models file for tests to run. diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_access.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_access.html deleted file mode 100644 index b5c65db..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_access.html +++ /dev/null @@ -1 +0,0 @@ -{{ user }} diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_messages.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_messages.html deleted file mode 100644 index 7b7e448..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_messages.html +++ /dev/null @@ -1 +0,0 @@ -{% for m in messages %}{{ m }}{% endfor %} diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_no_access.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_no_access.html deleted file mode 100644 index 8d1c8b6..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_no_access.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_perms.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_perms.html deleted file mode 100644 index a5db868..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_perms.html +++ /dev/null @@ -1 +0,0 @@ -{% if perms.auth %}Has auth permissions{% endif %} diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_test_access.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_test_access.html deleted file mode 100644 index a28ff93..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_test_access.html +++ /dev/null @@ -1 +0,0 @@ -{% if session_accessed %}Session accessed{% else %}Session not accessed{% endif %} diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_user.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_user.html deleted file mode 100644 index 7ed16d7..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/auth_attrs_user.html +++ /dev/null @@ -1,4 +0,0 @@ -unicode: {{ user }} -id: {{ user.id }} -username: {{ user.username }} -url: {% url userpage user %} diff --git a/parts/django/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html b/parts/django/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html deleted file mode 100644 index 3978e9d..0000000 --- a/parts/django/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html +++ /dev/null @@ -1,13 +0,0 @@ -{% if request %} -Have request -{% else %} -No request -{% endif %} - -{% if request.is_secure %} -Secure -{% else %} -Not secure -{% endif %} - -{{ request.path }} diff --git a/parts/django/tests/regressiontests/context_processors/tests.py b/parts/django/tests/regressiontests/context_processors/tests.py deleted file mode 100644 index 0d19bef..0000000 --- a/parts/django/tests/regressiontests/context_processors/tests.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -Tests for Django's bundled context processors. -""" - -from django.conf import settings -from django.contrib.auth import authenticate -from django.db.models import Q -from django.test import TestCase -from django.template import Template - -class RequestContextProcessorTests(TestCase): - """ - Tests for the ``django.core.context_processors.request`` processor. - """ - - urls = 'regressiontests.context_processors.urls' - - def test_request_attributes(self): - """ - Test that the request object is available in the template and that its - attributes can't be overridden by GET and POST parameters (#3828). - """ - url = '/request_attrs/' - # We should have the request object in the template. - response = self.client.get(url) - self.assertContains(response, 'Have request') - # Test is_secure. - response = self.client.get(url) - self.assertContains(response, 'Not secure') - response = self.client.get(url, {'is_secure': 'blah'}) - self.assertContains(response, 'Not secure') - response = self.client.post(url, {'is_secure': 'blah'}) - self.assertContains(response, 'Not secure') - # Test path. - response = self.client.get(url) - self.assertContains(response, url) - response = self.client.get(url, {'path': '/blah/'}) - self.assertContains(response, url) - response = self.client.post(url, {'path': '/blah/'}) - self.assertContains(response, url) - -class AuthContextProcessorTests(TestCase): - """ - Tests for the ``django.contrib.auth.context_processors.auth`` processor - """ - urls = 'regressiontests.context_processors.urls' - fixtures = ['context-processors-users.xml'] - - def test_session_not_accessed(self): - """ - Tests that the session is not accessed simply by including - the auth context processor - """ - response = self.client.get('/auth_processor_no_attr_access/') - self.assertContains(response, "Session not accessed") - - def test_session_is_accessed(self): - """ - Tests that the session is accessed if the auth context processor - is used and relevant attributes accessed. - """ - response = self.client.get('/auth_processor_attr_access/') - self.assertContains(response, "Session accessed") - - def test_perms_attrs(self): - self.client.login(username='super', password='secret') - response = self.client.get('/auth_processor_perms/') - self.assertContains(response, "Has auth permissions") - - def test_message_attrs(self): - self.client.login(username='super', password='secret') - response = self.client.get('/auth_processor_messages/') - self.assertContains(response, "Message 1") - - def test_user_attrs(self): - """ - Test that the lazy objects returned behave just like the wrapped objects. - """ - # These are 'functional' level tests for common use cases. Direct - # testing of the implementation (SimpleLazyObject) is in the 'utils' - # tests. - self.client.login(username='super', password='secret') - user = authenticate(username='super', password='secret') - response = self.client.get('/auth_processor_user/') - self.assertContains(response, "unicode: super") - self.assertContains(response, "id: 100") - self.assertContains(response, "username: super") - # bug #12037 is tested by the {% url %} in the template: - self.assertContains(response, "url: /userpage/super/") - - # See if this object can be used for queries where a Q() comparing - # a user can be used with another Q() (in an AND or OR fashion). - # This simulates what a template tag might do with the user from the - # context. Note that we don't need to execute a query, just build it. - # - # The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped - # User is a fatal TypeError: "function() takes at least 2 arguments - # (0 given)" deep inside deepcopy(). - # - # Python 2.5 and 2.6 succeeded, but logged internally caught exception - # spew: - # - # Exception RuntimeError: 'maximum recursion depth exceeded while - # calling a Python object' in <type 'exceptions.AttributeError'> - # ignored" - query = Q(user=response.context['user']) & Q(someflag=True) - - # Tests for user equality. This is hard because User defines - # equality in a non-duck-typing way - # See bug #12060 - self.assertEqual(response.context['user'], user) - self.assertEqual(user, response.context['user']) diff --git a/parts/django/tests/regressiontests/context_processors/urls.py b/parts/django/tests/regressiontests/context_processors/urls.py deleted file mode 100644 index 30728c8..0000000 --- a/parts/django/tests/regressiontests/context_processors/urls.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.conf.urls.defaults import * - -import views - - -urlpatterns = patterns('', - (r'^request_attrs/$', views.request_processor), - (r'^auth_processor_no_attr_access/$', views.auth_processor_no_attr_access), - (r'^auth_processor_attr_access/$', views.auth_processor_attr_access), - (r'^auth_processor_user/$', views.auth_processor_user), - (r'^auth_processor_perms/$', views.auth_processor_perms), - (r'^auth_processor_messages/$', views.auth_processor_messages), - url(r'^userpage/(.+)/$', views.userpage, name="userpage"), -) diff --git a/parts/django/tests/regressiontests/context_processors/views.py b/parts/django/tests/regressiontests/context_processors/views.py deleted file mode 100644 index 3f2dcb0..0000000 --- a/parts/django/tests/regressiontests/context_processors/views.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.core import context_processors -from django.shortcuts import render_to_response -from django.template.context import RequestContext - - -def request_processor(request): - return render_to_response('context_processors/request_attrs.html', - RequestContext(request, {}, processors=[context_processors.request])) - -def auth_processor_no_attr_access(request): - r1 = render_to_response('context_processors/auth_attrs_no_access.html', - RequestContext(request, {}, processors=[context_processors.auth])) - # *After* rendering, we check whether the session was accessed - return render_to_response('context_processors/auth_attrs_test_access.html', - {'session_accessed':request.session.accessed}) - -def auth_processor_attr_access(request): - r1 = render_to_response('context_processors/auth_attrs_access.html', - RequestContext(request, {}, processors=[context_processors.auth])) - return render_to_response('context_processors/auth_attrs_test_access.html', - {'session_accessed':request.session.accessed}) - -def auth_processor_user(request): - return render_to_response('context_processors/auth_attrs_user.html', - RequestContext(request, {}, processors=[context_processors.auth])) - -def auth_processor_perms(request): - return render_to_response('context_processors/auth_attrs_perms.html', - RequestContext(request, {}, processors=[context_processors.auth])) - -def auth_processor_messages(request): - request.user.message_set.create(message="Message 1") - return render_to_response('context_processors/auth_attrs_messages.html', - RequestContext(request, {}, processors=[context_processors.auth])) - -def userpage(request): - pass diff --git a/parts/django/tests/regressiontests/csrf_tests/__init__.py b/parts/django/tests/regressiontests/csrf_tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/csrf_tests/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/csrf_tests/models.py b/parts/django/tests/regressiontests/csrf_tests/models.py deleted file mode 100644 index 71abcc5..0000000 --- a/parts/django/tests/regressiontests/csrf_tests/models.py +++ /dev/null @@ -1 +0,0 @@ -# models.py file for tests to run. diff --git a/parts/django/tests/regressiontests/csrf_tests/tests.py b/parts/django/tests/regressiontests/csrf_tests/tests.py deleted file mode 100644 index 9f74fc5..0000000 --- a/parts/django/tests/regressiontests/csrf_tests/tests.py +++ /dev/null @@ -1,375 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.test import TestCase -from django.http import HttpRequest, HttpResponse -from django.middleware.csrf import CsrfMiddleware, CsrfViewMiddleware -from django.views.decorators.csrf import csrf_exempt, csrf_view_exempt, requires_csrf_token -from django.core.context_processors import csrf -from django.contrib.sessions.middleware import SessionMiddleware -from django.utils.importlib import import_module -from django.conf import settings -from django.template import RequestContext, Template - -# Response/views used for CsrfResponseMiddleware and CsrfViewMiddleware tests -def post_form_response(): - resp = HttpResponse(content=u""" -<html><body><h1>\u00a1Unicode!<form method="post"><input type="text" /></form></body></html> -""", mimetype="text/html") - return resp - -def post_form_response_non_html(): - resp = post_form_response() - resp["Content-Type"] = "application/xml" - return resp - -def post_form_view(request): - """A view that returns a POST form (without a token)""" - return post_form_response() - -# Response/views used for template tag tests -def _token_template(): - return Template("{% csrf_token %}") - -def _render_csrf_token_template(req): - context = RequestContext(req, processors=[csrf]) - template = _token_template() - return template.render(context) - -def token_view(request): - """A view that uses {% csrf_token %}""" - return HttpResponse(_render_csrf_token_template(request)) - -def non_token_view_using_request_processor(request): - """ - A view that doesn't use the token, but does use the csrf view processor. - """ - context = RequestContext(request, processors=[csrf]) - template = Template("") - return HttpResponse(template.render(context)) - -class TestingHttpRequest(HttpRequest): - """ - A version of HttpRequest that allows us to change some things - more easily - """ - def is_secure(self): - return getattr(self, '_is_secure', False) - -class CsrfMiddlewareTest(TestCase): - # The csrf token is potentially from an untrusted source, so could have - # characters that need dealing with. - _csrf_id_cookie = "<1>\xc2\xa1" - _csrf_id = "1" - - # This is a valid session token for this ID and secret key. This was generated using - # the old code that we're to be backwards-compatible with. Don't use the CSRF code - # to generate this hash, or we're merely testing the code against itself and not - # checking backwards-compatibility. This is also the output of (echo -n test1 | md5sum). - _session_token = "5a105e8b9d40e1329780d62ea2265d8a" - _session_id = "1" - _secret_key_for_session_test= "test" - - def _get_GET_no_csrf_cookie_request(self): - return TestingHttpRequest() - - def _get_GET_csrf_cookie_request(self): - req = TestingHttpRequest() - req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie - return req - - def _get_POST_csrf_cookie_request(self): - req = self._get_GET_csrf_cookie_request() - req.method = "POST" - return req - - def _get_POST_no_csrf_cookie_request(self): - req = self._get_GET_no_csrf_cookie_request() - req.method = "POST" - return req - - def _get_POST_request_with_token(self): - req = self._get_POST_csrf_cookie_request() - req.POST['csrfmiddlewaretoken'] = self._csrf_id - return req - - def _get_POST_session_request_with_token(self): - req = self._get_POST_no_csrf_cookie_request() - req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id - req.POST['csrfmiddlewaretoken'] = self._session_token - return req - - def _get_POST_session_request_no_token(self): - req = self._get_POST_no_csrf_cookie_request() - req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id - return req - - def _check_token_present(self, response, csrf_id=None): - self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id)) - - # Check the post processing and outgoing cookie - def test_process_response_no_csrf_cookie(self): - """ - When no prior CSRF cookie exists, check that the cookie is created and a - token is inserted. - """ - req = self._get_GET_no_csrf_cookie_request() - CsrfMiddleware().process_view(req, post_form_view, (), {}) - - resp = post_form_response() - resp_content = resp.content # needed because process_response modifies resp - resp2 = CsrfMiddleware().process_response(req, resp) - - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertNotEqual(csrf_cookie, False) - self.assertNotEqual(resp_content, resp2.content) - self._check_token_present(resp2, csrf_cookie.value) - # Check the Vary header got patched correctly - self.assert_('Cookie' in resp2.get('Vary','')) - - def test_process_response_for_exempt_view(self): - """ - Check that a view decorated with 'csrf_view_exempt' is still - post-processed to add the CSRF token. - """ - req = self._get_GET_no_csrf_cookie_request() - CsrfMiddleware().process_view(req, csrf_view_exempt(post_form_view), (), {}) - - resp = post_form_response() - resp_content = resp.content # needed because process_response modifies resp - resp2 = CsrfMiddleware().process_response(req, resp) - - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertNotEqual(csrf_cookie, False) - self.assertNotEqual(resp_content, resp2.content) - self._check_token_present(resp2, csrf_cookie.value) - - def test_process_response_no_csrf_cookie_view_only_get_token_used(self): - """ - When no prior CSRF cookie exists, check that the cookie is created, even - if only CsrfViewMiddleware is used. - """ - # This is checking that CsrfViewMiddleware has the cookie setting - # code. Most of the other tests use CsrfMiddleware. - req = self._get_GET_no_csrf_cookie_request() - # token_view calls get_token() indirectly - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertNotEqual(csrf_cookie, False) - - def test_process_response_get_token_not_used(self): - """ - Check that if get_token() is not called, the view middleware does not - add a cookie. - """ - # This is important to make pages cacheable. Pages which do call - # get_token(), assuming they use the token, are not cacheable because - # the token is specific to the user - req = self._get_GET_no_csrf_cookie_request() - # non_token_view_using_request_processor does not call get_token(), but - # does use the csrf request processor. By using this, we are testing - # that the view processor is properly lazy and doesn't call get_token() - # until needed. - CsrfViewMiddleware().process_view(req, non_token_view_using_request_processor, (), {}) - resp = non_token_view_using_request_processor(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertEqual(csrf_cookie, False) - - def test_process_response_existing_csrf_cookie(self): - """ - Check that the token is inserted when a prior CSRF cookie exists - """ - req = self._get_GET_csrf_cookie_request() - CsrfMiddleware().process_view(req, post_form_view, (), {}) - - resp = post_form_response() - resp_content = resp.content # needed because process_response modifies resp - resp2 = CsrfMiddleware().process_response(req, resp) - self.assertNotEqual(resp_content, resp2.content) - self._check_token_present(resp2) - - def test_process_response_non_html(self): - """ - Check the the post-processor does nothing for content-types not in _HTML_TYPES. - """ - req = self._get_GET_no_csrf_cookie_request() - CsrfMiddleware().process_view(req, post_form_view, (), {}) - resp = post_form_response_non_html() - resp_content = resp.content # needed because process_response modifies resp - resp2 = CsrfMiddleware().process_response(req, resp) - self.assertEquals(resp_content, resp2.content) - - def test_process_response_exempt_view(self): - """ - Check that no post processing is done for an exempt view - """ - req = self._get_GET_csrf_cookie_request() - view = csrf_exempt(post_form_view) - CsrfMiddleware().process_view(req, view, (), {}) - - resp = view(req) - resp_content = resp.content - resp2 = CsrfMiddleware().process_response(req, resp) - self.assertEquals(resp_content, resp2.content) - - # Check the request processing - def test_process_request_no_session_no_csrf_cookie(self): - """ - Check that if neither a CSRF cookie nor a session cookie are present, - the middleware rejects the incoming request. This will stop login CSRF. - """ - req = self._get_POST_no_csrf_cookie_request() - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(403, req2.status_code) - - def test_process_request_csrf_cookie_no_token(self): - """ - Check that if a CSRF cookie is present but no token, the middleware - rejects the incoming request. - """ - req = self._get_POST_csrf_cookie_request() - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(403, req2.status_code) - - def test_process_request_csrf_cookie_and_token(self): - """ - Check that if both a cookie and a token is present, the middleware lets it through. - """ - req = self._get_POST_request_with_token() - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(None, req2) - - def test_process_request_session_cookie_no_csrf_cookie_token(self): - """ - When no CSRF cookie exists, but the user has a session, check that a token - using the session cookie as a legacy CSRF cookie is accepted. - """ - orig_secret_key = settings.SECRET_KEY - settings.SECRET_KEY = self._secret_key_for_session_test - try: - req = self._get_POST_session_request_with_token() - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(None, req2) - finally: - settings.SECRET_KEY = orig_secret_key - - def test_process_request_session_cookie_no_csrf_cookie_no_token(self): - """ - Check that if a session cookie is present but no token and no CSRF cookie, - the request is rejected. - """ - req = self._get_POST_session_request_no_token() - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(403, req2.status_code) - - def test_process_request_csrf_cookie_no_token_exempt_view(self): - """ - Check that if a CSRF cookie is present and no token, but the csrf_exempt - decorator has been applied to the view, the middleware lets it through - """ - req = self._get_POST_csrf_cookie_request() - req2 = CsrfMiddleware().process_view(req, csrf_exempt(post_form_view), (), {}) - self.assertEquals(None, req2) - - def test_ajax_exemption(self): - """ - Check that AJAX requests are automatically exempted. - """ - req = self._get_POST_csrf_cookie_request() - req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' - req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(None, req2) - - # Tests for the template tag method - def test_token_node_no_csrf_cookie(self): - """ - Check that CsrfTokenNode works when no CSRF cookie is set - """ - req = self._get_GET_no_csrf_cookie_request() - resp = token_view(req) - self.assertEquals(u"", resp.content) - - def test_token_node_empty_csrf_cookie(self): - """ - Check that we get a new token if the csrf_cookie is the empty string - """ - req = self._get_GET_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = "" - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - - self.assertNotEqual(u"", resp.content) - - def test_token_node_with_csrf_cookie(self): - """ - Check that CsrfTokenNode works when a CSRF cookie is set - """ - req = self._get_GET_csrf_cookie_request() - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - self._check_token_present(resp) - - def test_get_token_for_exempt_view(self): - """ - Check that get_token still works for a view decorated with 'csrf_view_exempt'. - """ - req = self._get_GET_csrf_cookie_request() - CsrfViewMiddleware().process_view(req, csrf_view_exempt(token_view), (), {}) - resp = token_view(req) - self._check_token_present(resp) - - def test_get_token_for_requires_csrf_token_view(self): - """ - Check that get_token works for a view decorated solely with requires_csrf_token - """ - req = self._get_GET_csrf_cookie_request() - resp = requires_csrf_token(token_view)(req) - self._check_token_present(resp) - - def test_token_node_with_new_csrf_cookie(self): - """ - Check that CsrfTokenNode works when a CSRF cookie is created by - the middleware (when one was not already present) - """ - req = self._get_GET_no_csrf_cookie_request() - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies[settings.CSRF_COOKIE_NAME] - self._check_token_present(resp, csrf_id=csrf_cookie.value) - - def test_response_middleware_without_view_middleware(self): - """ - Check that CsrfResponseMiddleware finishes without error if the view middleware - has not been called, as is the case if a request middleware returns a response. - """ - req = self._get_GET_no_csrf_cookie_request() - resp = post_form_view(req) - CsrfMiddleware().process_response(req, resp) - - def test_https_bad_referer(self): - """ - Test that a POST HTTPS request with a bad referer is rejected - """ - req = self._get_POST_request_with_token() - req._is_secure = True - req.META['HTTP_HOST'] = 'www.example.com' - req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage' - req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) - self.assertNotEqual(None, req2) - self.assertEquals(403, req2.status_code) - - def test_https_good_referer(self): - """ - Test that a POST HTTPS request with a good referer is accepted - """ - req = self._get_POST_request_with_token() - req._is_secure = True - req.META['HTTP_HOST'] = 'www.example.com' - req.META['HTTP_REFERER'] = 'https://www.example.com/somepage' - req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) - self.assertEquals(None, req2) diff --git a/parts/django/tests/regressiontests/custom_columns_regress/__init__.py b/parts/django/tests/regressiontests/custom_columns_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/custom_columns_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/custom_columns_regress/models.py b/parts/django/tests/regressiontests/custom_columns_regress/models.py deleted file mode 100644 index 93de237..0000000 --- a/parts/django/tests/regressiontests/custom_columns_regress/models.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Regression for #9736. - -Checks some pathological column naming to make sure it doesn't break -table creation or queries. - -""" - -from django.db import models - -class Article(models.Model): - Article_ID = models.AutoField(primary_key=True, db_column='Article ID') - headline = models.CharField(max_length=100) - authors = models.ManyToManyField('Author', db_table='my m2m table') - primary_author = models.ForeignKey('Author', db_column='Author ID', related_name='primary_set') - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('headline',) - -class Author(models.Model): - Author_ID = models.AutoField(primary_key=True, db_column='Author ID') - first_name = models.CharField(max_length=30, db_column='first name') - last_name = models.CharField(max_length=30, db_column='last name') - - def __unicode__(self): - return u'%s %s' % (self.first_name, self.last_name) - - class Meta: - db_table = 'my author table' - ordering = ('last_name','first_name') - - - diff --git a/parts/django/tests/regressiontests/custom_columns_regress/tests.py b/parts/django/tests/regressiontests/custom_columns_regress/tests.py deleted file mode 100644 index 8507601..0000000 --- a/parts/django/tests/regressiontests/custom_columns_regress/tests.py +++ /dev/null @@ -1,84 +0,0 @@ -from django.test import TestCase -from django.core.exceptions import FieldError - -from models import Author, Article - -def pks(objects): - """ Return pks to be able to compare lists""" - return [o.pk for o in objects] - -class CustomColumnRegression(TestCase): - - def assertRaisesMessage(self, exc, msg, func, *args, **kwargs): - try: - func(*args, **kwargs) - except Exception, e: - self.assertEqual(msg, str(e)) - self.assertTrue(isinstance(e, exc), "Expected %s, got %s" % (exc, type(e))) - - def setUp(self): - self.a1 = Author.objects.create(first_name='John', last_name='Smith') - self.a2 = Author.objects.create(first_name='Peter', last_name='Jones') - self.authors = [self.a1, self.a2] - - def test_basic_creation(self): - art = Article(headline='Django lets you build Web apps easily', primary_author=self.a1) - art.save() - art.authors = [self.a1, self.a2] - - def test_author_querying(self): - self.assertQuerysetEqual( - Author.objects.all().order_by('last_name'), - ['<Author: Peter Jones>', '<Author: John Smith>'] - ) - - def test_author_filtering(self): - self.assertQuerysetEqual( - Author.objects.filter(first_name__exact='John'), - ['<Author: John Smith>'] - ) - - def test_author_get(self): - self.assertEqual(self.a1, Author.objects.get(first_name__exact='John')) - - def test_filter_on_nonexistant_field(self): - self.assertRaisesMessage( - FieldError, - "Cannot resolve keyword 'firstname' into field. Choices are: Author_ID, article, first_name, last_name, primary_set", - Author.objects.filter, - firstname__exact='John' - ) - - def test_author_get_attributes(self): - a = Author.objects.get(last_name__exact='Smith') - self.assertEqual('John', a.first_name) - self.assertEqual('Smith', a.last_name) - self.assertRaisesMessage( - AttributeError, - "'Author' object has no attribute 'firstname'", - getattr, - a, 'firstname' - ) - - self.assertRaisesMessage( - AttributeError, - "'Author' object has no attribute 'last'", - getattr, - a, 'last' - ) - - def test_m2m_table(self): - art = Article.objects.create(headline='Django lets you build Web apps easily', primary_author=self.a1) - art.authors = self.authors - self.assertQuerysetEqual( - art.authors.all().order_by('last_name'), - ['<Author: Peter Jones>', '<Author: John Smith>'] - ) - self.assertQuerysetEqual( - self.a1.article_set.all(), - ['<Article: Django lets you build Web apps easily>'] - ) - self.assertQuerysetEqual( - art.authors.filter(last_name='Jones'), - ['<Author: Peter Jones>'] - ) diff --git a/parts/django/tests/regressiontests/custom_managers_regress/__init__.py b/parts/django/tests/regressiontests/custom_managers_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/custom_managers_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/custom_managers_regress/models.py b/parts/django/tests/regressiontests/custom_managers_regress/models.py deleted file mode 100644 index 747972b..0000000 --- a/parts/django/tests/regressiontests/custom_managers_regress/models.py +++ /dev/null @@ -1,40 +0,0 @@ -""" -Regression tests for custom manager classes. -""" - -from django.db import models - -class RestrictedManager(models.Manager): - """ - A manager that filters out non-public instances. - """ - def get_query_set(self): - return super(RestrictedManager, self).get_query_set().filter(is_public=True) - -class RelatedModel(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return self.name - -class RestrictedModel(models.Model): - name = models.CharField(max_length=50) - is_public = models.BooleanField(default=False) - related = models.ForeignKey(RelatedModel) - - objects = RestrictedManager() - plain_manager = models.Manager() - - def __unicode__(self): - return self.name - -class OneToOneRestrictedModel(models.Model): - name = models.CharField(max_length=50) - is_public = models.BooleanField(default=False) - related = models.OneToOneField(RelatedModel) - - objects = RestrictedManager() - plain_manager = models.Manager() - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/regressiontests/custom_managers_regress/tests.py b/parts/django/tests/regressiontests/custom_managers_regress/tests.py deleted file mode 100644 index 6dd668a..0000000 --- a/parts/django/tests/regressiontests/custom_managers_regress/tests.py +++ /dev/null @@ -1,47 +0,0 @@ -from django.test import TestCase - -from models import RelatedModel, RestrictedModel, OneToOneRestrictedModel - -class CustomManagersRegressTestCase(TestCase): - def test_filtered_default_manager(self): - """Even though the default manager filters out some records, - we must still be able to save (particularly, save by updating - existing records) those filtered instances. This is a - regression test for #8990, #9527""" - related = RelatedModel.objects.create(name="xyzzy") - obj = RestrictedModel.objects.create(name="hidden", related=related) - obj.name = "still hidden" - obj.save() - - # If the hidden object wasn't seen during the save process, - # there would now be two objects in the database. - self.assertEqual(RestrictedModel.plain_manager.count(), 1) - - def test_delete_related_on_filtered_manager(self): - """Deleting related objects should also not be distracted by a - restricted manager on the related object. This is a regression - test for #2698.""" - related = RelatedModel.objects.create(name="xyzzy") - - for name, public in (('one', True), ('two', False), ('three', False)): - RestrictedModel.objects.create(name=name, is_public=public, related=related) - - obj = RelatedModel.objects.get(name="xyzzy") - obj.delete() - - # All of the RestrictedModel instances should have been - # deleted, since they *all* pointed to the RelatedModel. If - # the default manager is used, only the public one will be - # deleted. - self.assertEqual(len(RestrictedModel.plain_manager.all()), 0) - - def test_delete_one_to_one_manager(self): - # The same test case as the last one, but for one-to-one - # models, which are implemented slightly different internally, - # so it's a different code path. - obj = RelatedModel.objects.create(name="xyzzy") - OneToOneRestrictedModel.objects.create(name="foo", is_public=False, related=obj) - obj = RelatedModel.objects.get(name="xyzzy") - obj.delete() - self.assertEqual(len(OneToOneRestrictedModel.plain_manager.all()), 0) - diff --git a/parts/django/tests/regressiontests/datatypes/__init__.py b/parts/django/tests/regressiontests/datatypes/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/datatypes/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/datatypes/models.py b/parts/django/tests/regressiontests/datatypes/models.py deleted file mode 100644 index f6fb72d..0000000 --- a/parts/django/tests/regressiontests/datatypes/models.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -This is a basic model to test saving and loading boolean and date-related -types, which in the past were problematic for some database backends. -""" - -from django.db import models - -class Donut(models.Model): - name = models.CharField(max_length=100) - is_frosted = models.BooleanField(default=False) - has_sprinkles = models.NullBooleanField() - baked_date = models.DateField(null=True) - baked_time = models.TimeField(null=True) - consumed_at = models.DateTimeField(null=True) - review = models.TextField() - - class Meta: - ordering = ('consumed_at',) - - def __str__(self): - return self.name - -class RumBaba(models.Model): - baked_date = models.DateField(auto_now_add=True) - baked_timestamp = models.DateTimeField(auto_now_add=True) diff --git a/parts/django/tests/regressiontests/datatypes/tests.py b/parts/django/tests/regressiontests/datatypes/tests.py deleted file mode 100644 index f7a0447..0000000 --- a/parts/django/tests/regressiontests/datatypes/tests.py +++ /dev/null @@ -1,93 +0,0 @@ -import datetime -from django.db import DEFAULT_DB_ALIAS -from django.test import TestCase -from django.utils import tzinfo - -from models import Donut, RumBaba -from django.conf import settings - -class DataTypesTestCase(TestCase): - - def test_boolean_type(self): - d = Donut(name='Apple Fritter') - self.assertFalse(d.is_frosted) - self.assertTrue(d.has_sprinkles is None) - d.has_sprinkles = True - self.assertTrue(d.has_sprinkles) - - d.save() - - d2 = Donut.objects.get(name='Apple Fritter') - self.assertFalse(d2.is_frosted) - self.assertTrue(d2.has_sprinkles) - - def test_date_type(self): - d = Donut(name='Apple Fritter') - d.baked_date = datetime.date(year=1938, month=6, day=4) - d.baked_time = datetime.time(hour=5, minute=30) - d.consumed_at = datetime.datetime(year=2007, month=4, day=20, hour=16, minute=19, second=59) - d.save() - - d2 = Donut.objects.get(name='Apple Fritter') - self.assertEqual(d2.baked_date, datetime.date(1938, 6, 4)) - self.assertEqual(d2.baked_time, datetime.time(5, 30)) - self.assertEqual(d2.consumed_at, datetime.datetime(2007, 4, 20, 16, 19, 59)) - - def test_time_field(self): - #Test for ticket #12059: TimeField wrongly handling datetime.datetime object. - d = Donut(name='Apple Fritter') - d.baked_time = datetime.datetime(year=2007, month=4, day=20, hour=16, minute=19, second=59) - d.save() - - d2 = Donut.objects.get(name='Apple Fritter') - self.assertEqual(d2.baked_time, datetime.time(16, 19, 59)) - - def test_year_boundaries(self): - """Year boundary tests (ticket #3689)""" - d = Donut.objects.create(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)) - d1 = Donut.objects.create(name='Date Test 2006', - baked_date=datetime.datetime(year=2006, month=1, day=1), - consumed_at=datetime.datetime(year=2006, month=1, day=1)) - - self.assertEqual("Date Test 2007", - Donut.objects.filter(baked_date__year=2007)[0].name) - - self.assertEqual("Date Test 2006", - Donut.objects.filter(baked_date__year=2006)[0].name) - - d2 = Donut.objects.create(name='Apple Fritter', - consumed_at = datetime.datetime(year=2007, month=4, day=20, hour=16, minute=19, second=59)) - - self.assertEqual([u'Apple Fritter', u'Date Test 2007'], - list(Donut.objects.filter(consumed_at__year=2007).order_by('name').values_list('name', flat=True))) - - self.assertEqual(0, Donut.objects.filter(consumed_at__year=2005).count()) - self.assertEqual(0, Donut.objects.filter(consumed_at__year=2008).count()) - - def test_textfields_unicode(self): - """Regression test for #10238: TextField values returned from the - database should be unicode.""" - d = Donut.objects.create(name=u'Jelly Donut', review=u'Outstanding') - newd = Donut.objects.get(id=d.id) - self.assert_(isinstance(newd.review, unicode)) - - def test_tz_awareness_mysql(self): - """Regression test for #8354: the MySQL backend should raise an error - if given a timezone-aware datetime object.""" - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.mysql': - dt = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(0)) - d = Donut(name='Bear claw', consumed_at=dt) - self.assertRaises(ValueError, d.save) - # ValueError: MySQL backend does not support timezone-aware datetimes. - - def test_datefield_auto_now_add(self): - """Regression test for #10970, auto_now_add for DateField should store - a Python datetime.date, not a datetime.datetime""" - b = RumBaba.objects.create() - # Verify we didn't break DateTimeField behavior - self.assert_(isinstance(b.baked_timestamp, datetime.datetime)) - # We need to test this this way because datetime.datetime inherits - # from datetime.date: - self.assert_(isinstance(b.baked_date, datetime.date) and not isinstance(b.baked_date, datetime.datetime)) diff --git a/parts/django/tests/regressiontests/db_typecasts/__init__.py b/parts/django/tests/regressiontests/db_typecasts/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/db_typecasts/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/db_typecasts/models.py b/parts/django/tests/regressiontests/db_typecasts/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/db_typecasts/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/db_typecasts/tests.py b/parts/django/tests/regressiontests/db_typecasts/tests.py deleted file mode 100644 index 8c71c8f..0000000 --- a/parts/django/tests/regressiontests/db_typecasts/tests.py +++ /dev/null @@ -1,62 +0,0 @@ -# Unit tests for typecast functions in django.db.backends.util - -from django.db.backends import util as typecasts -import datetime, unittest - -TEST_CASES = { - 'typecast_date': ( - ('', None), - (None, None), - ('2005-08-11', datetime.date(2005, 8, 11)), - ('1990-01-01', datetime.date(1990, 1, 1)), - ), - 'typecast_time': ( - ('', None), - (None, None), - ('0:00:00', datetime.time(0, 0)), - ('0:30:00', datetime.time(0, 30)), - ('8:50:00', datetime.time(8, 50)), - ('08:50:00', datetime.time(8, 50)), - ('12:00:00', datetime.time(12, 00)), - ('12:30:00', datetime.time(12, 30)), - ('13:00:00', datetime.time(13, 00)), - ('23:59:00', datetime.time(23, 59)), - ('00:00:12', datetime.time(0, 0, 12)), - ('00:00:12.5', datetime.time(0, 0, 12, 500000)), - ('7:22:13.312', datetime.time(7, 22, 13, 312000)), - ), - 'typecast_timestamp': ( - ('', None), - (None, None), - ('2005-08-11 0:00:00', datetime.datetime(2005, 8, 11)), - ('2005-08-11 0:30:00', datetime.datetime(2005, 8, 11, 0, 30)), - ('2005-08-11 8:50:30', datetime.datetime(2005, 8, 11, 8, 50, 30)), - ('2005-08-11 8:50:30.123', datetime.datetime(2005, 8, 11, 8, 50, 30, 123000)), - ('2005-08-11 8:50:30.9', datetime.datetime(2005, 8, 11, 8, 50, 30, 900000)), - ('2005-08-11 8:50:30.312-05', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), - ('2005-08-11 8:50:30.312+02', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), - # ticket 14453 - ('2010-10-12 15:29:22.063202', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), - ('2010-10-12 15:29:22.063202-03', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), - ('2010-10-12 15:29:22.063202+04', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), - ('2010-10-12 15:29:22.0632021', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), - ('2010-10-12 15:29:22.0632029', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), - ), - 'typecast_boolean': ( - (None, None), - ('', False), - ('t', True), - ('f', False), - ('x', False), - ), -} - -class DBTypeCasts(unittest.TestCase): - def test_typeCasts(self): - for k, v in TEST_CASES.items(): - for inpt, expected in v: - got = getattr(typecasts, k)(inpt) - assert got == expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got) - -if __name__ == '__main__': - unittest.main() diff --git a/parts/django/tests/regressiontests/decorators/__init__.py b/parts/django/tests/regressiontests/decorators/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/decorators/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/decorators/models.py b/parts/django/tests/regressiontests/decorators/models.py deleted file mode 100644 index e5a7950..0000000 --- a/parts/django/tests/regressiontests/decorators/models.py +++ /dev/null @@ -1,2 +0,0 @@ -# A models.py so that tests run. - diff --git a/parts/django/tests/regressiontests/decorators/tests.py b/parts/django/tests/regressiontests/decorators/tests.py deleted file mode 100644 index ea2e10e..0000000 --- a/parts/django/tests/regressiontests/decorators/tests.py +++ /dev/null @@ -1,141 +0,0 @@ -from unittest import TestCase -from sys import version_info -try: - from functools import wraps -except ImportError: - from django.utils.functional import wraps # Python 2.4 fallback. - -from django.http import HttpResponse, HttpRequest -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.utils.decorators import method_decorator -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 -# Apply user_passes_test twice to check #9474 -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__') - - def test_user_passes_test_composition(self): - """ - Test that the user_passes_test decorator can be applied multiple times - (#9474). - """ - def test1(user): - user.decorators_applied.append('test1') - return True - - def test2(user): - user.decorators_applied.append('test2') - return True - - def callback(request): - return request.user.decorators_applied - - callback = user_passes_test(test1)(callback) - callback = user_passes_test(test2)(callback) - - class DummyUser(object): pass - class DummyRequest(object): pass - - request = DummyRequest() - request.user = DummyUser() - request.user.decorators_applied = [] - response = callback(request) - - self.assertEqual(response, ['test2', 'test1']) - - def test_cache_page_new_style(self): - """ - Test that we can call cache_page the new way - """ - def my_view(request): - return "response" - my_view_cached = cache_page(123)(my_view) - self.assertEqual(my_view_cached(HttpRequest()), "response") - my_view_cached2 = cache_page(123, key_prefix="test")(my_view) - self.assertEqual(my_view_cached2(HttpRequest()), "response") - - def test_cache_page_old_style(self): - """ - Test that we can call cache_page the old way - """ - def my_view(request): - return "response" - my_view_cached = cache_page(my_view, 123) - self.assertEqual(my_view_cached(HttpRequest()), "response") - my_view_cached2 = cache_page(my_view, 123, key_prefix="test") - self.assertEqual(my_view_cached2(HttpRequest()), "response") - my_view_cached3 = cache_page(my_view) - self.assertEqual(my_view_cached3(HttpRequest()), "response") - my_view_cached4 = cache_page()(my_view) - self.assertEqual(my_view_cached4(HttpRequest()), "response") - - -# For testing method_decorator, a decorator that assumes a single argument. -# We will get type arguments if there is a mismatch in the number of arguments. -def simple_dec(func): - def wrapper(arg): - return func("test:" + arg) - return wraps(func)(wrapper) - -simple_dec_m = method_decorator(simple_dec) - - -class MethodDecoratorTests(TestCase): - """ - Tests for method_decorator - """ - def test_method_decorator(self): - class Test(object): - @simple_dec_m - def say(self, arg): - return arg - - self.assertEqual("test:hello", Test().say("hello")) diff --git a/parts/django/tests/regressiontests/defaultfilters/__init__.py b/parts/django/tests/regressiontests/defaultfilters/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/defaultfilters/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/defaultfilters/models.py b/parts/django/tests/regressiontests/defaultfilters/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/defaultfilters/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/defaultfilters/tests.py b/parts/django/tests/regressiontests/defaultfilters/tests.py deleted file mode 100644 index 0866bfc..0000000 --- a/parts/django/tests/regressiontests/defaultfilters/tests.py +++ /dev/null @@ -1,485 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -import unittest - -from django.template.defaultfilters import * - -class DefaultFiltersTests(unittest.TestCase): - - def test_floatformat(self): - self.assertEqual(floatformat(7.7), u'7.7') - self.assertEqual(floatformat(7.0), u'7') - self.assertEqual(floatformat(0.7), u'0.7') - self.assertEqual(floatformat(0.07), u'0.1') - self.assertEqual(floatformat(0.007), u'0.0') - self.assertEqual(floatformat(0.0), u'0') - self.assertEqual(floatformat(7.7, 3), u'7.700') - self.assertEqual(floatformat(6.000000, 3), u'6.000') - self.assertEqual(floatformat(6.200000, 3), u'6.200') - self.assertEqual(floatformat(6.200000, -3), u'6.200') - self.assertEqual(floatformat(13.1031, -3), u'13.103') - self.assertEqual(floatformat(11.1197, -2), u'11.12') - self.assertEqual(floatformat(11.0000, -2), u'11') - self.assertEqual(floatformat(11.000001, -2), u'11.00') - self.assertEqual(floatformat(8.2798, 3), u'8.280') - self.assertEqual(floatformat(u'foo'), u'') - self.assertEqual(floatformat(13.1031, u'bar'), u'13.1031') - self.assertEqual(floatformat(18.125, 2), u'18.13') - self.assertEqual(floatformat(u'foo', u'bar'), u'') - self.assertEqual(floatformat(u'¿Cómo esta usted?'), u'') - self.assertEqual(floatformat(None), u'') - - pos_inf = float(1e30000) - self.assertEqual(floatformat(pos_inf), unicode(pos_inf)) - - neg_inf = float(-1e30000) - self.assertEqual(floatformat(neg_inf), unicode(neg_inf)) - - nan = pos_inf / pos_inf - self.assertEqual(floatformat(nan), unicode(nan)) - - class FloatWrapper(object): - def __init__(self, value): - self.value = value - def __float__(self): - return self.value - - self.assertEqual(floatformat(FloatWrapper(11.000001), -2), u'11.00') - - def test_addslashes(self): - self.assertEqual(addslashes(u'"double quotes" and \'single quotes\''), - u'\\"double quotes\\" and \\\'single quotes\\\'') - - self.assertEqual(addslashes(ur'\ : backslashes, too'), - u'\\\\ : backslashes, too') - - def test_capfirst(self): - self.assertEqual(capfirst(u'hello world'), u'Hello world') - - def test_escapejs(self): - self.assertEqual(escapejs(u'"double quotes" and \'single quotes\''), - u'\\u0022double quotes\\u0022 and \\u0027single quotes\\u0027') - self.assertEqual(escapejs(ur'\ : backslashes, too'), - u'\\u005C : backslashes, too') - self.assertEqual(escapejs(u'and lots of whitespace: \r\n\t\v\f\b'), - u'and lots of whitespace: \\u000D\\u000A\\u0009\\u000B\\u000C\\u0008') - self.assertEqual(escapejs(ur'<script>and this</script>'), - u'\\u003Cscript\\u003Eand this\\u003C/script\\u003E') - self.assertEqual( - escapejs(u'paragraph separator:\u2029and line separator:\u2028'), - u'paragraph separator:\\u2029and line separator:\\u2028') - - def test_fix_ampersands(self): - self.assertEqual(fix_ampersands(u'Jack & Jill & Jeroboam'), - u'Jack & Jill & Jeroboam') - - def test_linenumbers(self): - self.assertEqual(linenumbers(u'line 1\nline 2'), - u'1. line 1\n2. line 2') - self.assertEqual(linenumbers(u'\n'.join([u'x'] * 10)), - u'01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. '\ - u'x\n08. x\n09. x\n10. x') - - def test_lower(self): - self.assertEqual(lower('TEST'), u'test') - - # uppercase E umlaut - self.assertEqual(lower(u'\xcb'), u'\xeb') - - def test_make_list(self): - self.assertEqual(make_list('abc'), [u'a', u'b', u'c']) - self.assertEqual(make_list(1234), [u'1', u'2', u'3', u'4']) - - def test_slugify(self): - self.assertEqual(slugify(' Jack & Jill like numbers 1,2,3 and 4 and'\ - ' silly characters ?%.$!/'), - u'jack-jill-like-numbers-123-and-4-and-silly-characters') - - self.assertEqual(slugify(u"Un \xe9l\xe9phant \xe0 l'or\xe9e du bois"), - u'un-elephant-a-loree-du-bois') - - def test_stringformat(self): - self.assertEqual(stringformat(1, u'03d'), u'001') - self.assertEqual(stringformat(1, u'z'), u'') - - def test_title(self): - self.assertEqual(title('a nice title, isn\'t it?'), - u"A Nice Title, Isn't It?") - self.assertEqual(title(u'discoth\xe8que'), u'Discoth\xe8que') - - def test_truncatewords(self): - self.assertEqual( - truncatewords(u'A sentence with a few words in it', 1), u'A ...') - self.assertEqual( - truncatewords(u'A sentence with a few words in it', 5), - u'A sentence with a few ...') - self.assertEqual( - truncatewords(u'A sentence with a few words in it', 100), - u'A sentence with a few words in it') - self.assertEqual( - truncatewords(u'A sentence with a few words in it', - 'not a number'), u'A sentence with a few words in it') - - def test_truncatewords_html(self): - self.assertEqual(truncatewords_html( - u'<p>one <a href="#">two - three <br>four</a> five</p>', 0), u'') - self.assertEqual(truncatewords_html(u'<p>one <a href="#">two - '\ - u'three <br>four</a> five</p>', 2), - u'<p>one <a href="#">two ...</a></p>') - self.assertEqual(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>') - self.assertEqual(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>') - self.assertEqual(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>') - self.assertEqual(truncatewords_html( - u'\xc5ngstr\xf6m was here', 1), u'\xc5ngstr\xf6m ...') - - def test_upper(self): - self.assertEqual(upper(u'Mixed case input'), u'MIXED CASE INPUT') - # lowercase e umlaut - self.assertEqual(upper(u'\xeb'), u'\xcb') - - def test_urlencode(self): - self.assertEqual(urlencode(u'fran\xe7ois & jill'), - u'fran%C3%A7ois%20%26%20jill') - self.assertEqual(urlencode(1), u'1') - - def test_iriencode(self): - self.assertEqual(iriencode(u'S\xf8r-Tr\xf8ndelag'), - u'S%C3%B8r-Tr%C3%B8ndelag') - self.assertEqual(iriencode(urlencode(u'fran\xe7ois & jill')), - u'fran%C3%A7ois%20%26%20jill') - - def test_urlizetrunc(self): - self.assertEqual(urlizetrunc(u'http://short.com/', 20), u'<a href='\ - u'"http://short.com/" rel="nofollow">http://short.com/</a>') - - self.assertEqual(urlizetrunc(u'http://www.google.co.uk/search?hl=en'\ - u'&q=some+long+url&btnG=Search&meta=', 20), u'<a href="http://'\ - u'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&'\ - u'meta=" rel="nofollow">http://www.google...</a>') - - self.assertEqual(urlizetrunc('http://www.google.co.uk/search?hl=en'\ - u'&q=some+long+url&btnG=Search&meta=', 20), u'<a href="http://'\ - u'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search'\ - u'&meta=" rel="nofollow">http://www.google...</a>') - - # Check truncating of URIs which are the exact length - uri = 'http://31characteruri.com/test/' - self.assertEqual(len(uri), 31) - - self.assertEqual(urlizetrunc(uri, 31), - u'<a href="http://31characteruri.com/test/" rel="nofollow">'\ - u'http://31characteruri.com/test/</a>') - - self.assertEqual(urlizetrunc(uri, 30), - u'<a href="http://31characteruri.com/test/" rel="nofollow">'\ - u'http://31characteruri.com/t...</a>') - - self.assertEqual(urlizetrunc(uri, 2), - u'<a href="http://31characteruri.com/test/"'\ - u' rel="nofollow">...</a>') - - def test_urlize(self): - # Check normal urlize - self.assertEqual(urlize('http://google.com'), - u'<a href="http://google.com" rel="nofollow">http://google.com</a>') - self.assertEqual(urlize('http://google.com/'), - u'<a href="http://google.com/" rel="nofollow">http://google.com/</a>') - self.assertEqual(urlize('www.google.com'), - u'<a href="http://www.google.com" rel="nofollow">www.google.com</a>') - self.assertEqual(urlize('djangoproject.org'), - u'<a href="http://djangoproject.org" rel="nofollow">djangoproject.org</a>') - self.assertEqual(urlize('info@djangoproject.org'), - u'<a href="mailto:info@djangoproject.org">info@djangoproject.org</a>') - - # Check urlize with https addresses - self.assertEqual(urlize('https://google.com'), - u'<a href="https://google.com" rel="nofollow">https://google.com</a>') - - def test_wordcount(self): - self.assertEqual(wordcount(''), 0) - self.assertEqual(wordcount(u'oneword'), 1) - self.assertEqual(wordcount(u'lots of words'), 3) - - self.assertEqual(wordwrap(u'this is a long paragraph of text that '\ - u'really needs to be wrapped I\'m afraid', 14), - u"this is a long\nparagraph of\ntext that\nreally needs\nto be "\ - u"wrapped\nI'm afraid") - - self.assertEqual(wordwrap(u'this is a short paragraph of text.\n '\ - u'But this line should be indented', 14), - u'this is a\nshort\nparagraph of\ntext.\n But this\nline '\ - u'should be\nindented') - - self.assertEqual(wordwrap(u'this is a short paragraph of text.\n '\ - u'But this line should be indented',15), u'this is a short\n'\ - u'paragraph of\ntext.\n But this line\nshould be\nindented') - - def test_rjust(self): - self.assertEqual(ljust(u'test', 10), u'test ') - self.assertEqual(ljust(u'test', 3), u'test') - self.assertEqual(rjust(u'test', 10), u' test') - self.assertEqual(rjust(u'test', 3), u'test') - - def test_center(self): - self.assertEqual(center(u'test', 6), u' test ') - - def test_cut(self): - self.assertEqual(cut(u'a string to be mangled', 'a'), - u' string to be mngled') - self.assertEqual(cut(u'a string to be mangled', 'ng'), - u'a stri to be maled') - self.assertEqual(cut(u'a string to be mangled', 'strings'), - u'a string to be mangled') - - def test_force_escape(self): - self.assertEqual( - force_escape(u'<some html & special characters > here'), - u'<some html & special characters > here') - self.assertEqual( - force_escape(u'<some html & special characters > here ĐÅ€£'), - u'<some html & special characters > here'\ - u' \u0110\xc5\u20ac\xa3') - - def test_linebreaks(self): - self.assertEqual(linebreaks(u'line 1'), u'<p>line 1</p>') - self.assertEqual(linebreaks(u'line 1\nline 2'), - u'<p>line 1<br />line 2</p>') - - def test_removetags(self): - self.assertEqual(removetags(u'some <b>html</b> with <script>alert'\ - u'("You smell")</script> disallowed <img /> tags', 'script img'), - u'some <b>html</b> with alert("You smell") disallowed tags') - self.assertEqual(striptags(u'some <b>html</b> with <script>alert'\ - u'("You smell")</script> disallowed <img /> tags'), - u'some html with alert("You smell") disallowed tags') - - def test_dictsort(self): - sorted_dicts = dictsort([{'age': 23, 'name': 'Barbara-Ann'}, - {'age': 63, 'name': 'Ra Ra Rasputin'}, - {'name': 'Jonny B Goode', 'age': 18}], 'age') - - self.assertEqual([sorted(dict.items()) for dict in sorted_dicts], - [[('age', 18), ('name', 'Jonny B Goode')], - [('age', 23), ('name', 'Barbara-Ann')], - [('age', 63), ('name', 'Ra Ra Rasputin')]]) - - def test_dictsortreversed(self): - sorted_dicts = dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'}, - {'age': 63, 'name': 'Ra Ra Rasputin'}, - {'name': 'Jonny B Goode', 'age': 18}], - 'age') - - self.assertEqual([sorted(dict.items()) for dict in sorted_dicts], - [[('age', 63), ('name', 'Ra Ra Rasputin')], - [('age', 23), ('name', 'Barbara-Ann')], - [('age', 18), ('name', 'Jonny B Goode')]]) - - def test_first(self): - self.assertEqual(first([0,1,2]), 0) - self.assertEqual(first(u''), u'') - self.assertEqual(first(u'test'), u't') - - def test_join(self): - self.assertEqual(join([0,1,2], u'glue'), u'0glue1glue2') - - def test_length(self): - self.assertEqual(length(u'1234'), 4) - self.assertEqual(length([1,2,3,4]), 4) - self.assertEqual(length_is([], 0), True) - self.assertEqual(length_is([], 1), False) - self.assertEqual(length_is('a', 1), True) - self.assertEqual(length_is(u'a', 10), False) - - def test_slice(self): - self.assertEqual(slice_(u'abcdefg', u'0'), u'') - self.assertEqual(slice_(u'abcdefg', u'1'), u'a') - self.assertEqual(slice_(u'abcdefg', u'-1'), u'abcdef') - self.assertEqual(slice_(u'abcdefg', u'1:2'), u'b') - self.assertEqual(slice_(u'abcdefg', u'1:3'), u'bc') - self.assertEqual(slice_(u'abcdefg', u'0::2'), u'aceg') - - def test_unordered_list(self): - self.assertEqual(unordered_list([u'item 1', u'item 2']), - u'\t<li>item 1</li>\n\t<li>item 2</li>') - self.assertEqual(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>') - - self.assertEqual( - unordered_list([u'item 1', [u'item 1.1', u'item1.2'], u'item 2']), - u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item1.2'\ - u'</li>\n\t</ul>\n\t</li>\n\t<li>item 2</li>') - - self.assertEqual( - unordered_list([u'item 1', [u'item 1.1', [u'item 1.1.1', - [u'item 1.1.1.1']]]]), - u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1\n\t\t<ul>\n\t\t\t<li>'\ - u'item 1.1.1\n\t\t\t<ul>\n\t\t\t\t<li>item 1.1.1.1</li>\n\t\t\t'\ - u'</ul>\n\t\t\t</li>\n\t\t</ul>\n\t\t</li>\n\t</ul>\n\t</li>') - - self.assertEqual(unordered_list( - ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]), - u'\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>'\ - u'Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>'\ - u'\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>') - - class ULItem(object): - def __init__(self, title): - self.title = title - def __unicode__(self): - return u'ulitem-%s' % str(self.title) - - a = ULItem('a') - b = ULItem('b') - self.assertEqual(unordered_list([a,b]), - u'\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>') - - # Old format for unordered lists should still work - self.assertEqual(unordered_list([u'item 1', []]), u'\t<li>item 1</li>') - - self.assertEqual(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>') - - self.assertEqual(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'\ - u'</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>') - - self.assertEqual(unordered_list(['States', [['Kansas', [['Lawrence', - []], ['Topeka', []]]], ['Illinois', []]]]), u'\t<li>States\n\t'\ - u'<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>'\ - u'\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>'\ - u'Illinois</li>\n\t</ul>\n\t</li>') - - def test_add(self): - self.assertEqual(add(u'1', u'2'), 3) - - def test_get_digit(self): - self.assertEqual(get_digit(123, 1), 3) - self.assertEqual(get_digit(123, 2), 2) - self.assertEqual(get_digit(123, 3), 1) - self.assertEqual(get_digit(123, 4), 0) - self.assertEqual(get_digit(123, 0), 123) - self.assertEqual(get_digit(u'xyz', 0), u'xyz') - - def test_date(self): - # real testing of date() is in dateformat.py - self.assertEqual(date(datetime.datetime(2005, 12, 29), u"d F Y"), - u'29 December 2005') - self.assertEqual(date(datetime.datetime(2005, 12, 29), ur'jS o\f F'), - u'29th of December') - - def test_time(self): - # real testing of time() is done in dateformat.py - self.assertEqual(time(datetime.time(13), u"h"), u'01') - self.assertEqual(time(datetime.time(0), u"h"), u'12') - - def test_timesince(self): - # real testing is done in timesince.py, where we can provide our own 'now' - self.assertEqual( - timesince(datetime.datetime.now() - datetime.timedelta(1)), - u'1 day') - - self.assertEqual( - timesince(datetime.datetime(2005, 12, 29), - datetime.datetime(2005, 12, 30)), - u'1 day') - - def test_timeuntil(self): - self.assertEqual( - timeuntil(datetime.datetime.now() + datetime.timedelta(1)), - u'1 day') - - self.assertEqual(timeuntil(datetime.datetime(2005, 12, 30), - datetime.datetime(2005, 12, 29)), - u'1 day') - - def test_default(self): - self.assertEqual(default(u"val", u"default"), u'val') - self.assertEqual(default(None, u"default"), u'default') - self.assertEqual(default(u'', u"default"), u'default') - - def test_if_none(self): - self.assertEqual(default_if_none(u"val", u"default"), u'val') - self.assertEqual(default_if_none(None, u"default"), u'default') - self.assertEqual(default_if_none(u'', u"default"), u'') - - def test_divisibleby(self): - self.assertEqual(divisibleby(4, 2), True) - self.assertEqual(divisibleby(4, 3), False) - - def test_yesno(self): - self.assertEqual(yesno(True), u'yes') - self.assertEqual(yesno(False), u'no') - self.assertEqual(yesno(None), u'maybe') - self.assertEqual(yesno(True, u'certainly,get out of town,perhaps'), - u'certainly') - self.assertEqual(yesno(False, u'certainly,get out of town,perhaps'), - u'get out of town') - self.assertEqual(yesno(None, u'certainly,get out of town,perhaps'), - u'perhaps') - self.assertEqual(yesno(None, u'certainly,get out of town'), - u'get out of town') - - def test_filesizeformat(self): - self.assertEqual(filesizeformat(1023), u'1023 bytes') - self.assertEqual(filesizeformat(1024), u'1.0 KB') - self.assertEqual(filesizeformat(10*1024), u'10.0 KB') - self.assertEqual(filesizeformat(1024*1024-1), u'1024.0 KB') - self.assertEqual(filesizeformat(1024*1024), u'1.0 MB') - self.assertEqual(filesizeformat(1024*1024*50), u'50.0 MB') - self.assertEqual(filesizeformat(1024*1024*1024-1), u'1024.0 MB') - self.assertEqual(filesizeformat(1024*1024*1024), u'1.0 GB') - self.assertEqual(filesizeformat(complex(1,-1)), u'0 bytes') - self.assertEqual(filesizeformat(""), u'0 bytes') - self.assertEqual(filesizeformat(u"\N{GREEK SMALL LETTER ALPHA}"), - u'0 bytes') - - def test_pluralize(self): - self.assertEqual(pluralize(1), u'') - self.assertEqual(pluralize(0), u's') - self.assertEqual(pluralize(2), u's') - self.assertEqual(pluralize([1]), u'') - self.assertEqual(pluralize([]), u's') - self.assertEqual(pluralize([1,2,3]), u's') - self.assertEqual(pluralize(1,u'es'), u'') - self.assertEqual(pluralize(0,u'es'), u'es') - self.assertEqual(pluralize(2,u'es'), u'es') - self.assertEqual(pluralize(1,u'y,ies'), u'y') - self.assertEqual(pluralize(0,u'y,ies'), u'ies') - self.assertEqual(pluralize(2,u'y,ies'), u'ies') - self.assertEqual(pluralize(0,u'y,ies,error'), u'') - - def test_phone2numeric(self): - self.assertEqual(phone2numeric(u'0800 flowers'), u'0800 3569377') - - def test_non_string_input(self): - # Filters shouldn't break if passed non-strings - self.assertEqual(addslashes(123), u'123') - self.assertEqual(linenumbers(123), u'1. 123') - self.assertEqual(lower(123), u'123') - self.assertEqual(make_list(123), [u'1', u'2', u'3']) - self.assertEqual(slugify(123), u'123') - self.assertEqual(title(123), u'123') - self.assertEqual(truncatewords(123, 2), u'123') - self.assertEqual(upper(123), u'123') - self.assertEqual(urlencode(123), u'123') - self.assertEqual(urlize(123), u'123') - self.assertEqual(urlizetrunc(123, 1), u'123') - self.assertEqual(wordcount(123), 1) - self.assertEqual(wordwrap(123, 2), u'123') - self.assertEqual(ljust('123', 4), u'123 ') - self.assertEqual(rjust('123', 4), u' 123') - self.assertEqual(center('123', 5), u' 123 ') - self.assertEqual(center('123', 6), u' 123 ') - self.assertEqual(cut(123, '2'), u'13') - self.assertEqual(escape(123), u'123') - self.assertEqual(linebreaks(123), u'<p>123</p>') - self.assertEqual(linebreaksbr(123), u'123') - self.assertEqual(removetags(123, 'a'), u'123') - self.assertEqual(striptags(123), u'123') - diff --git a/parts/django/tests/regressiontests/defer_regress/__init__.py b/parts/django/tests/regressiontests/defer_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/defer_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/defer_regress/models.py b/parts/django/tests/regressiontests/defer_regress/models.py deleted file mode 100644 index 8db8c29..0000000 --- a/parts/django/tests/regressiontests/defer_regress/models.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Regression tests for defer() / only() behavior. -""" - -from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from django.db import connection, models - -class Item(models.Model): - name = models.CharField(max_length=15) - text = models.TextField(default="xyzzy") - value = models.IntegerField() - other_value = models.IntegerField(default=0) - - def __unicode__(self): - return self.name - -class RelatedItem(models.Model): - item = models.ForeignKey(Item) - -class Child(models.Model): - name = models.CharField(max_length=10) - value = models.IntegerField() - -class Leaf(models.Model): - name = models.CharField(max_length=10) - child = models.ForeignKey(Child) - second_child = models.ForeignKey(Child, related_name="other", null=True) - value = models.IntegerField(default=42) - - def __unicode__(self): - return self.name - -class ResolveThis(models.Model): - num = models.FloatField() - name = models.CharField(max_length=16) diff --git a/parts/django/tests/regressiontests/defer_regress/tests.py b/parts/django/tests/regressiontests/defer_regress/tests.py deleted file mode 100644 index 05f1279..0000000 --- a/parts/django/tests/regressiontests/defer_regress/tests.py +++ /dev/null @@ -1,163 +0,0 @@ -from operator import attrgetter - -from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from django.contrib.sessions.backends.db import SessionStore -from django.db import connection -from django.db.models.loading import cache -from django.test import TestCase - -from models import ResolveThis, Item, RelatedItem, Child, Leaf - - -class DeferRegressionTest(TestCase): - def assert_num_queries(self, n, func, *args, **kwargs): - old_DEBUG = settings.DEBUG - settings.DEBUG = True - starting_queries = len(connection.queries) - try: - func(*args, **kwargs) - finally: - settings.DEBUG = old_DEBUG - self.assertEqual(starting_queries + n, len(connection.queries)) - - def test_basic(self): - # Deferred fields should really be deferred and not accidentally use - # the field's default value just because they aren't passed to __init__ - - Item.objects.create(name="first", value=42) - obj = Item.objects.only("name", "other_value").get(name="first") - # Accessing "name" doesn't trigger a new database query. Accessing - # "value" or "text" should. - def test(): - self.assertEqual(obj.name, "first") - self.assertEqual(obj.other_value, 0) - self.assert_num_queries(0, test) - - def test(): - self.assertEqual(obj.value, 42) - self.assert_num_queries(1, test) - - def test(): - self.assertEqual(obj.text, "xyzzy") - self.assert_num_queries(1, test) - - def test(): - self.assertEqual(obj.text, "xyzzy") - self.assert_num_queries(0, test) - - # Regression test for #10695. Make sure different instances don't - # inadvertently share data in the deferred descriptor objects. - i = Item.objects.create(name="no I'm first", value=37) - items = Item.objects.only("value").order_by("-value") - self.assertEqual(items[0].name, "first") - self.assertEqual(items[1].name, "no I'm first") - - RelatedItem.objects.create(item=i) - r = RelatedItem.objects.defer("item").get() - self.assertEqual(r.item_id, i.id) - self.assertEqual(r.item, i) - - # Some further checks for select_related() and inherited model - # behaviour (regression for #10710). - c1 = Child.objects.create(name="c1", value=42) - c2 = Child.objects.create(name="c2", value=37) - Leaf.objects.create(name="l1", child=c1, second_child=c2) - - obj = Leaf.objects.only("name", "child").select_related()[0] - self.assertEqual(obj.child.name, "c1") - - self.assertQuerysetEqual( - Leaf.objects.select_related().only("child__name", "second_child__name"), [ - "l1", - ], - attrgetter("name") - ) - - # Models instances with deferred fields should still return the same - # content types as their non-deferred versions (bug #10738). - ctype = ContentType.objects.get_for_model - c1 = ctype(Item.objects.all()[0]) - c2 = ctype(Item.objects.defer("name")[0]) - c3 = ctype(Item.objects.only("name")[0]) - self.assertTrue(c1 is c2 is c3) - - # Regression for #10733 - only() can be used on a model with two - # foreign keys. - results = Leaf.objects.only("name", "child", "second_child").select_related() - self.assertEqual(results[0].child.name, "c1") - self.assertEqual(results[0].second_child.name, "c2") - - results = Leaf.objects.only("name", "child", "second_child", "child__name", "second_child__name").select_related() - self.assertEqual(results[0].child.name, "c1") - self.assertEqual(results[0].second_child.name, "c2") - - # Test for #12163 - Pickling error saving session with unsaved model - # instances. - SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead' - - item = Item() - item._deferred = False - s = SessionStore(SESSION_KEY) - s.clear() - s["item"] = item - s.save() - - s = SessionStore(SESSION_KEY) - s.modified = True - s.save() - - i2 = s["item"] - self.assertFalse(i2._deferred) - - # Regression for #11936 - loading.get_models should not return deferred - # models by default. - klasses = sorted( - cache.get_models(cache.get_app("defer_regress")), - key=lambda klass: klass.__name__ - ) - self.assertEqual( - klasses, [ - Child, - Item, - Leaf, - RelatedItem, - ResolveThis, - ] - ) - - klasses = sorted( - map( - attrgetter("__name__"), - cache.get_models( - cache.get_app("defer_regress"), include_deferred=True - ), - ) - ) - self.assertEqual( - klasses, [ - "Child", - "Child_Deferred_value", - "Item", - "Item_Deferred_name", - "Item_Deferred_name_other_value_text", - "Item_Deferred_name_other_value_value", - "Item_Deferred_other_value_text_value", - "Item_Deferred_text_value", - "Leaf", - "Leaf_Deferred_child_id_second_child_id_value", - "Leaf_Deferred_name_value", - "Leaf_Deferred_second_child_value", - "Leaf_Deferred_value", - "RelatedItem", - "RelatedItem_Deferred_", - "RelatedItem_Deferred_item_id", - "ResolveThis", - ] - ) - - def test_resolve_columns(self): - rt = ResolveThis.objects.create(num=5.0, name='Foobar') - qs = ResolveThis.objects.defer('num') - self.assertEqual(1, qs.count()) - self.assertEqual('Foobar', qs[0].name) diff --git a/parts/django/tests/regressiontests/delete_regress/__init__.py b/parts/django/tests/regressiontests/delete_regress/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/delete_regress/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/delete_regress/models.py b/parts/django/tests/regressiontests/delete_regress/models.py deleted file mode 100644 index 8109c0a..0000000 --- a/parts/django/tests/regressiontests/delete_regress/models.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.db import models - -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType - -class Award(models.Model): - name = models.CharField(max_length=25) - object_id = models.PositiveIntegerField() - content_type = models.ForeignKey(ContentType) - content_object = generic.GenericForeignKey() - -class AwardNote(models.Model): - award = models.ForeignKey(Award) - note = models.CharField(max_length=100) - -class Person(models.Model): - name = models.CharField(max_length=25) - awards = generic.GenericRelation(Award) - -class Book(models.Model): - pagecount = models.IntegerField() - -class Toy(models.Model): - name = models.CharField(max_length=50) - -class Child(models.Model): - name = models.CharField(max_length=50) - toys = models.ManyToManyField(Toy, through='PlayedWith') - -class PlayedWith(models.Model): - child = models.ForeignKey(Child) - toy = models.ForeignKey(Toy) - date = models.DateField(db_column='date_col') - -class PlayedWithNote(models.Model): - played = models.ForeignKey(PlayedWith) - note = models.TextField() diff --git a/parts/django/tests/regressiontests/delete_regress/tests.py b/parts/django/tests/regressiontests/delete_regress/tests.py deleted file mode 100644 index 26cd3c5..0000000 --- a/parts/django/tests/regressiontests/delete_regress/tests.py +++ /dev/null @@ -1,116 +0,0 @@ -import datetime - -from django.conf import settings -from django.db import backend, connection, transaction, DEFAULT_DB_ALIAS -from django.test import TestCase, TransactionTestCase - -from models import Book, Award, AwardNote, Person, Child, Toy, PlayedWith, PlayedWithNote - -# Can't run this test under SQLite, because you can't -# get two connections to an in-memory database. -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.sqlite3': - class DeleteLockingTest(TransactionTestCase): - def setUp(self): - # Create a second connection to the default database - conn_settings = settings.DATABASES[DEFAULT_DB_ALIAS] - self.conn2 = backend.DatabaseWrapper({ - 'HOST': conn_settings['HOST'], - 'NAME': conn_settings['NAME'], - 'OPTIONS': conn_settings['OPTIONS'], - 'PASSWORD': conn_settings['PASSWORD'], - 'PORT': conn_settings['PORT'], - 'USER': conn_settings['USER'], - 'TIME_ZONE': settings.TIME_ZONE, - }) - - # Put both DB connections into managed transaction mode - transaction.enter_transaction_management() - transaction.managed(True) - self.conn2._enter_transaction_management(True) - - def tearDown(self): - # Close down the second connection. - transaction.leave_transaction_management() - self.conn2.close() - - def test_concurrent_delete(self): - "Deletes on concurrent transactions don't collide and lock the database. Regression for #9479" - - # Create some dummy data - b1 = Book(id=1, pagecount=100) - b2 = Book(id=2, pagecount=200) - b3 = Book(id=3, pagecount=300) - b1.save() - b2.save() - b3.save() - - transaction.commit() - - self.assertEquals(3, Book.objects.count()) - - # Delete something using connection 2. - cursor2 = self.conn2.cursor() - cursor2.execute('DELETE from delete_regress_book WHERE id=1') - self.conn2._commit(); - - # Now perform a queryset delete that covers the object - # deleted in connection 2. This causes an infinite loop - # under MySQL InnoDB unless we keep track of already - # deleted objects. - Book.objects.filter(pagecount__lt=250).delete() - transaction.commit() - self.assertEquals(1, Book.objects.count()) - -class DeleteCascadeTests(TestCase): - def test_generic_relation_cascade(self): - """ - Test that Django cascades deletes through generic-related - objects to their reverse relations. - - This might falsely succeed if the database cascades deletes - itself immediately; the postgresql_psycopg2 backend does not - give such a false success because ForeignKeys are created with - DEFERRABLE INITIALLY DEFERRED, so its internal cascade is - delayed until transaction commit. - - """ - person = Person.objects.create(name='Nelson Mandela') - award = Award.objects.create(name='Nobel', content_object=person) - note = AwardNote.objects.create(note='a peace prize', - award=award) - self.assertEquals(AwardNote.objects.count(), 1) - person.delete() - self.assertEquals(Award.objects.count(), 0) - # first two asserts are just sanity checks, this is the kicker: - self.assertEquals(AwardNote.objects.count(), 0) - - def test_fk_to_m2m_through(self): - """ - Test that if a M2M relationship has an explicitly-specified - through model, and some other model has an FK to that through - model, deletion is cascaded from one of the participants in - the M2M, to the through model, to its related model. - - Like the above test, this could in theory falsely succeed if - the DB cascades deletes itself immediately. - - """ - juan = Child.objects.create(name='Juan') - paints = Toy.objects.create(name='Paints') - played = PlayedWith.objects.create(child=juan, toy=paints, - date=datetime.date.today()) - note = PlayedWithNote.objects.create(played=played, - note='the next Jackson Pollock') - self.assertEquals(PlayedWithNote.objects.count(), 1) - paints.delete() - self.assertEquals(PlayedWith.objects.count(), 0) - # first two asserts just sanity checks, this is the kicker: - self.assertEquals(PlayedWithNote.objects.count(), 0) - -class LargeDeleteTests(TestCase): - def test_large_deletes(self): - "Regression for #13309 -- if the number of objects > chunk size, deletion still occurs" - for x in range(300): - track = Book.objects.create(pagecount=x+100) - Book.objects.all().delete() - self.assertEquals(Book.objects.count(), 0) diff --git a/parts/django/tests/regressiontests/dispatch/__init__.py b/parts/django/tests/regressiontests/dispatch/__init__.py deleted file mode 100644 index 679895b..0000000 --- a/parts/django/tests/regressiontests/dispatch/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Unit-tests for the dispatch project -""" diff --git a/parts/django/tests/regressiontests/dispatch/models.py b/parts/django/tests/regressiontests/dispatch/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/dispatch/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/dispatch/tests/__init__.py b/parts/django/tests/regressiontests/dispatch/tests/__init__.py deleted file mode 100644 index 150bb01..0000000 --- a/parts/django/tests/regressiontests/dispatch/tests/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -Unit-tests for the dispatch project -""" - -from test_saferef import * -from test_dispatcher import * diff --git a/parts/django/tests/regressiontests/dispatch/tests/test_dispatcher.py b/parts/django/tests/regressiontests/dispatch/tests/test_dispatcher.py deleted file mode 100644 index ad3a05f..0000000 --- a/parts/django/tests/regressiontests/dispatch/tests/test_dispatcher.py +++ /dev/null @@ -1,123 +0,0 @@ -from django.dispatch import Signal -import unittest -import sys -import gc -import django.utils.copycompat as copy - -if sys.platform.startswith('java'): - def garbage_collect(): - """Run the garbage collector and wait a bit to let it do his work""" - import time - gc.collect() - time.sleep(0.1) -else: - def garbage_collect(): - gc.collect() - -def receiver_1_arg(val, **kwargs): - return val - -class Callable(object): - def __call__(self, val, **kwargs): - return val - - def a(self, val, **kwargs): - return val - -a_signal = Signal(providing_args=["val"]) - -class DispatcherTests(unittest.TestCase): - """Test suite for dispatcher (barely started)""" - - def _testIsClean(self, signal): - """Assert that everything has been cleaned up automatically""" - self.assertEqual(signal.receivers, []) - - # force cleanup just in case - signal.receivers = [] - - def testExact(self): - a_signal.connect(receiver_1_arg, sender=self) - expected = [(receiver_1_arg,"test")] - result = a_signal.send(sender=self, val="test") - self.assertEqual(result, expected) - a_signal.disconnect(receiver_1_arg, sender=self) - self._testIsClean(a_signal) - - def testIgnoredSender(self): - a_signal.connect(receiver_1_arg) - expected = [(receiver_1_arg,"test")] - result = a_signal.send(sender=self, val="test") - self.assertEqual(result, expected) - a_signal.disconnect(receiver_1_arg) - self._testIsClean(a_signal) - - def testGarbageCollected(self): - a = Callable() - a_signal.connect(a.a, sender=self) - expected = [] - del a - garbage_collect() - result = a_signal.send(sender=self, val="test") - self.assertEqual(result, expected) - self._testIsClean(a_signal) - - def testMultipleRegistration(self): - a = Callable() - a_signal.connect(a) - a_signal.connect(a) - a_signal.connect(a) - a_signal.connect(a) - a_signal.connect(a) - a_signal.connect(a) - result = a_signal.send(sender=self, val="test") - self.assertEqual(len(result), 1) - self.assertEqual(len(a_signal.receivers), 1) - del a - del result - garbage_collect() - self._testIsClean(a_signal) - - def testUidRegistration(self): - def uid_based_receiver_1(**kwargs): - pass - - def uid_based_receiver_2(**kwargs): - pass - - a_signal.connect(uid_based_receiver_1, dispatch_uid = "uid") - a_signal.connect(uid_based_receiver_2, dispatch_uid = "uid") - self.assertEqual(len(a_signal.receivers), 1) - a_signal.disconnect(dispatch_uid = "uid") - self._testIsClean(a_signal) - - def testRobust(self): - """Test the sendRobust function""" - def fails(val, **kwargs): - raise ValueError('this') - a_signal.connect(fails) - result = a_signal.send_robust(sender=self, val="test") - err = result[0][1] - self.assert_(isinstance(err, ValueError)) - self.assertEqual(err.args, ('this',)) - a_signal.disconnect(fails) - self._testIsClean(a_signal) - - def testDisconnection(self): - receiver_1 = Callable() - receiver_2 = Callable() - receiver_3 = Callable() - a_signal.connect(receiver_1) - a_signal.connect(receiver_2) - a_signal.connect(receiver_3) - a_signal.disconnect(receiver_1) - del receiver_2 - garbage_collect() - a_signal.disconnect(receiver_3) - self._testIsClean(a_signal) - -def getSuite(): - return unittest.makeSuite(DispatcherTests,'test') - -if __name__ == "__main__": - unittest.main() diff --git a/parts/django/tests/regressiontests/dispatch/tests/test_saferef.py b/parts/django/tests/regressiontests/dispatch/tests/test_saferef.py deleted file mode 100644 index c0ec879..0000000 --- a/parts/django/tests/regressiontests/dispatch/tests/test_saferef.py +++ /dev/null @@ -1,79 +0,0 @@ -from django.dispatch.saferef import * - -import unittest - -class Test1(object): - def x(self): - pass - -def test2(obj): - pass - -class Test2(object): - def __call__(self, obj): - pass - -class Tester(unittest.TestCase): - def setUp(self): - ts = [] - ss = [] - for x in xrange(5000): - t = Test1() - ts.append(t) - s = safeRef(t.x, self._closure) - ss.append(s) - ts.append(test2) - ss.append(safeRef(test2, self._closure)) - for x in xrange(30): - t = Test2() - ts.append(t) - s = safeRef(t, self._closure) - ss.append(s) - self.ts = ts - self.ss = ss - self.closureCount = 0 - - def tearDown(self): - del self.ts - del self.ss - - def testIn(self): - """Test the "in" operator for safe references (cmp)""" - for t in self.ts[:50]: - self.assert_(safeRef(t.x) in self.ss) - - def testValid(self): - """Test that the references are valid (return instance methods)""" - for s in self.ss: - self.assert_(s()) - - def testShortCircuit (self): - """Test that creation short-circuits to reuse existing references""" - sd = {} - for s in self.ss: - sd[s] = 1 - for t in self.ts: - if hasattr(t, 'x'): - self.assert_(sd.has_key(safeRef(t.x))) - self.assert_(safeRef(t.x) in sd) - else: - self.assert_(sd.has_key(safeRef(t))) - self.assert_(safeRef(t) in sd) - - def testRepresentation (self): - """Test that the reference object's representation works - - XXX Doesn't currently check the results, just that no error - is raised - """ - repr(self.ss[-1]) - - def _closure(self, ref): - """Dumb utility mechanism to increment deletion counter""" - self.closureCount +=1 - -def getSuite(): - return unittest.makeSuite(Tester,'test') - -if __name__ == "__main__": - unittest.main() diff --git a/parts/django/tests/regressiontests/expressions_regress/__init__.py b/parts/django/tests/regressiontests/expressions_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/expressions_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/expressions_regress/models.py b/parts/django/tests/regressiontests/expressions_regress/models.py deleted file mode 100644 index f2997ee..0000000 --- a/parts/django/tests/regressiontests/expressions_regress/models.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -Model for testing arithmetic expressions. -""" -from django.db import models - -class Number(models.Model): - integer = models.IntegerField(db_column='the_integer') - float = models.FloatField(null=True, db_column='the_float') - - def __unicode__(self): - return u'%i, %.3f' % (self.integer, self.float) - diff --git a/parts/django/tests/regressiontests/expressions_regress/tests.py b/parts/django/tests/regressiontests/expressions_regress/tests.py deleted file mode 100644 index a662728..0000000 --- a/parts/django/tests/regressiontests/expressions_regress/tests.py +++ /dev/null @@ -1,195 +0,0 @@ -""" -Spanning tests for all the operations that F() expressions can perform. -""" -from django.test import TestCase, Approximate - -from django.conf import settings -from django.db import models, DEFAULT_DB_ALIAS -from django.db.models import F - -from regressiontests.expressions_regress.models import Number - -class ExpressionsRegressTests(TestCase): - - def setUp(self): - Number(integer=-1).save() - Number(integer=42).save() - Number(integer=1337).save() - self.assertEqual(Number.objects.update(float=F('integer')), 3) - - def test_fill_with_value_from_same_object(self): - """ - We can fill a value in all objects with an other value of the - same object. - """ - self.assertQuerysetEqual( - Number.objects.all(), - [ - '<Number: -1, -1.000>', - '<Number: 42, 42.000>', - '<Number: 1337, 1337.000>' - ] - ) - - def test_increment_value(self): - """ - We can increment a value of all objects in a query set. - """ - self.assertEqual( - Number.objects.filter(integer__gt=0) - .update(integer=F('integer') + 1), - 2) - - self.assertQuerysetEqual( - Number.objects.all(), - [ - '<Number: -1, -1.000>', - '<Number: 43, 42.000>', - '<Number: 1338, 1337.000>' - ] - ) - - def test_filter_not_equals_other_field(self): - """ - We can filter for objects, where a value is not equals the value - of an other field. - """ - self.assertEqual( - Number.objects.filter(integer__gt=0) - .update(integer=F('integer') + 1), - 2) - self.assertQuerysetEqual( - Number.objects.exclude(float=F('integer')), - [ - '<Number: 43, 42.000>', - '<Number: 1338, 1337.000>' - ] - ) - - def test_complex_expressions(self): - """ - Complex expressions of different connection types are possible. - """ - n = Number.objects.create(integer=10, float=123.45) - self.assertEqual(Number.objects.filter(pk=n.pk) - .update(float=F('integer') + F('float') * 2), - 1) - - self.assertEqual(Number.objects.get(pk=n.pk).integer, 10) - self.assertEqual(Number.objects.get(pk=n.pk).float, Approximate(256.900, places=3)) - -class ExpressionOperatorTests(TestCase): - def setUp(self): - self.n = Number.objects.create(integer=42, float=15.5) - - def test_lefthand_addition(self): - # LH Addition of floats and integers - Number.objects.filter(pk=self.n.pk).update( - integer=F('integer') + 15, - float=F('float') + 42.7 - ) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) - - def test_lefthand_subtraction(self): - # LH Subtraction of floats and integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') - 15, - float=F('float') - 42.7) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(-27.200, places=3)) - - def test_lefthand_multiplication(self): - # Multiplication of floats and integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') * 15, - float=F('float') * 42.7) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) - - def test_lefthand_division(self): - # LH Division of floats and integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') / 2, - float=F('float') / 42.7) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 21) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(0.363, places=3)) - - def test_lefthand_modulo(self): - # LH Modulo arithmetic on integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') % 20) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 2) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - - def test_lefthand_bitwise_and(self): - # LH Bitwise ands on integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') & 56) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': - def test_lefthand_bitwise_or(self): - # LH Bitwise or on integers - Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - - def test_right_hand_addition(self): - # Right hand operators - Number.objects.filter(pk=self.n.pk).update(integer=15 + F('integer'), - float=42.7 + F('float')) - - # RH Addition of floats and integers - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) - - def test_right_hand_subtraction(self): - Number.objects.filter(pk=self.n.pk).update(integer=15 - F('integer'), - float=42.7 - F('float')) - - # RH Subtraction of floats and integers - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, -27) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(27.200, places=3)) - - def test_right_hand_multiplication(self): - # RH Multiplication of floats and integers - Number.objects.filter(pk=self.n.pk).update(integer=15 * F('integer'), - float=42.7 * F('float')) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) - - def test_right_hand_division(self): - # RH Division of floats and integers - Number.objects.filter(pk=self.n.pk).update(integer=640 / F('integer'), - float=42.7 / F('float')) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 15) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(2.755, places=3)) - - def test_right_hand_modulo(self): - # RH Modulo arithmetic on integers - Number.objects.filter(pk=self.n.pk).update(integer=69 % F('integer')) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - - def test_right_hand_bitwise_and(self): - # RH Bitwise ands on integers - Number.objects.filter(pk=self.n.pk).update(integer=15 & F('integer')) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 10) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': - def test_right_hand_bitwise_or(self): - # RH Bitwise or on integers - Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer')) - - self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47) - self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) - diff --git a/parts/django/tests/regressiontests/extra_regress/__init__.py b/parts/django/tests/regressiontests/extra_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/extra_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/extra_regress/models.py b/parts/django/tests/regressiontests/extra_regress/models.py deleted file mode 100644 index 073157a..0000000 --- a/parts/django/tests/regressiontests/extra_regress/models.py +++ /dev/null @@ -1,40 +0,0 @@ -import datetime - -import django.utils.copycompat as copy - -from django.contrib.auth.models import User -from django.db import models - -class RevisionableModel(models.Model): - base = models.ForeignKey('self', null=True) - title = models.CharField(blank=True, max_length=255) - when = models.DateTimeField(default=datetime.datetime.now) - - def __unicode__(self): - return u"%s (%s, %s)" % (self.title, self.id, self.base.id) - - def save(self, *args, **kwargs): - super(RevisionableModel, self).save(*args, **kwargs) - if not self.base: - self.base = self - kwargs.pop('force_insert', None) - kwargs.pop('force_update', None) - super(RevisionableModel, self).save(*args, **kwargs) - - def new_revision(self): - new_revision = copy.copy(self) - new_revision.pk = None - return new_revision - -class Order(models.Model): - created_by = models.ForeignKey(User) - text = models.TextField() - -class TestObject(models.Model): - first = models.CharField(max_length=20) - second = models.CharField(max_length=20) - third = models.CharField(max_length=20) - - def __unicode__(self): - return u'TestObject: %s,%s,%s' % (self.first,self.second,self.third) - diff --git a/parts/django/tests/regressiontests/extra_regress/tests.py b/parts/django/tests/regressiontests/extra_regress/tests.py deleted file mode 100644 index ef7cbb8..0000000 --- a/parts/django/tests/regressiontests/extra_regress/tests.py +++ /dev/null @@ -1,314 +0,0 @@ -from django.test import TestCase - -from django.utils.datastructures import SortedDict - -from django.contrib.auth.models import User -from regressiontests.extra_regress.models import TestObject, Order, \ - RevisionableModel - -import datetime - -class ExtraRegressTests(TestCase): - - def setUp(self): - self.u = User.objects.create_user( - username="fred", - password="secret", - email="fred@example.com" - ) - - def test_regression_7314_7372(self): - """ - Regression tests for #7314 and #7372 - """ - rm = RevisionableModel.objects.create( - title='First Revision', - when=datetime.datetime(2008, 9, 28, 10, 30, 0) - ) - self.assertEqual(rm.pk, rm.base.pk) - - rm2 = rm.new_revision() - rm2.title = "Second Revision" - rm.when = datetime.datetime(2008, 9, 28, 14, 25, 0) - rm2.save() - - self.assertEqual(rm2.title, 'Second Revision') - self.assertEqual(rm2.base.title, 'First Revision') - - self.assertNotEqual(rm2.pk, rm.pk) - self.assertEqual(rm2.base.pk, rm.pk) - - # Queryset to match most recent revision: - qs = RevisionableModel.objects.extra( - where=["%(table)s.id IN (SELECT MAX(rev.id) FROM %(table)s rev GROUP BY rev.base_id)" % { - 'table': RevisionableModel._meta.db_table, - }] - ) - - self.assertQuerysetEqual(qs, - [('Second Revision', 'First Revision')], - transform=lambda r: (r.title, r.base.title) - ) - - # Queryset to search for string in title: - qs2 = RevisionableModel.objects.filter(title__contains="Revision") - self.assertQuerysetEqual(qs2, - [ - ('First Revision', 'First Revision'), - ('Second Revision', 'First Revision'), - ], - transform=lambda r: (r.title, r.base.title) - ) - - # Following queryset should return the most recent revision: - self.assertQuerysetEqual(qs & qs2, - [('Second Revision', 'First Revision')], - transform=lambda r: (r.title, r.base.title) - ) - - def test_extra_stay_tied(self): - # Extra select parameters should stay tied to their corresponding - # select portions. Applies when portions are updated or otherwise - # moved around. - qs = User.objects.extra( - select=SortedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))), - select_params=(1, 3) - ) - qs = qs.extra(select={"beta": 4}) - qs = qs.extra(select={"alpha": "%s"}, select_params=[5]) - self.assertEqual( - list(qs.filter(id=self.u.id).values('alpha', 'beta', 'gamma')), - [{'alpha': 5, 'beta': 4, 'gamma': 3}] - ) - - def test_regression_7957(self): - """ - Regression test for #7957: Combining extra() calls should leave the - corresponding parameters associated with the right extra() bit. I.e. - internal dictionary must remain sorted. - """ - self.assertEqual( - User.objects.extra(select={"alpha": "%s"}, select_params=(1,) - ).extra(select={"beta": "%s"}, select_params=(2,))[0].alpha, - 1) - - self.assertEqual( - User.objects.extra(select={"beta": "%s"}, select_params=(1,) - ).extra(select={"alpha": "%s"}, select_params=(2,))[0].alpha, - 2) - - def test_regression_7961(self): - """ - Regression test for #7961: When not using a portion of an - extra(...) in a query, remove any corresponding parameters from the - query as well. - """ - self.assertEqual( - list(User.objects.extra(select={"alpha": "%s"}, select_params=(-6,) - ).filter(id=self.u.id).values_list('id', flat=True)), - [self.u.id] - ) - - def test_regression_8063(self): - """ - Regression test for #8063: limiting a query shouldn't discard any - extra() bits. - """ - qs = User.objects.all().extra(where=['id=%s'], params=[self.u.id]) - self.assertQuerysetEqual(qs, ['<User: fred>']) - self.assertQuerysetEqual(qs[:1], ['<User: fred>']) - - def test_regression_8039(self): - """ - Regression test for #8039: Ordering sometimes removed relevant tables - from extra(). This test is the critical case: ordering uses a table, - but then removes the reference because of an optimisation. The table - should still be present because of the extra() call. - """ - self.assertQuerysetEqual( - Order.objects.extra(where=["username=%s"], - params=["fred"], - tables=["auth_user"] - ).order_by('created_by'), - [] - ) - - def test_regression_8819(self): - """ - Regression test for #8819: Fields in the extra(select=...) list - should be available to extra(order_by=...). - """ - self.assertQuerysetEqual( - User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}).distinct(), - ['<User: fred>'] - ) - self.assertQuerysetEqual( - User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}, order_by=['extra_field']), - ['<User: fred>'] - ) - self.assertQuerysetEqual( - User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}, order_by=['extra_field']).distinct(), - ['<User: fred>'] - ) - - def test_dates_query(self): - """ - When calling the dates() method on a queryset with extra selection - columns, we can (and should) ignore those columns. They don't change - the result and cause incorrect SQL to be produced otherwise. - """ - rm = RevisionableModel.objects.create( - title='First Revision', - when=datetime.datetime(2008, 9, 28, 10, 30, 0) - ) - - self.assertQuerysetEqual( - RevisionableModel.objects.extra(select={"the_answer": 'id'}).dates('when', 'month'), - ['datetime.datetime(2008, 9, 1, 0, 0)'] - ) - - def test_values_with_extra(self): - """ - Regression test for #10256... If there is a values() clause, Extra - columns are only returned if they are explicitly mentioned. - """ - obj = TestObject(first='first', second='second', third='third') - obj.save() - - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()), - [{'bar': u'second', 'third': u'third', 'second': u'second', 'whiz': u'third', 'foo': u'first', 'id': obj.pk, 'first': u'first'}] - ) - - # Extra clauses after an empty values clause are still included - self.assertEqual( - list(TestObject.objects.values().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), - [{'bar': u'second', 'third': u'third', 'second': u'second', 'whiz': u'third', 'foo': u'first', 'id': obj.pk, 'first': u'first'}] - ) - - # Extra columns are ignored if not mentioned in the values() clause - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')), - [{'second': u'second', 'first': u'first'}] - ) - - # Extra columns after a non-empty values() clause are ignored - self.assertEqual( - list(TestObject.objects.values('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), - [{'second': u'second', 'first': u'first'}] - ) - - # Extra columns can be partially returned - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')), - [{'second': u'second', 'foo': u'first', 'first': u'first'}] - ) - - # Also works if only extra columns are included - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')), - [{'foo': u'first', 'whiz': u'third'}] - ) - - # Values list works the same way - # All columns are returned for an empty values_list() - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()), - [(u'first', u'second', u'third', obj.pk, u'first', u'second', u'third')] - ) - - # Extra columns after an empty values_list() are still included - self.assertEqual( - list(TestObject.objects.values_list().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), - [(u'first', u'second', u'third', obj.pk, u'first', u'second', u'third')] - ) - - # Extra columns ignored completely if not mentioned in values_list() - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')), - [(u'first', u'second')] - ) - - # Extra columns after a non-empty values_list() clause are ignored completely - self.assertEqual( - list(TestObject.objects.values_list('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), - [(u'first', u'second')] - ) - - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)), - [u'second'] - ) - - # Only the extra columns specified in the values_list() are returned - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')), - [(u'first', u'second', u'third')] - ) - - # ...also works if only extra columns are included - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')), - [(u'first', u'third')] - ) - - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)), - [u'third'] - ) - - # ... and values are returned in the order they are specified - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')), - [(u'third', u'first')] - ) - - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')), - [(u'first', obj.pk)] - ) - - self.assertEqual( - list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')), - [(u'third', u'first', u'second', obj.pk)] - ) - - def test_regression_10847(self): - """ - Regression for #10847: the list of extra columns can always be - accurately evaluated. Using an inner query ensures that as_sql() is - producing correct output without requiring full evaluation and - execution of the inner query. - """ - obj = TestObject(first='first', second='second', third='third') - obj.save() - - self.assertEqual( - list(TestObject.objects.extra(select={'extra': 1}).values('pk')), - [{'pk': obj.pk}] - ) - - self.assertQuerysetEqual( - TestObject.objects.filter( - pk__in=TestObject.objects.extra(select={'extra': 1}).values('pk') - ), - ['<TestObject: TestObject: first,second,third>'] - ) - - self.assertEqual( - list(TestObject.objects.values('pk').extra(select={'extra': 1})), - [{'pk': obj.pk}] - ) - - self.assertQuerysetEqual( - TestObject.objects.filter( - pk__in=TestObject.objects.values('pk').extra(select={'extra': 1}) - ), - ['<TestObject: TestObject: first,second,third>'] - ) - - self.assertQuerysetEqual( - TestObject.objects.filter(pk=obj.pk) | - TestObject.objects.extra(where=["id > %s"], params=[obj.pk]), - ['<TestObject: TestObject: first,second,third>'] - ) diff --git a/parts/django/tests/regressiontests/file_storage/__init__.py b/parts/django/tests/regressiontests/file_storage/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/file_storage/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/file_storage/models.py b/parts/django/tests/regressiontests/file_storage/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/file_storage/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/file_storage/test.png b/parts/django/tests/regressiontests/file_storage/test.png Binary files differdeleted file mode 100644 index 4f17cd0..0000000 --- a/parts/django/tests/regressiontests/file_storage/test.png +++ /dev/null diff --git a/parts/django/tests/regressiontests/file_storage/test1.png b/parts/django/tests/regressiontests/file_storage/test1.png Binary files differdeleted file mode 100644 index bc98741..0000000 --- a/parts/django/tests/regressiontests/file_storage/test1.png +++ /dev/null diff --git a/parts/django/tests/regressiontests/file_storage/tests.py b/parts/django/tests/regressiontests/file_storage/tests.py deleted file mode 100644 index 8726181..0000000 --- a/parts/django/tests/regressiontests/file_storage/tests.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import shutil -import sys -import tempfile -import time -import unittest -from cStringIO import StringIO -from django.conf import settings -from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured -from django.core.files.base import ContentFile, File -from django.core.files.images import get_image_dimensions -from django.core.files.storage import FileSystemStorage, get_storage_class -from django.core.files.uploadedfile import UploadedFile -from unittest import TestCase - -try: - import threading -except ImportError: - import dummy_threading as threading - -# Try to import PIL in either of the two ways it can end up installed. -# Checking for the existence of Image is enough for CPython, but -# for PyPy, you need to check for the underlying modules -try: - from PIL import Image, _imaging -except ImportError: - try: - import Image, _imaging - except ImportError: - Image = None - -class GetStorageClassTests(unittest.TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, - *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_get_filesystem_storage(self): - """ - get_storage_class returns the class for a storage backend name/path. - """ - self.assertEqual( - get_storage_class('django.core.files.storage.FileSystemStorage'), - FileSystemStorage) - - def test_get_invalid_storage_module(self): - """ - get_storage_class raises an error if the requested import don't exist. - """ - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "NonExistingStorage isn't a storage module.", - get_storage_class, - 'NonExistingStorage') - - def test_get_nonexisting_storage_class(self): - """ - get_storage_class raises an error if the requested class don't exist. - """ - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - 'Storage module "django.core.files.storage" does not define a '\ - '"NonExistingStorage" class.', - get_storage_class, - 'django.core.files.storage.NonExistingStorage') - - def test_get_nonexisting_storage_module(self): - """ - get_storage_class raises an error if the requested module don't exist. - """ - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - 'Error importing storage module django.core.files.non_existing_'\ - 'storage: "No module named non_existing_storage"', - get_storage_class, - 'django.core.files.non_existing_storage.NonExistingStorage') - -class FileStorageTests(unittest.TestCase): - storage_class = FileSystemStorage - - def setUp(self): - self.temp_dir = tempfile.mktemp() - os.makedirs(self.temp_dir) - self.storage = self.storage_class(location=self.temp_dir, - base_url='/test_media_url/') - - def tearDown(self): - shutil.rmtree(self.temp_dir) - - def test_file_access_options(self): - """ - Standard file access options are available, and work as expected. - """ - self.assertFalse(self.storage.exists('storage_test')) - f = self.storage.open('storage_test', 'w') - f.write('storage contents') - f.close() - self.assert_(self.storage.exists('storage_test')) - - f = self.storage.open('storage_test', 'r') - self.assertEqual(f.read(), 'storage contents') - f.close() - - self.storage.delete('storage_test') - self.assertFalse(self.storage.exists('storage_test')) - - def test_file_save_without_name(self): - """ - File storage extracts the filename from the content object if no - name is given explicitly. - """ - self.assertFalse(self.storage.exists('test.file')) - - f = ContentFile('custom contents') - f.name = 'test.file' - - storage_f_name = self.storage.save(None, f) - - self.assertEqual(storage_f_name, f.name) - - self.assert_(os.path.exists(os.path.join(self.temp_dir, f.name))) - - self.storage.delete(storage_f_name) - - def test_file_path(self): - """ - File storage returns the full path of a file - """ - self.assertFalse(self.storage.exists('test.file')) - - f = ContentFile('custom contents') - f_name = self.storage.save('test.file', f) - - self.assertEqual(self.storage.path(f_name), - os.path.join(self.temp_dir, f_name)) - - self.storage.delete(f_name) - - def test_file_url(self): - """ - File storage returns a url to access a given file from the Web. - """ - self.assertEqual(self.storage.url('test.file'), - '%s%s' % (self.storage.base_url, 'test.file')) - - self.storage.base_url = None - self.assertRaises(ValueError, self.storage.url, 'test.file') - - def test_file_with_mixin(self): - """ - File storage can get a mixin to extend the functionality of the - returned file. - """ - self.assertFalse(self.storage.exists('test.file')) - - class TestFileMixin(object): - mixed_in = True - - f = ContentFile('custom contents') - f_name = self.storage.save('test.file', f) - - self.assert_(isinstance( - self.storage.open('test.file', mixin=TestFileMixin), - TestFileMixin - )) - - self.storage.delete('test.file') - - def test_listdir(self): - """ - File storage returns a tuple containing directories and files. - """ - self.assertFalse(self.storage.exists('storage_test_1')) - self.assertFalse(self.storage.exists('storage_test_2')) - self.assertFalse(self.storage.exists('storage_dir_1')) - - f = self.storage.save('storage_test_1', ContentFile('custom content')) - f = self.storage.save('storage_test_2', ContentFile('custom content')) - os.mkdir(os.path.join(self.temp_dir, 'storage_dir_1')) - - dirs, files = self.storage.listdir('') - self.assertEqual(set(dirs), set([u'storage_dir_1'])) - self.assertEqual(set(files), - set([u'storage_test_1', u'storage_test_2'])) - - self.storage.delete('storage_test_1') - self.storage.delete('storage_test_2') - os.rmdir(os.path.join(self.temp_dir, 'storage_dir_1')) - - def test_file_storage_prevents_directory_traversal(self): - """ - File storage prevents directory traversal (files can only be accessed if - they're below the storage location). - """ - self.assertRaises(SuspiciousOperation, self.storage.exists, '..') - self.assertRaises(SuspiciousOperation, self.storage.exists, '/etc/passwd') - -class CustomStorage(FileSystemStorage): - def get_available_name(self, name): - """ - Append numbers to duplicate files rather than underscores, like Trac. - """ - parts = name.split('.') - basename, ext = parts[0], parts[1:] - number = 2 - while self.exists(name): - name = '.'.join([basename, str(number)] + ext) - number += 1 - - return name - -class CustomStorageTests(FileStorageTests): - storage_class = CustomStorage - - def test_custom_get_available_name(self): - first = self.storage.save('custom_storage', ContentFile('custom contents')) - self.assertEqual(first, 'custom_storage') - second = self.storage.save('custom_storage', ContentFile('more contents')) - self.assertEqual(second, 'custom_storage.2') - self.storage.delete(first) - self.storage.delete(second) - -class UnicodeFileNameTests(unittest.TestCase): - def test_unicode_file_names(self): - """ - Regression test for #8156: files with unicode names I can't quite figure - out the encoding situation between doctest and this file, but the actual - repr doesn't matter; it just shouldn't return a unicode object. - """ - uf = UploadedFile(name=u'¿Cómo?',content_type='text') - self.assertEqual(type(uf.__repr__()), str) - -# Tests for a race condition on file saving (#4948). -# This is written in such a way that it'll always pass on platforms -# without threading. - -class SlowFile(ContentFile): - def chunks(self): - time.sleep(1) - return super(ContentFile, self).chunks() - -class FileSaveRaceConditionTest(TestCase): - def setUp(self): - self.storage_dir = tempfile.mkdtemp() - self.storage = FileSystemStorage(self.storage_dir) - self.thread = threading.Thread(target=self.save_file, args=['conflict']) - - def tearDown(self): - shutil.rmtree(self.storage_dir) - - def save_file(self, name): - name = self.storage.save(name, SlowFile("Data")) - - def test_race_condition(self): - self.thread.start() - name = self.save_file('conflict') - self.thread.join() - self.assert_(self.storage.exists('conflict')) - self.assert_(self.storage.exists('conflict_1')) - self.storage.delete('conflict') - self.storage.delete('conflict_1') - -class FileStoragePermissions(TestCase): - def setUp(self): - self.old_perms = settings.FILE_UPLOAD_PERMISSIONS - settings.FILE_UPLOAD_PERMISSIONS = 0666 - self.storage_dir = tempfile.mkdtemp() - self.storage = FileSystemStorage(self.storage_dir) - - def tearDown(self): - settings.FILE_UPLOAD_PERMISSIONS = self.old_perms - shutil.rmtree(self.storage_dir) - - def test_file_upload_permissions(self): - name = self.storage.save("the_file", ContentFile("data")) - actual_mode = os.stat(self.storage.path(name))[0] & 0777 - self.assertEqual(actual_mode, 0666) - - -class FileStoragePathParsing(TestCase): - def setUp(self): - self.storage_dir = tempfile.mkdtemp() - self.storage = FileSystemStorage(self.storage_dir) - - def tearDown(self): - shutil.rmtree(self.storage_dir) - - def test_directory_with_dot(self): - """Regression test for #9610. - - If the directory name contains a dot and the file name doesn't, make - sure we still mangle the file name instead of the directory name. - """ - - self.storage.save('dotted.path/test', ContentFile("1")) - self.storage.save('dotted.path/test', ContentFile("2")) - - self.assertFalse(os.path.exists(os.path.join(self.storage_dir, 'dotted_.path'))) - self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/test'))) - self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/test_1'))) - - def test_first_character_dot(self): - """ - File names with a dot as their first character don't have an extension, - and the underscore should get added to the end. - """ - self.storage.save('dotted.path/.test', ContentFile("1")) - self.storage.save('dotted.path/.test', ContentFile("2")) - - self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/.test'))) - # Before 2.6, a leading dot was treated as an extension, and so - # underscore gets added to beginning instead of end. - if sys.version_info < (2, 6): - self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/_1.test'))) - else: - self.assert_(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/.test_1'))) - -if Image is not None: - class DimensionClosingBug(TestCase): - """ - Test that get_image_dimensions() properly closes files (#8817) - """ - def test_not_closing_of_files(self): - """ - Open files passed into get_image_dimensions() should stay opened. - """ - empty_io = StringIO() - try: - get_image_dimensions(empty_io) - finally: - self.assert_(not empty_io.closed) - - def test_closing_of_filenames(self): - """ - get_image_dimensions() called with a filename should closed the file. - """ - # We need to inject a modified open() builtin into the images module - # that checks if the file was closed properly if the function is - # called with a filename instead of an file object. - # get_image_dimensions will call our catching_open instead of the - # regular builtin one. - - class FileWrapper(object): - _closed = [] - def __init__(self, f): - self.f = f - def __getattr__(self, name): - return getattr(self.f, name) - def close(self): - self._closed.append(True) - self.f.close() - - def catching_open(*args): - return FileWrapper(open(*args)) - - from django.core.files import images - images.open = catching_open - try: - get_image_dimensions(os.path.join(os.path.dirname(__file__), "test1.png")) - finally: - del images.open - self.assert_(FileWrapper._closed) - - class InconsistentGetImageDimensionsBug(TestCase): - """ - Test that get_image_dimensions() works properly after various calls using a file handler (#11158) - """ - def test_multiple_calls(self): - """ - Multiple calls of get_image_dimensions() should return the same size. - """ - from django.core.files.images import ImageFile - img_path = os.path.join(os.path.dirname(__file__), "test.png") - image = ImageFile(open(img_path, 'rb')) - image_pil = Image.open(img_path) - size_1, size_2 = get_image_dimensions(image), get_image_dimensions(image) - self.assertEqual(image_pil.size, size_1) - self.assertEqual(size_1, size_2) diff --git a/parts/django/tests/regressiontests/file_uploads/__init__.py b/parts/django/tests/regressiontests/file_uploads/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/file_uploads/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/file_uploads/models.py b/parts/django/tests/regressiontests/file_uploads/models.py deleted file mode 100644 index 9d02050..0000000 --- a/parts/django/tests/regressiontests/file_uploads/models.py +++ /dev/null @@ -1,10 +0,0 @@ -import tempfile -import os -from django.db import models -from django.core.files.storage import FileSystemStorage - -temp_storage = FileSystemStorage(tempfile.mkdtemp()) -UPLOAD_TO = os.path.join(temp_storage.location, 'test_upload') - -class FileModel(models.Model): - testfile = models.FileField(storage=temp_storage, upload_to='test_upload') diff --git a/parts/django/tests/regressiontests/file_uploads/tests.py b/parts/django/tests/regressiontests/file_uploads/tests.py deleted file mode 100644 index 99d0b6b..0000000 --- a/parts/django/tests/regressiontests/file_uploads/tests.py +++ /dev/null @@ -1,305 +0,0 @@ -#! -*- coding: utf-8 -*- -import errno -import os -import shutil -import unittest -from StringIO import StringIO - -from django.core.files import temp as tempfile -from django.core.files.uploadedfile import SimpleUploadedFile -from django.test import TestCase, client -from django.utils import simplejson -from django.utils.hashcompat import sha_constructor -from django.http.multipartparser import MultiPartParser - -from models import FileModel, temp_storage, UPLOAD_TO -import uploadhandler - - -UNICODE_FILENAME = u'test-0123456789_中文_Orléans.jpg' - -class FileUploadTests(TestCase): - def test_simple_upload(self): - post_data = { - 'name': 'Ringo', - 'file_field': open(__file__), - } - response = self.client.post('/file_uploads/upload/', post_data) - self.assertEqual(response.status_code, 200) - - def test_large_upload(self): - tdir = tempfile.gettempdir() - - file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir) - file1.write('a' * (2 ** 21)) - file1.seek(0) - - file2 = tempfile.NamedTemporaryFile(suffix=".file2", dir=tdir) - file2.write('a' * (10 * 2 ** 20)) - file2.seek(0) - - post_data = { - 'name': 'Ringo', - 'file_field1': file1, - 'file_field2': file2, - } - - for key in post_data.keys(): - try: - post_data[key + '_hash'] = sha_constructor(post_data[key].read()).hexdigest() - post_data[key].seek(0) - except AttributeError: - post_data[key + '_hash'] = sha_constructor(post_data[key]).hexdigest() - - response = self.client.post('/file_uploads/verify/', post_data) - - self.assertEqual(response.status_code, 200) - - def test_unicode_file_name(self): - tdir = tempfile.gettempdir() - - # This file contains chinese symbols and an accented char in the name. - file1 = open(os.path.join(tdir, UNICODE_FILENAME.encode('utf-8')), 'w+b') - file1.write('b' * (2 ** 10)) - file1.seek(0) - - post_data = { - 'file_unicode': file1, - } - - response = self.client.post('/file_uploads/unicode_name/', post_data) - - file1.close() - try: - os.unlink(file1.name) - except: - pass - - self.assertEqual(response.status_code, 200) - - def test_dangerous_file_names(self): - """Uploaded file names should be sanitized before ever reaching the view.""" - # This test simulates possible directory traversal attacks by a - # malicious uploader We have to do some monkeybusiness here to construct - # a malicious payload with an invalid file name (containing os.sep or - # os.pardir). This similar to what an attacker would need to do when - # trying such an attack. - scary_file_names = [ - "/tmp/hax0rd.txt", # Absolute path, *nix-style. - "C:\\Windows\\hax0rd.txt", # Absolute path, win-syle. - "C:/Windows/hax0rd.txt", # Absolute path, broken-style. - "\\tmp\\hax0rd.txt", # Absolute path, broken in a different way. - "/tmp\\hax0rd.txt", # Absolute path, broken by mixing. - "subdir/hax0rd.txt", # Descendant path, *nix-style. - "subdir\\hax0rd.txt", # Descendant path, win-style. - "sub/dir\\hax0rd.txt", # Descendant path, mixed. - "../../hax0rd.txt", # Relative path, *nix-style. - "..\\..\\hax0rd.txt", # Relative path, win-style. - "../..\\hax0rd.txt" # Relative path, mixed. - ] - - payload = [] - for i, name in enumerate(scary_file_names): - payload.extend([ - '--' + client.BOUNDARY, - 'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, name), - 'Content-Type: application/octet-stream', - '', - 'You got pwnd.' - ]) - payload.extend([ - '--' + client.BOUNDARY + '--', - '', - ]) - - payload = "\r\n".join(payload) - r = { - 'CONTENT_LENGTH': len(payload), - 'CONTENT_TYPE': client.MULTIPART_CONTENT, - 'PATH_INFO': "/file_uploads/echo/", - 'REQUEST_METHOD': 'POST', - 'wsgi.input': client.FakePayload(payload), - } - response = self.client.request(**r) - - # The filenames should have been sanitized by the time it got to the view. - recieved = simplejson.loads(response.content) - for i, name in enumerate(scary_file_names): - got = recieved["file%s" % i] - self.assertEqual(got, "hax0rd.txt") - - def test_filename_overflow(self): - """File names over 256 characters (dangerous on some platforms) get fixed up.""" - name = "%s.txt" % ("f"*500) - payload = "\r\n".join([ - '--' + client.BOUNDARY, - 'Content-Disposition: form-data; name="file"; filename="%s"' % name, - 'Content-Type: application/octet-stream', - '', - 'Oops.' - '--' + client.BOUNDARY + '--', - '', - ]) - r = { - 'CONTENT_LENGTH': len(payload), - 'CONTENT_TYPE': client.MULTIPART_CONTENT, - 'PATH_INFO': "/file_uploads/echo/", - 'REQUEST_METHOD': 'POST', - 'wsgi.input': client.FakePayload(payload), - } - got = simplejson.loads(self.client.request(**r).content) - self.assert_(len(got['file']) < 256, "Got a long file name (%s characters)." % len(got['file'])) - - def test_custom_upload_handler(self): - # A small file (under the 5M quota) - smallfile = tempfile.NamedTemporaryFile() - smallfile.write('a' * (2 ** 21)) - smallfile.seek(0) - - # A big file (over the quota) - bigfile = tempfile.NamedTemporaryFile() - bigfile.write('a' * (10 * 2 ** 20)) - bigfile.seek(0) - - # Small file posting should work. - response = self.client.post('/file_uploads/quota/', {'f': smallfile}) - got = simplejson.loads(response.content) - self.assert_('f' in got) - - # Large files don't go through. - response = self.client.post("/file_uploads/quota/", {'f': bigfile}) - got = simplejson.loads(response.content) - self.assert_('f' not in got) - - def test_broken_custom_upload_handler(self): - f = tempfile.NamedTemporaryFile() - f.write('a' * (2 ** 21)) - f.seek(0) - - # AttributeError: You cannot alter upload handlers after the upload has been processed. - self.assertRaises( - AttributeError, - self.client.post, - '/file_uploads/quota/broken/', - {'f': f} - ) - - def test_fileupload_getlist(self): - file1 = tempfile.NamedTemporaryFile() - file1.write('a' * (2 ** 23)) - file1.seek(0) - - file2 = tempfile.NamedTemporaryFile() - file2.write('a' * (2 * 2 ** 18)) - file2.seek(0) - - file2a = tempfile.NamedTemporaryFile() - file2a.write('a' * (5 * 2 ** 20)) - file2a.seek(0) - - response = self.client.post('/file_uploads/getlist_count/', { - 'file1': file1, - 'field1': u'test', - 'field2': u'test3', - 'field3': u'test5', - 'field4': u'test6', - 'field5': u'test7', - 'file2': (file2, file2a) - }) - got = simplejson.loads(response.content) - - self.assertEqual(got.get('file1'), 1) - self.assertEqual(got.get('file2'), 2) - - def test_file_error_blocking(self): - """ - The server should not block when there are upload errors (bug #8622). - This can happen if something -- i.e. an exception handler -- tries to - access POST while handling an error in parsing POST. This shouldn't - cause an infinite loop! - """ - class POSTAccessingHandler(client.ClientHandler): - """A handler that'll access POST during an exception.""" - def handle_uncaught_exception(self, request, resolver, exc_info): - ret = super(POSTAccessingHandler, self).handle_uncaught_exception(request, resolver, exc_info) - p = request.POST - return ret - - post_data = { - 'name': 'Ringo', - 'file_field': open(__file__), - } - # Maybe this is a little more complicated that it needs to be; but if - # the django.test.client.FakePayload.read() implementation changes then - # this test would fail. So we need to know exactly what kind of error - # it raises when there is an attempt to read more than the available bytes: - try: - client.FakePayload('a').read(2) - except Exception, reference_error: - pass - - # install the custom handler that tries to access request.POST - self.client.handler = POSTAccessingHandler() - - try: - response = self.client.post('/file_uploads/upload_errors/', post_data) - except reference_error.__class__, err: - self.failIf( - str(err) == str(reference_error), - "Caught a repeated exception that'll cause an infinite loop in file uploads." - ) - except Exception, err: - # CustomUploadError is the error that should have been raised - self.assertEqual(err.__class__, uploadhandler.CustomUploadError) - -class DirectoryCreationTests(unittest.TestCase): - """ - Tests for error handling during directory creation - via _save_FIELD_file (ticket #6450) - """ - def setUp(self): - self.obj = FileModel() - if not os.path.isdir(temp_storage.location): - os.makedirs(temp_storage.location) - if os.path.isdir(UPLOAD_TO): - os.chmod(UPLOAD_TO, 0700) - shutil.rmtree(UPLOAD_TO) - - def tearDown(self): - os.chmod(temp_storage.location, 0700) - shutil.rmtree(temp_storage.location) - - def test_readonly_root(self): - """Permission errors are not swallowed""" - os.chmod(temp_storage.location, 0500) - try: - self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', 'x')) - except OSError, err: - self.assertEquals(err.errno, errno.EACCES) - except Exception, err: - self.fail("OSError [Errno %s] not raised." % errno.EACCES) - - def test_not_a_directory(self): - """The correct IOError is raised when the upload directory name exists but isn't a directory""" - # Create a file with the upload directory name - fd = open(UPLOAD_TO, 'w') - fd.close() - try: - self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', 'x')) - except IOError, err: - # The test needs to be done on a specific string as IOError - # is raised even without the patch (just not early enough) - self.assertEquals(err.args[0], - "%s exists and is not a directory." % UPLOAD_TO) - except: - self.fail("IOError not raised") - -class MultiParserTests(unittest.TestCase): - - def test_empty_upload_handlers(self): - # We're not actually parsing here; just checking if the parser properly - # instantiates with empty upload handlers. - parser = MultiPartParser({ - 'CONTENT_TYPE': 'multipart/form-data; boundary=_foo', - 'CONTENT_LENGTH': '1' - }, StringIO('x'), [], 'utf-8') diff --git a/parts/django/tests/regressiontests/file_uploads/uploadhandler.py b/parts/django/tests/regressiontests/file_uploads/uploadhandler.py deleted file mode 100644 index 9f3960a..0000000 --- a/parts/django/tests/regressiontests/file_uploads/uploadhandler.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -Upload handlers to test the upload API. -""" - -from django.core.files.uploadhandler import FileUploadHandler, StopUpload - -class QuotaUploadHandler(FileUploadHandler): - """ - This test upload handler terminates the connection if more than a quota - (5MB) is uploaded. - """ - - QUOTA = 5 * 2**20 # 5 MB - - def __init__(self, request=None): - super(QuotaUploadHandler, self).__init__(request) - self.total_upload = 0 - - def receive_data_chunk(self, raw_data, start): - self.total_upload += len(raw_data) - if self.total_upload >= self.QUOTA: - raise StopUpload(connection_reset=True) - return raw_data - - def file_complete(self, file_size): - return None - -class CustomUploadError(Exception): - pass - -class ErroringUploadHandler(FileUploadHandler): - """A handler that raises an exception.""" - def receive_data_chunk(self, raw_data, start): - raise CustomUploadError("Oops!") diff --git a/parts/django/tests/regressiontests/file_uploads/urls.py b/parts/django/tests/regressiontests/file_uploads/urls.py deleted file mode 100644 index 413080e..0000000 --- a/parts/django/tests/regressiontests/file_uploads/urls.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.conf.urls.defaults import * -import views - -urlpatterns = patterns('', - (r'^upload/$', views.file_upload_view), - (r'^verify/$', views.file_upload_view_verify), - (r'^unicode_name/$', views.file_upload_unicode_name), - (r'^echo/$', views.file_upload_echo), - (r'^quota/$', views.file_upload_quota), - (r'^quota/broken/$', views.file_upload_quota_broken), - (r'^getlist_count/$', views.file_upload_getlist_count), - (r'^upload_errors/$', views.file_upload_errors), -) diff --git a/parts/django/tests/regressiontests/file_uploads/views.py b/parts/django/tests/regressiontests/file_uploads/views.py deleted file mode 100644 index 50bc3f8..0000000 --- a/parts/django/tests/regressiontests/file_uploads/views.py +++ /dev/null @@ -1,114 +0,0 @@ -import os -from django.core.files.uploadedfile import UploadedFile -from django.http import HttpResponse, HttpResponseServerError -from django.utils import simplejson -from models import FileModel, UPLOAD_TO -from uploadhandler import QuotaUploadHandler, ErroringUploadHandler -from django.utils.hashcompat import sha_constructor -from tests import UNICODE_FILENAME - -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.get('file_field'), UploadedFile) and isinstance(form_data['name'], unicode): - # If a file is posted, the dummy client should only post the file name, - # not the full path. - if os.path.dirname(form_data['file_field'].name) != '': - return HttpResponseServerError() - return HttpResponse('') - else: - return HttpResponseServerError() - -def file_upload_view_verify(request): - """ - Use the sha digest hash to verify the uploaded contents. - """ - form_data = request.POST.copy() - form_data.update(request.FILES) - - for key, value in form_data.items(): - if key.endswith('_hash'): - continue - if key + '_hash' not in form_data: - continue - submitted_hash = form_data[key + '_hash'] - if isinstance(value, UploadedFile): - new_hash = sha_constructor(value.read()).hexdigest() - else: - new_hash = sha_constructor(value).hexdigest() - if new_hash != submitted_hash: - return HttpResponseServerError() - - # Adding large file to the database should succeed - largefile = request.FILES['file_field2'] - obj = FileModel() - obj.testfile.save(largefile.name, largefile) - - return HttpResponse('') - -def file_upload_unicode_name(request): - - # Check to see if unicode name came through properly. - if not request.FILES['file_unicode'].name.endswith(UNICODE_FILENAME): - return HttpResponseServerError() - - response = None - - # Check to make sure the exotic characters are preserved even - # through file save. - uni_named_file = request.FILES['file_unicode'] - obj = FileModel.objects.create(testfile=uni_named_file) - full_name = u'%s/%s' % (UPLOAD_TO, uni_named_file.name) - if not os.path.exists(full_name): - response = HttpResponseServerError() - - # Cleanup the object with its exotic file name immediately. - # (shutil.rmtree used elsewhere in the tests to clean up the - # upload directory has been seen to choke on unicode - # filenames on Windows.) - obj.delete() - - if response: - return response - else: - return HttpResponse('') - -def file_upload_echo(request): - """ - Simple view to echo back info about uploaded files for tests. - """ - r = dict([(k, f.name) for k, f in request.FILES.items()]) - return HttpResponse(simplejson.dumps(r)) - -def file_upload_quota(request): - """ - Dynamically add in an upload handler. - """ - request.upload_handlers.insert(0, QuotaUploadHandler()) - return file_upload_echo(request) - -def file_upload_quota_broken(request): - """ - You can't change handlers after reading FILES; this view shouldn't work. - """ - response = file_upload_echo(request) - request.upload_handlers.insert(0, QuotaUploadHandler()) - return response - -def file_upload_getlist_count(request): - """ - Check the .getlist() function to ensure we receive the correct number of files. - """ - file_counts = {} - - for key in request.FILES.keys(): - file_counts[key] = len(request.FILES.getlist(key)) - return HttpResponse(simplejson.dumps(file_counts)) - -def file_upload_errors(request): - request.upload_handlers.insert(0, ErroringUploadHandler()) - return file_upload_echo(request) diff --git a/parts/django/tests/regressiontests/fixtures_regress/__init__.py b/parts/django/tests/regressiontests/fixtures_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/absolute.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/absolute.json deleted file mode 100644 index 37ed3f6..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/absolute.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures_regress.absolute", - "fields": { - "name": "Load Absolute Path Test" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/animal.xml b/parts/django/tests/regressiontests/fixtures_regress/fixtures/animal.xml deleted file mode 100644 index 0383c60..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/animal.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="10" model="fixtures_regress.animal"> - <field type="CharField" name="name">Emu</field> - <field type="CharField" name="latin_name">Dromaius novaehollandiae</field> - <field type="IntegerField" name="count">42</field> - <field type="FloatField" name="weight">1.2</field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn b/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn deleted file mode 100644 index a8b0a0c..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn +++ /dev/null @@ -1 +0,0 @@ -This data shouldn't load, as it's of an unknown file format.
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml b/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml deleted file mode 100644 index 87b809f..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objcts version="1.0"> - <objct pk="2" model="fixtures.article"> - <field type="CharField" name="headline">Poker on TV is great!</field> - <field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field> - </objct> -</django-objcts>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json deleted file mode 100644 index e655fbb..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json +++ /dev/null @@ -1,83 +0,0 @@ -[ - { - "pk": 6, - "model": "fixtures_regress.channel", - "fields": { - "name": "Business" - } - }, - - { - "pk": 1, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 1", - "channels": [6] - } - }, - { - "pk": 2, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 2", - "channels": [6] - } - }, - { - "pk": 3, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 3", - "channels": [6] - } - }, - { - "pk": 4, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 4", - "channels": [6] - } - }, - - { - "pk": 5, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 5", - "channels": [6] - } - }, - { - "pk": 6, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 6", - "channels": [6] - } - }, - { - "pk": 7, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 7", - "channels": [6] - } - }, - { - "pk": 8, - "model": "fixtures_regress.article", - "fields": { - "title": "Article Title 8", - "channels": [6] - } - }, - { - "pk": 9, - "model": "fixtures_regress.article", - "fields": { - "title": "Yet Another Article", - "channels": [6] - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/empty.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/empty.json deleted file mode 100644 index 0637a08..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/empty.json +++ /dev/null @@ -1 +0,0 @@ -[]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/forward_ref_lookup.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/forward_ref_lookup.json deleted file mode 100644 index fe50c65..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/forward_ref_lookup.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "pk": "4", - "model": "fixtures_regress.person", - "fields": { - "name": "Neal Stephenson" - } - }, - { - "pk": "2", - "model": "fixtures_regress.store", - "fields": { - "name": "Amazon" - } - }, - { - "pk": "3", - "model": "fixtures_regress.store", - "fields": { - "name": "Borders" - } - }, - { - "pk": 1, - "model": "fixtures_regress.book", - "fields": { - "name": "Cryptonomicon", - "author": ["Neal Stephenson"], - "stores": [["Amazon"], ["Borders"]] - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/model-inheritance.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/model-inheritance.json deleted file mode 100644 index 00c482b..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/model-inheritance.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - {"pk": 1, "model": "fixtures_regress.parent", "fields": {"name": "fred"}}, - {"pk": 1, "model": "fixtures_regress.child", "fields": {"data": "apple"}} -] diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance.json deleted file mode 100644 index 08e5d4f..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "pk": 1, - "model": "fixtures_regress.nkchild", - "fields": { - "data": "apple" - } - }, - { - "pk": 1, - "model": "fixtures_regress.reftonkchild", - "fields": { - "text": "my text", - "nk_fk" : ["apple"], - "nk_m2m": [["apple"]] - } - } -] diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance2.xml b/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance2.xml deleted file mode 100644 index 7eb17a6..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/nk-inheritance2.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="2" model="fixtures_regress.parent"> - <field type="CharField" name="name">james</field> - </object> - <object pk="2" model="fixtures_regress.nkchild"> - <field type="CharField" name="data">banana</field> - </object> - <object pk="2" model="fixtures_regress.reftonkchild"> - <field type="CharField" name="text">other text</field> - <field to="fixtures_regress.nkchild" name="nk_fk" rel="ManyToOneRel"> - <natural>apple</natural> - </field> - <field to="fixtures_regress.nkchild" name="nk_m2m" rel="ManyToManyRel"> - <object> - <natural>banana</natural> - </object> - <object> - <natural>apple</natural> - </object> - </field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_1.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_1.json deleted file mode 100644 index 4bce792..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_1.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "pk": 12, - "model": "fixtures_regress.person", - "fields": { - "name": "Greg Egan" - } - }, - { - "pk": 11, - "model": "fixtures_regress.store", - "fields": { - "name": "Angus and Robertson" - } - }, - { - "pk": 10, - "model": "fixtures_regress.book", - "fields": { - "name": "Permutation City", - "author": 12, - "stores": [11] - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_2.xml b/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_2.xml deleted file mode 100644 index 280ad37..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/non_natural_2.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="22" model="fixtures_regress.person"> - <field type="CharField" name="name">Orson Scott Card</field> - </object> - <object pk="21" model="fixtures_regress.store"> - <field type="CharField" name="name">Collins Bookstore</field> - </object> - <object pk="20" model="fixtures_regress.book"> - <field type="CharField" name="name">Ender's Game</field> - <field to="fixtures_regress.person" name="author" rel="ManyToOneRel">22</field> - <field to="fixtures_regress.store" name="stores" rel="ManyToManyRel"> - <object pk="21"/> - </field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/pretty.xml b/parts/django/tests/regressiontests/fixtures_regress/fixtures/pretty.xml deleted file mode 100644 index 68e5710..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/pretty.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="1" model="fixtures_regress.stuff"> - <field type="CharField" name="name"> - <None/> - </field> - <field to="auth.user" name="owner" rel="ManyToOneRel"> - <None/> - </field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/sequence.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/sequence.json deleted file mode 100644 index 60bfcdd..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/sequence.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures_regress.animal", - "fields": { - "name": "Lion", - "latin_name": "Panthera leo", - "count": 3, - "weight": 1.2 - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/fixtures_regress/fixtures/thingy.json b/parts/django/tests/regressiontests/fixtures_regress/fixtures/thingy.json deleted file mode 100644 index 1693177..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/fixtures/thingy.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "pk": "1", - "model": "fixtures_regress.thingy", - "fields": { - "name": "Whatchamacallit" - } - } -] diff --git a/parts/django/tests/regressiontests/fixtures_regress/models.py b/parts/django/tests/regressiontests/fixtures_regress/models.py deleted file mode 100644 index 7465fd2..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/models.py +++ /dev/null @@ -1,225 +0,0 @@ -from django.db import models, DEFAULT_DB_ALIAS -from django.contrib.auth.models import User -from django.conf import settings - - -class Animal(models.Model): - name = models.CharField(max_length=150) - latin_name = models.CharField(max_length=150) - count = models.IntegerField() - weight = models.FloatField() - - # use a non-default name for the default manager - specimens = models.Manager() - - def __unicode__(self): - return self.name - - -class Plant(models.Model): - name = models.CharField(max_length=150) - - class Meta: - # For testing when upper case letter in app name; regression for #4057 - db_table = "Fixtures_regress_plant" - -class Stuff(models.Model): - name = models.CharField(max_length=20, null=True) - owner = models.ForeignKey(User, null=True) - - def __unicode__(self): - return unicode(self.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 - - -class Parent(models.Model): - name = models.CharField(max_length=10) - - class Meta: - ordering = ('id',) - - -class Child(Parent): - data = models.CharField(max_length=10) - - -# Models to regression test #7572 -class Channel(models.Model): - name = models.CharField(max_length=255) - - -class Article(models.Model): - title = models.CharField(max_length=255) - channels = models.ManyToManyField(Channel) - - class Meta: - ordering = ('id',) - - -# Models to regression test #11428 -class Widget(models.Model): - name = models.CharField(max_length=255) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - -class WidgetProxy(Widget): - class Meta: - proxy = True - - -# Check for forward references in FKs and M2Ms with natural keys -class TestManager(models.Manager): - def get_by_natural_key(self, key): - return self.get(name=key) - - -class Store(models.Model): - objects = TestManager() - name = models.CharField(max_length=255) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - def natural_key(self): - return (self.name,) - - -class Person(models.Model): - objects = TestManager() - name = models.CharField(max_length=255) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - - # Person doesn't actually have a dependency on store, but we need to define - # one to test the behaviour of the dependency resolution algorithm. - def natural_key(self): - return (self.name,) - natural_key.dependencies = ['fixtures_regress.store'] - - -class Book(models.Model): - name = models.CharField(max_length=255) - author = models.ForeignKey(Person) - stores = models.ManyToManyField(Store) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return u'%s by %s (available at %s)' % ( - self.name, - self.author.name, - ', '.join(s.name for s in self.stores.all()) - ) - - -class NKManager(models.Manager): - def get_by_natural_key(self, data): - return self.get(data=data) - - -class NKChild(Parent): - data = models.CharField(max_length=10, unique=True) - objects = NKManager() - - def natural_key(self): - return self.data - - def __unicode__(self): - return u'NKChild %s:%s' % (self.name, self.data) - - -class RefToNKChild(models.Model): - text = models.CharField(max_length=10) - nk_fk = models.ForeignKey(NKChild, related_name='ref_fks') - nk_m2m = models.ManyToManyField(NKChild, related_name='ref_m2ms') - - def __unicode__(self): - return u'%s: Reference to %s [%s]' % ( - self.text, - self.nk_fk, - ', '.join(str(o) for o in self.nk_m2m.all()) - ) - - -# ome models with pathological circular dependencies -class Circle1(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle2'] - - -class Circle2(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle1'] - - -class Circle3(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle3'] - - -class Circle4(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle5'] - - -class Circle5(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle6'] - - -class Circle6(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.circle4'] - - -class ExternalDependency(models.Model): - name = models.CharField(max_length=255) - - def natural_key(self): - return self.name - natural_key.dependencies = ['fixtures_regress.book'] - - -# Model for regression test of #11101 -class Thingy(models.Model): - name = models.CharField(max_length=255) diff --git a/parts/django/tests/regressiontests/fixtures_regress/tests.py b/parts/django/tests/regressiontests/fixtures_regress/tests.py deleted file mode 100644 index 57ee7c0..0000000 --- a/parts/django/tests/regressiontests/fixtures_regress/tests.py +++ /dev/null @@ -1,611 +0,0 @@ -# -*- coding: utf-8 -*- -# Unittests for fixtures. -import os -import sys -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -from django.conf import settings -from django.core import management -from django.core.management.commands.dumpdata import sort_dependencies -from django.core.management.base import CommandError -from django.db.models import signals -from django.db import DEFAULT_DB_ALIAS, transaction -from django.test import TestCase, TransactionTestCase - -from models import Animal, Stuff -from models import Absolute, Parent, Child -from models import Article, Widget -from models import Store, Person, Book -from models import NKChild, RefToNKChild -from models import Circle1, Circle2, Circle3 -from models import ExternalDependency -from models import Thingy - - -pre_save_checks = [] -def animal_pre_save_check(signal, sender, instance, **kwargs): - "A signal that is used to check the type of data loaded from fixtures" - pre_save_checks.append( - ( - 'Count = %s (%s)' % (instance.count, type(instance.count)), - 'Weight = %s (%s)' % (instance.weight, type(instance.weight)), - ) - ) - - -class TestFixtures(TestCase): - def test_duplicate_pk(self): - """ - This is a regression test for ticket #3790. - """ - # Load a fixture that uses PK=1 - management.call_command( - 'loaddata', - 'sequence', - verbosity=0, - commit=False - ) - - # Create a new animal. Without a sequence reset, this new object - # will take a PK of 1 (on Postgres), and the save will fail. - - animal = Animal( - name='Platypus', - latin_name='Ornithorhynchus anatinus', - count=2, - weight=2.2 - ) - animal.save() - self.assertTrue(animal.id > 1) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': - def test_pretty_print_xml(self): - """ - Regression test for ticket #4558 -- pretty printing of XML fixtures - doesn't affect parsing of None values. - """ - # Load a pretty-printed XML fixture with Nulls. - management.call_command( - 'loaddata', - 'pretty.xml', - verbosity=0, - commit=False - ) - self.assertEqual(Stuff.objects.all()[0].name, None) - self.assertEqual(Stuff.objects.all()[0].owner, None) - - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - def test_pretty_print_xml_empty_strings(self): - """ - Regression test for ticket #4558 -- pretty printing of XML fixtures - doesn't affect parsing of None values. - """ - # Load a pretty-printed XML fixture with Nulls. - management.call_command( - 'loaddata', - 'pretty.xml', - verbosity=0, - commit=False - ) - self.assertEqual(Stuff.objects.all()[0].name, u'') - self.assertEqual(Stuff.objects.all()[0].owner, None) - - def test_absolute_path(self): - """ - 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, - commit=False - ) - self.assertEqual(Absolute.load_count, 1) - - - def test_unknown_format(self): - """ - Test for ticket #4371 -- Loading data of an unknown format should fail - Validate that error conditions are caught correctly - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'bad_fixture1.unkn', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "Problem installing fixture 'bad_fixture1': unkn is not a known serialization format.\n" - ) - - def test_invalid_data(self): - """ - Test for ticket #4371 -- Loading a fixture file with invalid data - using explicit filename. - Validate that error conditions are caught correctly - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'bad_fixture2.xml', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" - ) - - def test_invalid_data_no_ext(self): - """ - Test for ticket #4371 -- Loading a fixture file with invalid data - without file extension. - Validate that error conditions are caught correctly - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'bad_fixture2', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" - ) - - def test_empty(self): - """ - Test for ticket #4371 -- Loading a fixture file with no data returns an error. - Validate that error conditions are caught correctly - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'empty', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "No fixture data found for 'empty'. (File format may be invalid.)\n" - ) - - def test_abort_loaddata_on_error(self): - """ - Test for ticket #4371 -- If any of the fixtures contain an error, - loading is aborted. - Validate that error conditions are caught correctly - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'empty', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "No fixture data found for 'empty'. (File format may be invalid.)\n" - ) - - def test_error_message(self): - """ - (Regression for #9011 - error message is correct) - """ - stderr = StringIO() - management.call_command( - 'loaddata', - 'bad_fixture2', - 'animal', - verbosity=0, - commit=False, - stderr=stderr, - ) - self.assertEqual( - stderr.getvalue(), - "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" - ) - - def test_pg_sequence_resetting_checks(self): - """ - Test for ticket #7565 -- PostgreSQL sequence resetting checks shouldn't - ascend to parent models when inheritance is used - (since they are treated individually). - """ - management.call_command( - 'loaddata', - 'model-inheritance.json', - verbosity=0, - commit=False - ) - self.assertEqual(Parent.objects.all()[0].id, 1) - self.assertEqual(Child.objects.all()[0].id, 1) - - def test_close_connection_after_loaddata(self): - """ - Test for ticket #7572 -- MySQL has a problem if the same connection is - used to create tables, load data, and then query over that data. - To compensate, we close the connection after running loaddata. - This ensures that a new connection is opened when test queries are - issued. - """ - management.call_command( - 'loaddata', - 'big-fixture.json', - verbosity=0, - commit=False - ) - articles = Article.objects.exclude(id=9) - self.assertEqual( - list(articles.values_list('id', flat=True)), - [1, 2, 3, 4, 5, 6, 7, 8] - ) - # Just for good measure, run the same query again. - # Under the influence of ticket #7572, this will - # give a different result to the previous call. - self.assertEqual( - list(articles.values_list('id', flat=True)), - [1, 2, 3, 4, 5, 6, 7, 8] - ) - - def test_field_value_coerce(self): - """ - Test for tickets #8298, #9942 - Field values should be coerced into the - correct type by the deserializer, not as part of the database write. - """ - global pre_save_checks - pre_save_checks = [] - signals.pre_save.connect(animal_pre_save_check) - management.call_command( - 'loaddata', - 'animal.xml', - verbosity=0, - commit=False, - ) - self.assertEqual( - pre_save_checks, - [ - ("Count = 42 (<type 'int'>)", "Weight = 1.2 (<type 'float'>)") - ] - ) - signals.pre_save.disconnect(animal_pre_save_check) - - def test_dumpdata_uses_default_manager(self): - """ - Regression for #11286 - Ensure that dumpdata honors the default manager - Dump the current contents of the database as a JSON fixture - """ - management.call_command( - 'loaddata', - 'animal.xml', - verbosity=0, - commit=False, - ) - management.call_command( - 'loaddata', - 'sequence.json', - verbosity=0, - commit=False, - ) - animal = Animal( - name='Platypus', - latin_name='Ornithorhynchus anatinus', - count=2, - weight=2.2 - ) - animal.save() - - stdout = StringIO() - management.call_command( - 'dumpdata', - 'fixtures_regress.animal', - format='json', - stdout=stdout - ) - - # Output order isn't guaranteed, so check for parts - data = stdout.getvalue() - lion_json = '{"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, "weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}}' - emu_json = '{"pk": 10, "model": "fixtures_regress.animal", "fields": {"count": 42, "weight": 1.2, "name": "Emu", "latin_name": "Dromaius novaehollandiae"}}' - platypus_json = '{"pk": %d, "model": "fixtures_regress.animal", "fields": {"count": 2, "weight": 2.2000000000000002, "name": "Platypus", "latin_name": "Ornithorhynchus anatinus"}}' - platypus_json = platypus_json % animal.pk - - self.assertEqual(len(data), len('[%s]' % ', '.join([lion_json, emu_json, platypus_json]))) - self.assertTrue(lion_json in data) - self.assertTrue(emu_json in data) - self.assertTrue(platypus_json in data) - - def test_proxy_model_included(self): - """ - Regression for #11428 - Proxy models aren't included when you dumpdata - """ - stdout = StringIO() - # Create an instance of the concrete class - Widget(name='grommet').save() - management.call_command( - 'dumpdata', - 'fixtures_regress.widget', - 'fixtures_regress.widgetproxy', - format='json', - stdout=stdout - ) - self.assertEqual( - stdout.getvalue(), - """[{"pk": 1, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]""" - ) - - -class NaturalKeyFixtureTests(TestCase): - def assertRaisesMessage(self, exc, msg, func, *args, **kwargs): - try: - func(*args, **kwargs) - except Exception, e: - self.assertEqual(msg, str(e)) - self.assertTrue(isinstance(e, exc), "Expected %s, got %s" % (exc, type(e))) - - def test_nk_deserialize(self): - """ - Test for ticket #13030 - Python based parser version - natural keys deserialize with fk to inheriting model - """ - management.call_command( - 'loaddata', - 'model-inheritance.json', - verbosity=0, - commit=False - ) - management.call_command( - 'loaddata', - 'nk-inheritance.json', - verbosity=0, - commit=False - ) - self.assertEqual( - NKChild.objects.get(pk=1).data, - 'apple' - ) - - self.assertEqual( - RefToNKChild.objects.get(pk=1).nk_fk.data, - 'apple' - ) - - def test_nk_deserialize_xml(self): - """ - Test for ticket #13030 - XML version - natural keys deserialize with fk to inheriting model - """ - management.call_command( - 'loaddata', - 'model-inheritance.json', - verbosity=0, - commit=False - ) - management.call_command( - 'loaddata', - 'nk-inheritance.json', - verbosity=0, - commit=False - ) - management.call_command( - 'loaddata', - 'nk-inheritance2.xml', - verbosity=0, - commit=False - ) - self.assertEqual( - NKChild.objects.get(pk=2).data, - 'banana' - ) - self.assertEqual( - RefToNKChild.objects.get(pk=2).nk_fk.data, - 'apple' - ) - - def test_nk_on_serialize(self): - """ - Check that natural key requirements are taken into account - when serializing models - """ - management.call_command( - 'loaddata', - 'forward_ref_lookup.json', - verbosity=0, - commit=False - ) - - stdout = StringIO() - management.call_command( - 'dumpdata', - 'fixtures_regress.book', - 'fixtures_regress.person', - 'fixtures_regress.store', - verbosity=0, - format='json', - use_natural_keys=True, - stdout=stdout, - ) - self.assertEqual( - stdout.getvalue(), - """[{"pk": 2, "model": "fixtures_regress.store", "fields": {"name": "Amazon"}}, {"pk": 3, "model": "fixtures_regress.store", "fields": {"name": "Borders"}}, {"pk": 4, "model": "fixtures_regress.person", "fields": {"name": "Neal Stephenson"}}, {"pk": 1, "model": "fixtures_regress.book", "fields": {"stores": [["Amazon"], ["Borders"]], "name": "Cryptonomicon", "author": ["Neal Stephenson"]}}]""" - ) - - def test_dependency_sorting(self): - """ - Now lets check the dependency sorting explicitly - It doesn't matter what order you mention the models - Store *must* be serialized before then Person, and both - must be serialized before Book. - """ - sorted_deps = sort_dependencies( - [('fixtures_regress', [Book, Person, Store])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_2(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Book, Store, Person])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_3(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Store, Book, Person])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_4(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Store, Person, Book])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_5(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Person, Book, Store])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_6(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Person, Store, Book])] - ) - self.assertEqual( - sorted_deps, - [Store, Person, Book] - ) - - def test_dependency_sorting_dangling(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Person, Circle1, Store, Book])] - ) - self.assertEqual( - sorted_deps, - [Circle1, Store, Person, Book] - ) - - def test_dependency_sorting_tight_circular(self): - self.assertRaisesMessage( - CommandError, - """Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.""", - sort_dependencies, - [('fixtures_regress', [Person, Circle2, Circle1, Store, Book])], - ) - - def test_dependency_sorting_tight_circular_2(self): - self.assertRaisesMessage( - CommandError, - """Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.""", - sort_dependencies, - [('fixtures_regress', [Circle1, Book, Circle2])], - ) - - def test_dependency_self_referential(self): - self.assertRaisesMessage( - CommandError, - """Can't resolve dependencies for fixtures_regress.Circle3 in serialized app list.""", - sort_dependencies, - [('fixtures_regress', [Book, Circle3])], - ) - - def test_dependency_sorting_long(self): - self.assertRaisesMessage( - CommandError, - """Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2, fixtures_regress.Circle3 in serialized app list.""", - sort_dependencies, - [('fixtures_regress', [Person, Circle2, Circle1, Circle3, Store, Book])], - ) - - def test_dependency_sorting_normal(self): - sorted_deps = sort_dependencies( - [('fixtures_regress', [Person, ExternalDependency, Book])] - ) - self.assertEqual( - sorted_deps, - [Person, Book, ExternalDependency] - ) - - def test_normal_pk(self): - """ - Check that normal primary keys still work - on a model with natural key capabilities - """ - management.call_command( - 'loaddata', - 'non_natural_1.json', - verbosity=0, - commit=False - ) - management.call_command( - 'loaddata', - 'forward_ref_lookup.json', - verbosity=0, - commit=False - ) - management.call_command( - 'loaddata', - 'non_natural_2.xml', - verbosity=0, - commit=False - ) - books = Book.objects.all() - self.assertEqual( - books.__repr__(), - """[<Book: Cryptonomicon by Neal Stephenson (available at Amazon, Borders)>, <Book: Ender's Game by Orson Scott Card (available at Collins Bookstore)>, <Book: Permutation City by Greg Egan (available at Angus and Robertson)>]""" - ) - - -class TestTicket11101(TransactionTestCase): - - def ticket_11101(self): - management.call_command( - 'loaddata', - 'thingy.json', - verbosity=0, - commit=False - ) - self.assertEqual(Thingy.objects.count(), 1) - transaction.rollback() - self.assertEqual(Thingy.objects.count(), 0) - - def test_ticket_11101(self): - """Test that fixtures can be rolled back (ticket #11101).""" - ticket_11101 = transaction.commit_manually(self.ticket_11101) - ticket_11101() diff --git a/parts/django/tests/regressiontests/forms/__init__.py b/parts/django/tests/regressiontests/forms/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/forms/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/forms/localflavor/__init__.py b/parts/django/tests/regressiontests/forms/localflavor/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/forms/localflavor/ar.py b/parts/django/tests/regressiontests/forms/localflavor/ar.py deleted file mode 100644 index 9c67269..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/ar.py +++ /dev/null @@ -1,99 +0,0 @@ -from django.contrib.localflavor.ar.forms import (ARProvinceSelect, - ARPostalCodeField, ARDNIField, ARCUITField) - -from utils import LocalFlavorTestCase - - -class ARLocalFlavorTests(LocalFlavorTestCase): - def test_ARProvinceSelect(self): - f = ARProvinceSelect() - out = u'''<select name="provincias"> -<option value="B">Buenos Aires</option> -<option value="K">Catamarca</option> -<option value="H">Chaco</option> -<option value="U">Chubut</option> -<option value="C">Ciudad Aut\xf3noma de Buenos Aires</option> -<option value="X">C\xf3rdoba</option> -<option value="W">Corrientes</option> -<option value="E">Entre R\xedos</option> -<option value="P">Formosa</option> -<option value="Y">Jujuy</option> -<option value="L">La Pampa</option> -<option value="F">La Rioja</option> -<option value="M">Mendoza</option> -<option value="N">Misiones</option> -<option value="Q">Neuqu\xe9n</option> -<option value="R">R\xedo Negro</option> -<option value="A" selected="selected">Salta</option> -<option value="J">San Juan</option> -<option value="D">San Luis</option> -<option value="Z">Santa Cruz</option> -<option value="S">Santa Fe</option> -<option value="G">Santiago del Estero</option> -<option value="V">Tierra del Fuego, Ant\xe1rtida e Islas del Atl\xe1ntico Sur</option> -<option value="T">Tucum\xe1n</option> -</select>''' - self.assertEqual(f.render('provincias', 'A'), out) - - def test_ARPostalCodeField(self): - error_format = [u'Enter a postal code in the format NNNN or ANNNNAAA.'] - error_atmost = [u'Ensure this value has at most 8 characters (it has 9).'] - error_atleast = [u'Ensure this value has at least 4 characters (it has 3).'] - valid = { - '5000': '5000', - 'C1064AAB': 'C1064AAB', - 'c1064AAB': 'C1064AAB', - 'C1064aab': 'C1064AAB', - '4400': '4400', - u'C1064AAB': 'C1064AAB', - } - invalid = { - 'C1064AABB': error_atmost + error_format, - 'C1064AA': error_format, - 'C1064AB': error_format, - '106AAB': error_format, - '500': error_atleast + error_format, - '5PPP': error_format, - } - self.assertFieldOutput(ARPostalCodeField, valid, invalid) - - def test_ARDNIField(self): - error_length = [u'This field requires 7 or 8 digits.'] - error_digitsonly = [u'This field requires only numbers.'] - valid = { - '20123456': '20123456', - '20.123.456': '20123456', - u'20123456': '20123456', - u'20.123.456': '20123456', - '20.123456': '20123456', - '9123456': '9123456', - '9.123.456': '9123456', - } - invalid = { - '101234566': error_length, - 'W0123456': error_digitsonly, - '10,123,456': error_digitsonly, - } - self.assertFieldOutput(ARDNIField, valid, invalid) - - def test_ARCUITField(self): - error_format = [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'] - error_invalid = [u'Invalid CUIT.'] - valid = { - '20-10123456-9': '20-10123456-9', - u'20-10123456-9': '20-10123456-9', - '27-10345678-4': '27-10345678-4', - '20101234569': '20-10123456-9', - '27103456784': '27-10345678-4', - } - invalid = { - '2-10123456-9': error_format, - '210123456-9': error_format, - '20-10123456': error_format, - '20-10123456-': error_format, - '20-10123456-5': error_invalid, - '2-10123456-9': error_format, - '27-10345678-1': error_invalid, - u'27-10345678-1': error_invalid, - } - self.assertFieldOutput(ARCUITField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/at.py b/parts/django/tests/regressiontests/forms/localflavor/at.py deleted file mode 100644 index 3fa50ac..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/at.py +++ /dev/null @@ -1,45 +0,0 @@ -from django.contrib.localflavor.at.forms import (ATZipCodeField, ATStateSelect, - ATSocialSecurityNumberField) - -from utils import LocalFlavorTestCase - - -class ATLocalFlavorTests(LocalFlavorTestCase): - def test_ATStateSelect(self): - f = ATStateSelect() - out = u'''<select name="bundesland"> -<option value="BL">Burgenland</option> -<option value="KA">Carinthia</option> -<option value="NO">Lower Austria</option> -<option value="OO">Upper Austria</option> -<option value="SA">Salzburg</option> -<option value="ST">Styria</option> -<option value="TI">Tyrol</option> -<option value="VO">Vorarlberg</option> -<option value="WI" selected="selected">Vienna</option> -</select>''' - self.assertEqual(f.render('bundesland', 'WI'), out) - - def test_ATZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXX.'] - valid = { - '1150': '1150', - '4020': '4020', - '8020': '8020', - } - invalid = { - '111222': error_format, - 'eeffee': error_format, - } - self.assertFieldOutput(ATZipCodeField, valid, invalid) - - def test_ATSocialSecurityNumberField(self): - error_format = [u'Enter a valid Austrian Social Security Number in XXXX XXXXXX format.'] - valid = { - '1237 010180': '1237 010180', - } - invalid = { - '1237 010181': error_format, - '12370 010180': error_format, - } - self.assertFieldOutput(ATSocialSecurityNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/au.py b/parts/django/tests/regressiontests/forms/localflavor/au.py deleted file mode 100644 index 4bd8a76..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/au.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.contrib.localflavor.au.forms import (AUPostCodeField, - AUPhoneNumberField, AUStateSelect) - -from utils import LocalFlavorTestCase - - -class AULocalFlavorTests(LocalFlavorTestCase): - def test_AUStateSelect(self): - f = AUStateSelect() - out = u'''<select name="state"> -<option value="ACT">Australian Capital Territory</option> -<option value="NSW" selected="selected">New South Wales</option> -<option value="NT">Northern Territory</option> -<option value="QLD">Queensland</option> -<option value="SA">South Australia</option> -<option value="TAS">Tasmania</option> -<option value="VIC">Victoria</option> -<option value="WA">Western Australia</option> -</select>''' - self.assertEqual(f.render('state', 'NSW'), out) - - def test_AUPostCodeField(self): - error_format = [u'Enter a 4 digit post code.'] - valid = { - '1234': '1234', - '2000': '2000', - } - invalid = { - 'abcd': error_format, - '20001': error_format, - } - self.assertFieldOutput(AUPostCodeField, valid, invalid) - - def test_AUPhoneNumberField(self): - error_format = [u'Phone numbers must contain 10 digits.'] - valid = { - '1234567890': '1234567890', - '0213456789': '0213456789', - '02 13 45 67 89': '0213456789', - '(02) 1345 6789': '0213456789', - '(02) 1345-6789': '0213456789', - '(02)1345-6789': '0213456789', - '0408 123 456': '0408123456', - } - invalid = { - '123': error_format, - '1800DJANGO': error_format, - } - self.assertFieldOutput(AUPhoneNumberField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/br.py b/parts/django/tests/regressiontests/forms/localflavor/br.py deleted file mode 100644 index 6ae7105..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/br.py +++ /dev/null @@ -1,144 +0,0 @@ -from django.contrib.localflavor.br.forms import (BRZipCodeField, - BRCNPJField, BRCPFField, BRPhoneNumberField, BRStateSelect, - BRStateChoiceField) - -from utils import LocalFlavorTestCase - - -class BRLocalFlavorTests(LocalFlavorTestCase): - def test_BRZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXXX-XXX.'] - valid = { - '12345-123': '12345-123', - } - invalid = { - '12345_123': error_format, - '1234-123': error_format, - 'abcde-abc': error_format, - '12345-': error_format, - '-123': error_format, - } - self.assertFieldOutput(BRZipCodeField, valid, invalid) - - def test_BRCNPJField(self): - error_format = [u'Invalid CNPJ number.'] - error_numbersonly = [u'This field requires only numbers.'] - valid = { - '64.132.916/0001-88': '64.132.916/0001-88', - '64-132-916/0001-88': '64-132-916/0001-88', - '64132916/0001-88': '64132916/0001-88', - } - invalid = { - '12-345-678/9012-10': error_format, - '12.345.678/9012-10': error_format, - '12345678/9012-10': error_format, - '64.132.916/0001-XX': error_numbersonly, - } - self.assertFieldOutput(BRCNPJField, valid, invalid) - - def test_BRCPFField(self): - error_format = [u'Invalid CPF number.'] - error_numbersonly = [u'This field requires only numbers.'] - error_atmost_chars = [u'Ensure this value has at most 14 characters (it has 15).'] - error_atleast_chars = [u'Ensure this value has at least 11 characters (it has 10).'] - error_atmost = [u'This field requires at most 11 digits or 14 characters.'] - valid = { - '663.256.017-26': '663.256.017-26', - '66325601726': '66325601726', - '375.788.573-20': '375.788.573-20', - '84828509895': '84828509895', - } - invalid = { - '489.294.654-54': error_format, - '295.669.575-98': error_format, - '539.315.127-22': error_format, - '375.788.573-XX': error_numbersonly, - '375.788.573-000': error_atmost_chars, - '123.456.78': error_atleast_chars, - '123456789555': error_atmost, - } - self.assertFieldOutput(BRCPFField, valid, invalid) - - def test_BRPhoneNumberField(self): - # TODO: this doesn't test for any invalid inputs. - valid = { - '41-3562-3464': u'41-3562-3464', - '4135623464': u'41-3562-3464', - '41 3562-3464': u'41-3562-3464', - '41 3562 3464': u'41-3562-3464', - '(41) 3562 3464': u'41-3562-3464', - '41.3562.3464': u'41-3562-3464', - '41.3562-3464': u'41-3562-3464', - ' (41) 3562.3464': u'41-3562-3464', - } - invalid = {} - self.assertFieldOutput(BRPhoneNumberField, valid, invalid) - - def test_BRStateSelect(self): - f = BRStateSelect() - out = u'''<select name="states"> -<option value="AC">Acre</option> -<option value="AL">Alagoas</option> -<option value="AP">Amap\xe1</option> -<option value="AM">Amazonas</option> -<option value="BA">Bahia</option> -<option value="CE">Cear\xe1</option> -<option value="DF">Distrito Federal</option> -<option value="ES">Esp\xedrito Santo</option> -<option value="GO">Goi\xe1s</option> -<option value="MA">Maranh\xe3o</option> -<option value="MT">Mato Grosso</option> -<option value="MS">Mato Grosso do Sul</option> -<option value="MG">Minas Gerais</option> -<option value="PA">Par\xe1</option> -<option value="PB">Para\xedba</option> -<option value="PR" selected="selected">Paran\xe1</option> -<option value="PE">Pernambuco</option> -<option value="PI">Piau\xed</option> -<option value="RJ">Rio de Janeiro</option> -<option value="RN">Rio Grande do Norte</option> -<option value="RS">Rio Grande do Sul</option> -<option value="RO">Rond\xf4nia</option> -<option value="RR">Roraima</option> -<option value="SC">Santa Catarina</option> -<option value="SP">S\xe3o Paulo</option> -<option value="SE">Sergipe</option> -<option value="TO">Tocantins</option> -</select>''' - self.assertEqual(f.render('states', 'PR'), out) - - def test_BRStateChoiceField(self): - error_invalid = [u'Select a valid brazilian state. That state is not one of the available states.'] - valid = { - 'AC': 'AC', - 'AL': 'AL', - 'AP': 'AP', - 'AM': 'AM', - 'BA': 'BA', - 'CE': 'CE', - 'DF': 'DF', - 'ES': 'ES', - 'GO': 'GO', - 'MA': 'MA', - 'MT': 'MT', - 'MS': 'MS', - 'MG': 'MG', - 'PA': 'PA', - 'PB': 'PB', - 'PR': 'PR', - 'PE': 'PE', - 'PI': 'PI', - 'RJ': 'RJ', - 'RN': 'RN', - 'RS': 'RS', - 'RO': 'RO', - 'RR': 'RR', - 'SC': 'SC', - 'SP': 'SP', - 'SE': 'SE', - 'TO': 'TO', - } - invalid = { - 'pr': error_invalid, - } - self.assertFieldOutput(BRStateChoiceField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/ca.py b/parts/django/tests/regressiontests/forms/localflavor/ca.py deleted file mode 100644 index 575f41c..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/ca.py +++ /dev/null @@ -1,95 +0,0 @@ -from django.contrib.localflavor.ca.forms import (CAPostalCodeField, - CAPhoneNumberField, CAProvinceField, CAProvinceSelect, - CASocialInsuranceNumberField) - -from utils import LocalFlavorTestCase - - -class CALocalFlavorTests(LocalFlavorTestCase): - def test_CAProvinceSelect(self): - f = CAProvinceSelect() - out = u'''<select name="province"> -<option value="AB" selected="selected">Alberta</option> -<option value="BC">British Columbia</option> -<option value="MB">Manitoba</option> -<option value="NB">New Brunswick</option> -<option value="NF">Newfoundland and Labrador</option> -<option value="NT">Northwest Territories</option> -<option value="NS">Nova Scotia</option> -<option value="NU">Nunavut</option> -<option value="ON">Ontario</option> -<option value="PE">Prince Edward Island</option> -<option value="QC">Quebec</option> -<option value="SK">Saskatchewan</option> -<option value="YK">Yukon</option> -</select>''' - self.assertEqual(f.render('province', 'AB'), out) - - def test_CAPostalCodeField(self): - error_format = [u'Enter a postal code in the format XXX XXX.'] - valid = { - 'T2S 2H7': 'T2S 2H7', - 'T2S 2W7': 'T2S 2W7', - 'T2S 2Z7': 'T2S 2Z7', - 'T2Z 2H7': 'T2Z 2H7', - - } - invalid = { - 'T2S2H7' : error_format, - 'T2S 2H' : error_format, - '2T6 H8I': error_format, - 'T2S2H' : error_format, - 90210 : error_format, - 'W2S 2H3': error_format, - 'Z2S 2H3': error_format, - 'F2S 2H3': error_format, - 'A2S 2D3': error_format, - 'A2I 2R3': error_format, - 'A2Q 2R3': error_format, - 'U2B 2R3': error_format, - 'O2B 2R3': error_format, - } - self.assertFieldOutput(CAPostalCodeField, valid, invalid) - - def test_CAPhoneNumberField(self): - error_format = [u'Phone numbers must be in XXX-XXX-XXXX format.'] - valid = { - '403-555-1212': '403-555-1212', - '4035551212': '403-555-1212', - '403 555-1212': '403-555-1212', - '(403) 555-1212': '403-555-1212', - '403 555 1212': '403-555-1212', - '403.555.1212': '403-555-1212', - '403.555-1212': '403-555-1212', - ' (403) 555.1212 ': '403-555-1212', - } - invalid = { - '555-1212': error_format, - '403-55-1212': error_format, - } - self.assertFieldOutput(CAPhoneNumberField, valid, invalid) - - def test_CAProvinceField(self): - error_format = [u'Enter a Canadian province or territory.'] - valid = { - 'ab': 'AB', - 'BC': 'BC', - 'nova scotia': 'NS', - ' manitoba ': 'MB', - } - invalid = { - 'T2S 2H7': error_format, - } - self.assertFieldOutput(CAProvinceField, valid, invalid) - - def test_CASocialInsuranceField(self): - error_format = [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.'] - valid = { - '046-454-286': '046-454-286', - } - invalid = { - '046-454-287': error_format, - '046 454 286': error_format, - '046-44-286': error_format, - } - self.assertFieldOutput(CASocialInsuranceNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/ch.py b/parts/django/tests/regressiontests/forms/localflavor/ch.py deleted file mode 100644 index c67bfcf..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/ch.py +++ /dev/null @@ -1,75 +0,0 @@ -from django.contrib.localflavor.ch.forms import (CHZipCodeField, - CHPhoneNumberField, CHIdentityCardNumberField, CHStateSelect) - -from utils import LocalFlavorTestCase - - -class CHLocalFlavorTests(LocalFlavorTestCase): - def test_CHStateSelect(self): - f = CHStateSelect() - out = u'''<select name="state"> -<option value="AG" selected="selected">Aargau</option> -<option value="AI">Appenzell Innerrhoden</option> -<option value="AR">Appenzell Ausserrhoden</option> -<option value="BS">Basel-Stadt</option> -<option value="BL">Basel-Land</option> -<option value="BE">Berne</option> -<option value="FR">Fribourg</option> -<option value="GE">Geneva</option> -<option value="GL">Glarus</option> -<option value="GR">Graubuenden</option> -<option value="JU">Jura</option> -<option value="LU">Lucerne</option> -<option value="NE">Neuchatel</option> -<option value="NW">Nidwalden</option> -<option value="OW">Obwalden</option> -<option value="SH">Schaffhausen</option> -<option value="SZ">Schwyz</option> -<option value="SO">Solothurn</option> -<option value="SG">St. Gallen</option> -<option value="TG">Thurgau</option> -<option value="TI">Ticino</option> -<option value="UR">Uri</option> -<option value="VS">Valais</option> -<option value="VD">Vaud</option> -<option value="ZG">Zug</option> -<option value="ZH">Zurich</option> -</select>''' - self.assertEqual(f.render('state', 'AG'), out) - - def test_CHZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXX.'] - valid = { - '1234': '1234', - '0000': '0000', - } - invalid = { - '800x': error_format, - '80 00': error_format, - } - self.assertFieldOutput(CHZipCodeField, valid, invalid) - - def test_CHPhoneNumberField(self): - error_format = [u'Phone numbers must be in 0XX XXX XX XX format.'] - valid = { - '012 345 67 89': '012 345 67 89', - '0123456789': '012 345 67 89', - } - invalid = { - '01234567890': error_format, - '1234567890': error_format, - } - self.assertFieldOutput(CHPhoneNumberField, valid, invalid) - - def test_CHIdentityCardNumberField(self): - error_format = [u'Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.'] - valid = { - 'C1234567<0': 'C1234567<0', - '2123456700': '2123456700', - } - invalid = { - 'C1234567<1': error_format, - '2123456701': error_format, - } - self.assertFieldOutput(CHIdentityCardNumberField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/cl.py b/parts/django/tests/regressiontests/forms/localflavor/cl.py deleted file mode 100644 index 15b8c7b..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/cl.py +++ /dev/null @@ -1,56 +0,0 @@ -from django.contrib.localflavor.cl.forms import CLRutField, CLRegionSelect -from django.core.exceptions import ValidationError - -from utils import LocalFlavorTestCase - - -class CLLocalFlavorTests(LocalFlavorTestCase): - def test_CLRegionSelect(self): - f = CLRegionSelect() - out = u'''<select name="foo"> -<option value="RM">Regi\xf3n Metropolitana de Santiago</option> -<option value="I">Regi\xf3n de Tarapac\xe1</option> -<option value="II">Regi\xf3n de Antofagasta</option> -<option value="III">Regi\xf3n de Atacama</option> -<option value="IV">Regi\xf3n de Coquimbo</option> -<option value="V">Regi\xf3n de Valpara\xedso</option> -<option value="VI">Regi\xf3n del Libertador Bernardo O'Higgins</option> -<option value="VII">Regi\xf3n del Maule</option> -<option value="VIII">Regi\xf3n del B\xedo B\xedo</option> -<option value="IX">Regi\xf3n de la Araucan\xeda</option> -<option value="X">Regi\xf3n de los Lagos</option> -<option value="XI">Regi\xf3n de Ays\xe9n del General Carlos Ib\xe1\xf1ez del Campo</option> -<option value="XII">Regi\xf3n de Magallanes y la Ant\xe1rtica Chilena</option> -<option value="XIV">Regi\xf3n de Los R\xedos</option> -<option value="XV">Regi\xf3n de Arica-Parinacota</option> -</select>''' - self.assertEqual(f.render('foo', 'bar'), out) - - def test_CLRutField(self): - error_invalid = [u'The Chilean RUT is not valid.'] - error_format = [u'Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.'] - valid = { - '11-6': '11-6', - '116': '11-6', - '767484100': '76.748.410-0', - '78.412.790-7': '78.412.790-7', - '8.334.6043': '8.334.604-3', - '76793310-K': '76.793.310-K', - } - invalid = { - '11.111.111-0': error_invalid, - '111': error_invalid, - } - self.assertFieldOutput(CLRutField, valid, invalid) - - # deal with special "Strict Mode". - invalid = { - '11-6': error_format, - '767484100': error_format, - '8.334.6043': error_format, - '76793310-K': error_format, - '11.111.111-0': error_invalid - } - self.assertFieldOutput(CLRutField, - {}, invalid, field_kwargs={"strict": True} - ) diff --git a/parts/django/tests/regressiontests/forms/localflavor/cz.py b/parts/django/tests/regressiontests/forms/localflavor/cz.py deleted file mode 100644 index 4cff172..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/cz.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# Tests for the contrib/localflavor/ CZ Form Fields - -tests = r""" -# CZPostalCodeField ######################################################### - ->>> from django.contrib.localflavor.cz.forms import CZPostalCodeField ->>> f = CZPostalCodeField() ->>> f.clean('84545x') -Traceback (most recent call last): -... -ValidationError: [u'Enter a postal code in the format XXXXX or XXX XX.'] ->>> f.clean('91909') -u'91909' ->>> f.clean('917 01') -u'91701' ->>> f.clean('12345') -u'12345' ->>> f.clean('123456') -Traceback (most recent call last): -... -ValidationError: [u'Enter a postal code in the format XXXXX or XXX XX.'] ->>> f.clean('1234') -Traceback (most recent call last): -... -ValidationError: [u'Enter a postal code in the format XXXXX or XXX XX.'] ->>> f.clean('123 4') -Traceback (most recent call last): -... -ValidationError: [u'Enter a postal code in the format XXXXX or XXX XX.'] - -# CZRegionSelect ############################################################ - ->>> from django.contrib.localflavor.cz.forms import CZRegionSelect ->>> w = CZRegionSelect() ->>> w.render('regions', 'TT') -u'<select name="regions">\n<option value="PR">Prague</option>\n<option value="CE">Central Bohemian Region</option>\n<option value="SO">South Bohemian Region</option>\n<option value="PI">Pilsen Region</option>\n<option value="CA">Carlsbad Region</option>\n<option value="US">Usti Region</option>\n<option value="LB">Liberec Region</option>\n<option value="HK">Hradec Region</option>\n<option value="PA">Pardubice Region</option>\n<option value="VY">Vysocina Region</option>\n<option value="SM">South Moravian Region</option>\n<option value="OL">Olomouc Region</option>\n<option value="ZL">Zlin Region</option>\n<option value="MS">Moravian-Silesian Region</option>\n</select>' - -# CZBirthNumberField ######################################################## - ->>> from django.contrib.localflavor.cz.forms import CZBirthNumberField ->>> f = CZBirthNumberField() ->>> f.clean('880523/1237') -u'880523/1237' ->>> f.clean('8805231237') -u'8805231237' ->>> f.clean('880523/000') -u'880523/000' ->>> f.clean('880523000') -u'880523000' ->>> f.clean('882101/0011') -u'882101/0011' ->>> f.clean('880523/1237', 'm') -u'880523/1237' ->>> f.clean('885523/1231', 'f') -u'885523/1231' ->>> f.clean('123456/12') -Traceback (most recent call last): -... -ValidationError: [u'Enter a birth number in the format XXXXXX/XXXX or XXXXXXXXXX.'] ->>> f.clean('123456/12345') -Traceback (most recent call last): -... -ValidationError: [u'Enter a birth number in the format XXXXXX/XXXX or XXXXXXXXXX.'] ->>> f.clean('12345612') -Traceback (most recent call last): -... -ValidationError: [u'Enter a birth number in the format XXXXXX/XXXX or XXXXXXXXXX.'] ->>> f.clean('12345612345') -Traceback (most recent call last): -... -ValidationError: [u'Enter a birth number in the format XXXXXX/XXXX or XXXXXXXXXX.'] ->>> f.clean('881523/0000', 'm') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('885223/0000', 'm') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('881223/0000', 'f') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('886523/0000', 'f') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('880523/1239') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('8805231239') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] ->>> f.clean('990101/0011') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid birth number.'] - -# CZICNumberField ######################################################## - ->>> from django.contrib.localflavor.cz.forms import CZICNumberField ->>> f = CZICNumberField() ->>> f.clean('12345679') -u'12345679' ->>> f.clean('12345601') -u'12345601' ->>> f.clean('12345661') -u'12345661' ->>> f.clean('12345610') -u'12345610' ->>> f.clean('1234567') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid IC number.'] ->>> f.clean('12345660') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid IC number.'] ->>> f.clean('12345600') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid IC number.'] -""" diff --git a/parts/django/tests/regressiontests/forms/localflavor/de.py b/parts/django/tests/regressiontests/forms/localflavor/de.py deleted file mode 100644 index 7c68bcc..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/de.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.contrib.localflavor.de.forms import (DEZipCodeField, DEStateSelect, - DEIdentityCardNumberField) - -from utils import LocalFlavorTestCase - - -class DELocalFlavorTests(LocalFlavorTestCase): - def test_DEStateSelect(self): - f = DEStateSelect() - out = u'''<select name="states"> -<option value="BW">Baden-Wuerttemberg</option> -<option value="BY">Bavaria</option> -<option value="BE">Berlin</option> -<option value="BB">Brandenburg</option> -<option value="HB">Bremen</option> -<option value="HH">Hamburg</option> -<option value="HE">Hessen</option> -<option value="MV">Mecklenburg-Western Pomerania</option> -<option value="NI">Lower Saxony</option> -<option value="NW">North Rhine-Westphalia</option> -<option value="RP">Rhineland-Palatinate</option> -<option value="SL">Saarland</option> -<option value="SN">Saxony</option> -<option value="ST">Saxony-Anhalt</option> -<option value="SH">Schleswig-Holstein</option> -<option value="TH" selected="selected">Thuringia</option> -</select>''' - self.assertEqual(f.render('states', 'TH'), out) - - def test_DEZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXXX.'] - valid = { - '99423': '99423', - } - invalid = { - ' 99423': error_format, - } - self.assertFieldOutput(DEZipCodeField, valid, invalid) - - def test_DEIdentityCardNumberField(self): - error_format = [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.'] - valid = { - '7549313035D-6004103-0903042-0': '7549313035D-6004103-0903042-0', - '9786324830D 6104243 0910271 2': '9786324830D-6104243-0910271-2', - } - invalid = { - '0434657485D-6407276-0508137-9': error_format, - } - self.assertFieldOutput(DEIdentityCardNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/es.py b/parts/django/tests/regressiontests/forms/localflavor/es.py deleted file mode 100644 index b584075..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/es.py +++ /dev/null @@ -1,172 +0,0 @@ -from django.contrib.localflavor.es.forms import (ESPostalCodeField, ESPhoneNumberField, - ESIdentityCardNumberField, ESCCCField, ESRegionSelect, ESProvinceSelect) - -from utils import LocalFlavorTestCase - - -class ESLocalFlavorTests(LocalFlavorTestCase): - def test_ESRegionSelect(self): - f = ESRegionSelect() - out = u'''<select name="regions"> -<option value="AN">Andalusia</option> -<option value="AR">Aragon</option> -<option value="O">Principality of Asturias</option> -<option value="IB">Balearic Islands</option> -<option value="PV">Basque Country</option> -<option value="CN">Canary Islands</option> -<option value="S">Cantabria</option> -<option value="CM">Castile-La Mancha</option> -<option value="CL">Castile and Leon</option> -<option value="CT" selected="selected">Catalonia</option> -<option value="EX">Extremadura</option> -<option value="GA">Galicia</option> -<option value="LO">La Rioja</option> -<option value="M">Madrid</option> -<option value="MU">Region of Murcia</option> -<option value="NA">Foral Community of Navarre</option> -<option value="VC">Valencian Community</option> -</select>''' - self.assertEqual(f.render('regions', 'CT'), out) - - def test_ESProvinceSelect(self): - f = ESProvinceSelect() - out = u'''<select name="provinces"> -<option value="01">Arava</option> -<option value="02">Albacete</option> -<option value="03">Alacant</option> -<option value="04">Almeria</option> -<option value="05">Avila</option> -<option value="06">Badajoz</option> -<option value="07">Illes Balears</option> -<option value="08" selected="selected">Barcelona</option> -<option value="09">Burgos</option> -<option value="10">Caceres</option> -<option value="11">Cadiz</option> -<option value="12">Castello</option> -<option value="13">Ciudad Real</option> -<option value="14">Cordoba</option> -<option value="15">A Coruna</option> -<option value="16">Cuenca</option> -<option value="17">Girona</option> -<option value="18">Granada</option> -<option value="19">Guadalajara</option> -<option value="20">Guipuzkoa</option> -<option value="21">Huelva</option> -<option value="22">Huesca</option> -<option value="23">Jaen</option> -<option value="24">Leon</option> -<option value="25">Lleida</option> -<option value="26">La Rioja</option> -<option value="27">Lugo</option> -<option value="28">Madrid</option> -<option value="29">Malaga</option> -<option value="30">Murcia</option> -<option value="31">Navarre</option> -<option value="32">Ourense</option> -<option value="33">Asturias</option> -<option value="34">Palencia</option> -<option value="35">Las Palmas</option> -<option value="36">Pontevedra</option> -<option value="37">Salamanca</option> -<option value="38">Santa Cruz de Tenerife</option> -<option value="39">Cantabria</option> -<option value="40">Segovia</option> -<option value="41">Seville</option> -<option value="42">Soria</option> -<option value="43">Tarragona</option> -<option value="44">Teruel</option> -<option value="45">Toledo</option> -<option value="46">Valencia</option> -<option value="47">Valladolid</option> -<option value="48">Bizkaia</option> -<option value="49">Zamora</option> -<option value="50">Zaragoza</option> -<option value="51">Ceuta</option> -<option value="52">Melilla</option> -</select>''' - self.assertEqual(f.render('provinces', '08'), out) - - def test_ESPostalCodeField(self): - error_invalid = [u'Enter a valid postal code in the range and format 01XXX - 52XXX.'] - valid = { - '08028': '08028', - '28080': '28080', - } - invalid = { - '53001': error_invalid, - '0801': error_invalid, - '080001': error_invalid, - '00999': error_invalid, - '08 01': error_invalid, - '08A01': error_invalid, - } - self.assertFieldOutput(ESPostalCodeField, valid, invalid) - - def test_ESPhoneNumberField(self): - error_invalid = [u'Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'] - valid = { - '650010101': '650010101', - '931234567': '931234567', - '800123123': '800123123', - } - invalid = { - '555555555': error_invalid, - '789789789': error_invalid, - '99123123': error_invalid, - '9999123123': error_invalid, - } - self.assertFieldOutput(ESPhoneNumberField, valid, invalid) - - def test_ESIdentityCardNumberField(self): - error_invalid = [u'Please enter a valid NIF, NIE, or CIF.'] - error_checksum_nif = [u'Invalid checksum for NIF.'] - error_checksum_nie = [u'Invalid checksum for NIE.'] - error_checksum_cif = [u'Invalid checksum for CIF.'] - valid = { - '78699688J': '78699688J', - '78699688-J': '78699688J', - '78699688 J': '78699688J', - '78699688 j': '78699688J', - 'X0901797J': 'X0901797J', - 'X-6124387-Q': 'X6124387Q', - 'X 0012953 G': 'X0012953G', - 'x-3287690-r': 'X3287690R', - 't-03287690r': 'T03287690R', - 'P2907500I': 'P2907500I', - 'B38790911': 'B38790911', - 'B31234560': 'B31234560', - 'B-3879091A': 'B3879091A', - 'B 38790911': 'B38790911', - 'P-3900800-H': 'P3900800H', - 'P 39008008': 'P39008008', - 'C-28795565': 'C28795565', - 'C 2879556E': 'C2879556E', - } - invalid = { - '78699688T': error_checksum_nif, - 'X-03287690': error_invalid, - 'X-03287690-T': error_checksum_nie, - 'B 38790917': error_checksum_cif, - 'C28795567': error_checksum_cif, - 'I38790911': error_invalid, - '78699688-2': error_invalid, - } - self.assertFieldOutput(ESIdentityCardNumberField, valid, invalid) - - def test_ESCCCField(self): - error_invalid = [u'Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'] - error_checksum = [u'Invalid checksum for bank account number.'] - valid = { - '20770338793100254321': '20770338793100254321', - '2077 0338 79 3100254321': '2077 0338 79 3100254321', - '2077-0338-79-3100254321': '2077-0338-79-3100254321', - } - invalid = { - '2077.0338.79.3100254321': error_invalid, - '2077-0338-78-3100254321': error_checksum, - '2077-0338-89-3100254321': error_checksum, - '2077-03-3879-3100254321': error_invalid, - } - self.assertFieldOutput(ESCCCField, valid, invalid) - - diff --git a/parts/django/tests/regressiontests/forms/localflavor/fi.py b/parts/django/tests/regressiontests/forms/localflavor/fi.py deleted file mode 100644 index 161eb17..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/fi.py +++ /dev/null @@ -1,382 +0,0 @@ -from django.contrib.localflavor.fi.forms import (FIZipCodeField, - FISocialSecurityNumber, FIMunicipalitySelect) - -from utils import LocalFlavorTestCase - - -class FILocalFlavorTests(LocalFlavorTestCase): - def test_FIMunicipalitySelect(self): - f = FIMunicipalitySelect() - out = u'''<select name="municipalities"> -<option value="akaa">Akaa</option> -<option value="alajarvi">Alaj\xe4rvi</option> -<option value="alavieska">Alavieska</option> -<option value="alavus">Alavus</option> -<option value="artjarvi">Artj\xe4rvi</option> -<option value="asikkala">Asikkala</option> -<option value="askola">Askola</option> -<option value="aura">Aura</option> -<option value="brando">Br\xe4nd\xf6</option> -<option value="eckero">Ecker\xf6</option> -<option value="enonkoski">Enonkoski</option> -<option value="enontekio">Enonteki\xf6</option> -<option value="espoo">Espoo</option> -<option value="eura">Eura</option> -<option value="eurajoki">Eurajoki</option> -<option value="evijarvi">Evij\xe4rvi</option> -<option value="finstrom">Finstr\xf6m</option> -<option value="forssa">Forssa</option> -<option value="foglo">F\xf6gl\xf6</option> -<option value="geta">Geta</option> -<option value="haapajarvi">Haapaj\xe4rvi</option> -<option value="haapavesi">Haapavesi</option> -<option value="hailuoto">Hailuoto</option> -<option value="halsua">Halsua</option> -<option value="hamina">Hamina</option> -<option value="hammarland">Hammarland</option> -<option value="hankasalmi">Hankasalmi</option> -<option value="hanko">Hanko</option> -<option value="harjavalta">Harjavalta</option> -<option value="hartola">Hartola</option> -<option value="hattula">Hattula</option> -<option value="haukipudas">Haukipudas</option> -<option value="hausjarvi">Hausj\xe4rvi</option> -<option value="heinola">Heinola</option> -<option value="heinavesi">Hein\xe4vesi</option> -<option value="helsinki">Helsinki</option> -<option value="hirvensalmi">Hirvensalmi</option> -<option value="hollola">Hollola</option> -<option value="honkajoki">Honkajoki</option> -<option value="huittinen">Huittinen</option> -<option value="humppila">Humppila</option> -<option value="hyrynsalmi">Hyrynsalmi</option> -<option value="hyvinkaa">Hyvink\xe4\xe4</option> -<option value="hameenkoski">H\xe4meenkoski</option> -<option value="hameenkyro">H\xe4meenkyr\xf6</option> -<option value="hameenlinna">H\xe4meenlinna</option> -<option value="ii">Ii</option> -<option value="iisalmi">Iisalmi</option> -<option value="iitti">Iitti</option> -<option value="ikaalinen">Ikaalinen</option> -<option value="ilmajoki">Ilmajoki</option> -<option value="ilomantsi">Ilomantsi</option> -<option value="imatra">Imatra</option> -<option value="inari">Inari</option> -<option value="inkoo">Inkoo</option> -<option value="isojoki">Isojoki</option> -<option value="isokyro">Isokyr\xf6</option> -<option value="jalasjarvi">Jalasj\xe4rvi</option> -<option value="janakkala">Janakkala</option> -<option value="joensuu">Joensuu</option> -<option value="jokioinen">Jokioinen</option> -<option value="jomala">Jomala</option> -<option value="joroinen">Joroinen</option> -<option value="joutsa">Joutsa</option> -<option value="juankoski">Juankoski</option> -<option value="juuka">Juuka</option> -<option value="juupajoki">Juupajoki</option> -<option value="juva">Juva</option> -<option value="jyvaskyla">Jyv\xe4skyl\xe4</option> -<option value="jamijarvi">J\xe4mij\xe4rvi</option> -<option value="jamsa">J\xe4ms\xe4</option> -<option value="jarvenpaa">J\xe4rvenp\xe4\xe4</option> -<option value="kaarina">Kaarina</option> -<option value="kaavi">Kaavi</option> -<option value="kajaani">Kajaani</option> -<option value="kalajoki">Kalajoki</option> -<option value="kangasala">Kangasala</option> -<option value="kangasniemi">Kangasniemi</option> -<option value="kankaanpaa">Kankaanp\xe4\xe4</option> -<option value="kannonkoski">Kannonkoski</option> -<option value="kannus">Kannus</option> -<option value="karijoki">Karijoki</option> -<option value="karjalohja">Karjalohja</option> -<option value="karkkila">Karkkila</option> -<option value="karstula">Karstula</option> -<option value="karttula">Karttula</option> -<option value="karvia">Karvia</option> -<option value="kaskinen">Kaskinen</option> -<option value="kauhajoki">Kauhajoki</option> -<option value="kauhava">Kauhava</option> -<option value="kauniainen">Kauniainen</option> -<option value="kaustinen">Kaustinen</option> -<option value="keitele">Keitele</option> -<option value="kemi">Kemi</option> -<option value="kemijarvi">Kemij\xe4rvi</option> -<option value="keminmaa">Keminmaa</option> -<option value="kemionsaari">Kemi\xf6nsaari</option> -<option value="kempele">Kempele</option> -<option value="kerava">Kerava</option> -<option value="kerimaki">Kerim\xe4ki</option> -<option value="kesalahti">Kes\xe4lahti</option> -<option value="keuruu">Keuruu</option> -<option value="kihnio">Kihni\xf6</option> -<option value="kiikoinen">Kiikoinen</option> -<option value="kiiminki">Kiiminki</option> -<option value="kinnula">Kinnula</option> -<option value="kirkkonummi">Kirkkonummi</option> -<option value="kitee">Kitee</option> -<option value="kittila">Kittil\xe4</option> -<option value="kiuruvesi">Kiuruvesi</option> -<option value="kivijarvi">Kivij\xe4rvi</option> -<option value="kokemaki">Kokem\xe4ki</option> -<option value="kokkola">Kokkola</option> -<option value="kolari">Kolari</option> -<option value="konnevesi">Konnevesi</option> -<option value="kontiolahti">Kontiolahti</option> -<option value="korsnas">Korsn\xe4s</option> -<option value="koskitl">Koski Tl</option> -<option value="kotka">Kotka</option> -<option value="kouvola">Kouvola</option> -<option value="kristiinankaupunki">Kristiinankaupunki</option> -<option value="kruunupyy">Kruunupyy</option> -<option value="kuhmalahti">Kuhmalahti</option> -<option value="kuhmo">Kuhmo</option> -<option value="kuhmoinen">Kuhmoinen</option> -<option value="kumlinge">Kumlinge</option> -<option value="kuopio">Kuopio</option> -<option value="kuortane">Kuortane</option> -<option value="kurikka">Kurikka</option> -<option value="kustavi">Kustavi</option> -<option value="kuusamo">Kuusamo</option> -<option value="kylmakoski">Kylm\xe4koski</option> -<option value="kyyjarvi">Kyyj\xe4rvi</option> -<option value="karkola">K\xe4rk\xf6l\xe4</option> -<option value="karsamaki">K\xe4rs\xe4m\xe4ki</option> -<option value="kokar">K\xf6kar</option> -<option value="koylio">K\xf6yli\xf6</option> -<option value="lahti">Lahti</option> -<option value="laihia">Laihia</option> -<option value="laitila">Laitila</option> -<option value="lapinjarvi">Lapinj\xe4rvi</option> -<option value="lapinlahti">Lapinlahti</option> -<option value="lappajarvi">Lappaj\xe4rvi</option> -<option value="lappeenranta">Lappeenranta</option> -<option value="lapua">Lapua</option> -<option value="laukaa">Laukaa</option> -<option value="lavia">Lavia</option> -<option value="lemi">Lemi</option> -<option value="lemland">Lemland</option> -<option value="lempaala">Lemp\xe4\xe4l\xe4</option> -<option value="leppavirta">Lepp\xe4virta</option> -<option value="lestijarvi">Lestij\xe4rvi</option> -<option value="lieksa">Lieksa</option> -<option value="lieto">Lieto</option> -<option value="liminka">Liminka</option> -<option value="liperi">Liperi</option> -<option value="lohja">Lohja</option> -<option value="loimaa">Loimaa</option> -<option value="loppi">Loppi</option> -<option value="loviisa">Loviisa</option> -<option value="luhanka">Luhanka</option> -<option value="lumijoki">Lumijoki</option> -<option value="lumparland">Lumparland</option> -<option value="luoto">Luoto</option> -<option value="luumaki">Luum\xe4ki</option> -<option value="luvia">Luvia</option> -<option value="lansi-turunmaa">L\xe4nsi-Turunmaa</option> -<option value="maalahti">Maalahti</option> -<option value="maaninka">Maaninka</option> -<option value="maarianhamina">Maarianhamina</option> -<option value="marttila">Marttila</option> -<option value="masku">Masku</option> -<option value="merijarvi">Merij\xe4rvi</option> -<option value="merikarvia">Merikarvia</option> -<option value="miehikkala">Miehikk\xe4l\xe4</option> -<option value="mikkeli">Mikkeli</option> -<option value="muhos">Muhos</option> -<option value="multia">Multia</option> -<option value="muonio">Muonio</option> -<option value="mustasaari">Mustasaari</option> -<option value="muurame">Muurame</option> -<option value="mynamaki">Myn\xe4m\xe4ki</option> -<option value="myrskyla">Myrskyl\xe4</option> -<option value="mantsala">M\xe4nts\xe4l\xe4</option> -<option value="mantta-vilppula">M\xe4ntt\xe4-Vilppula</option> -<option value="mantyharju">M\xe4ntyharju</option> -<option value="naantali">Naantali</option> -<option value="nakkila">Nakkila</option> -<option value="nastola">Nastola</option> -<option value="nilsia">Nilsi\xe4</option> -<option value="nivala">Nivala</option> -<option value="nokia">Nokia</option> -<option value="nousiainen">Nousiainen</option> -<option value="nummi-pusula">Nummi-Pusula</option> -<option value="nurmes">Nurmes</option> -<option value="nurmijarvi">Nurmij\xe4rvi</option> -<option value="narpio">N\xe4rpi\xf6</option> -<option value="oravainen">Oravainen</option> -<option value="orimattila">Orimattila</option> -<option value="oripaa">Orip\xe4\xe4</option> -<option value="orivesi">Orivesi</option> -<option value="oulainen">Oulainen</option> -<option value="oulu">Oulu</option> -<option value="oulunsalo">Oulunsalo</option> -<option value="outokumpu">Outokumpu</option> -<option value="padasjoki">Padasjoki</option> -<option value="paimio">Paimio</option> -<option value="paltamo">Paltamo</option> -<option value="parikkala">Parikkala</option> -<option value="parkano">Parkano</option> -<option value="pedersore">Peders\xf6re</option> -<option value="pelkosenniemi">Pelkosenniemi</option> -<option value="pello">Pello</option> -<option value="perho">Perho</option> -<option value="pertunmaa">Pertunmaa</option> -<option value="petajavesi">Pet\xe4j\xe4vesi</option> -<option value="pieksamaki">Pieks\xe4m\xe4ki</option> -<option value="pielavesi">Pielavesi</option> -<option value="pietarsaari">Pietarsaari</option> -<option value="pihtipudas">Pihtipudas</option> -<option value="pirkkala">Pirkkala</option> -<option value="polvijarvi">Polvij\xe4rvi</option> -<option value="pomarkku">Pomarkku</option> -<option value="pori">Pori</option> -<option value="pornainen">Pornainen</option> -<option value="porvoo">Porvoo</option> -<option value="posio">Posio</option> -<option value="pudasjarvi">Pudasj\xe4rvi</option> -<option value="pukkila">Pukkila</option> -<option value="punkaharju">Punkaharju</option> -<option value="punkalaidun">Punkalaidun</option> -<option value="puolanka">Puolanka</option> -<option value="puumala">Puumala</option> -<option value="pyhtaa">Pyht\xe4\xe4</option> -<option value="pyhajoki">Pyh\xe4joki</option> -<option value="pyhajarvi">Pyh\xe4j\xe4rvi</option> -<option value="pyhanta">Pyh\xe4nt\xe4</option> -<option value="pyharanta">Pyh\xe4ranta</option> -<option value="palkane">P\xe4lk\xe4ne</option> -<option value="poytya">P\xf6yty\xe4</option> -<option value="raahe">Raahe</option> -<option value="raasepori">Raasepori</option> -<option value="raisio">Raisio</option> -<option value="rantasalmi">Rantasalmi</option> -<option value="ranua">Ranua</option> -<option value="rauma">Rauma</option> -<option value="rautalampi">Rautalampi</option> -<option value="rautavaara">Rautavaara</option> -<option value="rautjarvi">Rautj\xe4rvi</option> -<option value="reisjarvi">Reisj\xe4rvi</option> -<option value="riihimaki">Riihim\xe4ki</option> -<option value="ristiina">Ristiina</option> -<option value="ristijarvi">Ristij\xe4rvi</option> -<option value="rovaniemi">Rovaniemi</option> -<option value="ruokolahti">Ruokolahti</option> -<option value="ruovesi">Ruovesi</option> -<option value="rusko">Rusko</option> -<option value="raakkyla">R\xe4\xe4kkyl\xe4</option> -<option value="saarijarvi">Saarij\xe4rvi</option> -<option value="salla">Salla</option> -<option value="salo">Salo</option> -<option value="saltvik">Saltvik</option> -<option value="sastamala">Sastamala</option> -<option value="sauvo">Sauvo</option> -<option value="savitaipale">Savitaipale</option> -<option value="savonlinna">Savonlinna</option> -<option value="savukoski">Savukoski</option> -<option value="seinajoki">Sein\xe4joki</option> -<option value="sievi">Sievi</option> -<option value="siikainen">Siikainen</option> -<option value="siikajoki">Siikajoki</option> -<option value="siikalatva">Siikalatva</option> -<option value="siilinjarvi">Siilinj\xe4rvi</option> -<option value="simo">Simo</option> -<option value="sipoo">Sipoo</option> -<option value="siuntio">Siuntio</option> -<option value="sodankyla">Sodankyl\xe4</option> -<option value="soini">Soini</option> -<option value="somero">Somero</option> -<option value="sonkajarvi">Sonkaj\xe4rvi</option> -<option value="sotkamo">Sotkamo</option> -<option value="sottunga">Sottunga</option> -<option value="sulkava">Sulkava</option> -<option value="sund">Sund</option> -<option value="suomenniemi">Suomenniemi</option> -<option value="suomussalmi">Suomussalmi</option> -<option value="suonenjoki">Suonenjoki</option> -<option value="sysma">Sysm\xe4</option> -<option value="sakyla">S\xe4kyl\xe4</option> -<option value="taipalsaari">Taipalsaari</option> -<option value="taivalkoski">Taivalkoski</option> -<option value="taivassalo">Taivassalo</option> -<option value="tammela">Tammela</option> -<option value="tampere">Tampere</option> -<option value="tarvasjoki">Tarvasjoki</option> -<option value="tervo">Tervo</option> -<option value="tervola">Tervola</option> -<option value="teuva">Teuva</option> -<option value="tohmajarvi">Tohmaj\xe4rvi</option> -<option value="toholampi">Toholampi</option> -<option value="toivakka">Toivakka</option> -<option value="tornio">Tornio</option> -<option value="turku" selected="selected">Turku</option> -<option value="tuusniemi">Tuusniemi</option> -<option value="tuusula">Tuusula</option> -<option value="tyrnava">Tyrn\xe4v\xe4</option> -<option value="toysa">T\xf6ys\xe4</option> -<option value="ulvila">Ulvila</option> -<option value="urjala">Urjala</option> -<option value="utajarvi">Utaj\xe4rvi</option> -<option value="utsjoki">Utsjoki</option> -<option value="uurainen">Uurainen</option> -<option value="uusikaarlepyy">Uusikaarlepyy</option> -<option value="uusikaupunki">Uusikaupunki</option> -<option value="vaala">Vaala</option> -<option value="vaasa">Vaasa</option> -<option value="valkeakoski">Valkeakoski</option> -<option value="valtimo">Valtimo</option> -<option value="vantaa">Vantaa</option> -<option value="varkaus">Varkaus</option> -<option value="varpaisjarvi">Varpaisj\xe4rvi</option> -<option value="vehmaa">Vehmaa</option> -<option value="vesanto">Vesanto</option> -<option value="vesilahti">Vesilahti</option> -<option value="veteli">Veteli</option> -<option value="vierema">Vierem\xe4</option> -<option value="vihanti">Vihanti</option> -<option value="vihti">Vihti</option> -<option value="viitasaari">Viitasaari</option> -<option value="vimpeli">Vimpeli</option> -<option value="virolahti">Virolahti</option> -<option value="virrat">Virrat</option> -<option value="vardo">V\xe5rd\xf6</option> -<option value="vahakyro">V\xe4h\xe4kyr\xf6</option> -<option value="voyri-maksamaa">V\xf6yri-Maksamaa</option> -<option value="yli-ii">Yli-Ii</option> -<option value="ylitornio">Ylitornio</option> -<option value="ylivieska">Ylivieska</option> -<option value="ylojarvi">Yl\xf6j\xe4rvi</option> -<option value="ypaja">Yp\xe4j\xe4</option> -<option value="ahtari">\xc4ht\xe4ri</option> -<option value="aanekoski">\xc4\xe4nekoski</option> -</select>''' - self.assertEquals(f.render('municipalities', 'turku'), out) - - def test_FIZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXXX.'] - valid = { - '20540': '20540', - '20101': '20101', - } - invalid = { - '20s40': error_format, - '205401': error_format - } - self.assertFieldOutput(FIZipCodeField, valid, invalid) - - def test_FISocialSecurityNumber(self): - error_invalid = [u'Enter a valid Finnish social security number.'] - valid = { - '010101-0101': '010101-0101', - '010101+0101': '010101+0101', - '010101A0101': '010101A0101', - } - invalid = { - '101010-0102': error_invalid, - '10a010-0101': error_invalid, - '101010-0\xe401': error_invalid, - '101010b0101': error_invalid, - } - self.assertFieldOutput(FISocialSecurityNumber, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/fr.py b/parts/django/tests/regressiontests/forms/localflavor/fr.py deleted file mode 100644 index 96045c3..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/fr.py +++ /dev/null @@ -1,145 +0,0 @@ -from django.contrib.localflavor.fr.forms import (FRZipCodeField, - FRPhoneNumberField, FRDepartmentSelect) - -from utils import LocalFlavorTestCase - - -class FRLocalFlavorTests(LocalFlavorTestCase): - def test_FRZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXXX.'] - valid = { - '75001': '75001', - '93200': '93200', - } - invalid = { - '2A200': error_format, - '980001': error_format, - } - self.assertFieldOutput(FRZipCodeField, valid, invalid) - - def test_FRPhoneNumberField(self): - error_format = [u'Phone numbers must be in 0X XX XX XX XX format.'] - valid = { - '01 55 44 58 64': '01 55 44 58 64', - '0155445864': '01 55 44 58 64', - '01 5544 5864': '01 55 44 58 64', - '01 55.44.58.64': '01 55 44 58 64', - '01.55.44.58.64': '01 55 44 58 64', - } - invalid = { - '01,55,44,58,64': error_format, - '555 015 544': error_format, - } - self.assertFieldOutput(FRPhoneNumberField, valid, invalid) - - def test_FRDepartmentSelect(self): - f = FRDepartmentSelect() - out = u'''<select name="dep"> -<option value="01">01 - Ain</option> -<option value="02">02 - Aisne</option> -<option value="03">03 - Allier</option> -<option value="04">04 - Alpes-de-Haute-Provence</option> -<option value="05">05 - Hautes-Alpes</option> -<option value="06">06 - Alpes-Maritimes</option> -<option value="07">07 - Ardeche</option> -<option value="08">08 - Ardennes</option> -<option value="09">09 - Ariege</option> -<option value="10">10 - Aube</option> -<option value="11">11 - Aude</option> -<option value="12">12 - Aveyron</option> -<option value="13">13 - Bouches-du-Rhone</option> -<option value="14">14 - Calvados</option> -<option value="15">15 - Cantal</option> -<option value="16">16 - Charente</option> -<option value="17">17 - Charente-Maritime</option> -<option value="18">18 - Cher</option> -<option value="19">19 - Correze</option> -<option value="21">21 - Cote-d'Or</option> -<option value="22">22 - Cotes-d'Armor</option> -<option value="23">23 - Creuse</option> -<option value="24">24 - Dordogne</option> -<option value="25">25 - Doubs</option> -<option value="26">26 - Drome</option> -<option value="27">27 - Eure</option> -<option value="28">28 - Eure-et-Loire</option> -<option value="29">29 - Finistere</option> -<option value="2A">2A - Corse-du-Sud</option> -<option value="2B">2B - Haute-Corse</option> -<option value="30">30 - Gard</option> -<option value="31">31 - Haute-Garonne</option> -<option value="32">32 - Gers</option> -<option value="33">33 - Gironde</option> -<option value="34">34 - Herault</option> -<option value="35">35 - Ille-et-Vilaine</option> -<option value="36">36 - Indre</option> -<option value="37">37 - Indre-et-Loire</option> -<option value="38">38 - Isere</option> -<option value="39">39 - Jura</option> -<option value="40">40 - Landes</option> -<option value="41">41 - Loir-et-Cher</option> -<option value="42">42 - Loire</option> -<option value="43">43 - Haute-Loire</option> -<option value="44">44 - Loire-Atlantique</option> -<option value="45">45 - Loiret</option> -<option value="46">46 - Lot</option> -<option value="47">47 - Lot-et-Garonne</option> -<option value="48">48 - Lozere</option> -<option value="49">49 - Maine-et-Loire</option> -<option value="50">50 - Manche</option> -<option value="51">51 - Marne</option> -<option value="52">52 - Haute-Marne</option> -<option value="53">53 - Mayenne</option> -<option value="54">54 - Meurthe-et-Moselle</option> -<option value="55">55 - Meuse</option> -<option value="56">56 - Morbihan</option> -<option value="57">57 - Moselle</option> -<option value="58">58 - Nievre</option> -<option value="59">59 - Nord</option> -<option value="60">60 - Oise</option> -<option value="61">61 - Orne</option> -<option value="62">62 - Pas-de-Calais</option> -<option value="63">63 - Puy-de-Dome</option> -<option value="64">64 - Pyrenees-Atlantiques</option> -<option value="65">65 - Hautes-Pyrenees</option> -<option value="66">66 - Pyrenees-Orientales</option> -<option value="67">67 - Bas-Rhin</option> -<option value="68">68 - Haut-Rhin</option> -<option value="69">69 - Rhone</option> -<option value="70">70 - Haute-Saone</option> -<option value="71">71 - Saone-et-Loire</option> -<option value="72">72 - Sarthe</option> -<option value="73">73 - Savoie</option> -<option value="74">74 - Haute-Savoie</option> -<option value="75">75 - Paris</option> -<option value="76">76 - Seine-Maritime</option> -<option value="77">77 - Seine-et-Marne</option> -<option value="78">78 - Yvelines</option> -<option value="79">79 - Deux-Sevres</option> -<option value="80">80 - Somme</option> -<option value="81">81 - Tarn</option> -<option value="82">82 - Tarn-et-Garonne</option> -<option value="83">83 - Var</option> -<option value="84">84 - Vaucluse</option> -<option value="85">85 - Vendee</option> -<option value="86">86 - Vienne</option> -<option value="87">87 - Haute-Vienne</option> -<option value="88">88 - Vosges</option> -<option value="89">89 - Yonne</option> -<option value="90">90 - Territoire de Belfort</option> -<option value="91">91 - Essonne</option> -<option value="92">92 - Hauts-de-Seine</option> -<option value="93">93 - Seine-Saint-Denis</option> -<option value="94">94 - Val-de-Marne</option> -<option value="95">95 - Val-d'Oise</option> -<option value="971">971 - Guadeloupe</option> -<option value="972">972 - Martinique</option> -<option value="973">973 - Guyane</option> -<option value="974">974 - La Reunion</option> -<option value="975">975 - Saint-Pierre-et-Miquelon</option> -<option value="976">976 - Mayotte</option> -<option value="984">984 - Terres Australes et Antarctiques</option> -<option value="986">986 - Wallis et Futuna</option> -<option value="987">987 - Polynesie Francaise</option> -<option value="988">988 - Nouvelle-Caledonie</option> -</select>''' - self.assertEqual(f.render('dep', 'Paris'), out) diff --git a/parts/django/tests/regressiontests/forms/localflavor/generic.py b/parts/django/tests/regressiontests/forms/localflavor/generic.py deleted file mode 100644 index f47fc91..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/generic.py +++ /dev/null @@ -1,88 +0,0 @@ -import datetime - -from django.contrib.localflavor.generic.forms import DateField, DateTimeField - -from utils import LocalFlavorTestCase - - -class GenericLocalFlavorTests(LocalFlavorTestCase): - def test_GenericDateField(self): - error_invalid = [u'Enter a valid date.'] - valid = { - datetime.date(2006, 10, 25): datetime.date(2006, 10, 25), - datetime.datetime(2006, 10, 25, 14, 30): datetime.date(2006, 10, 25), - datetime.datetime(2006, 10, 25, 14, 30, 59): datetime.date(2006, 10, 25), - datetime.datetime(2006, 10, 25, 14, 30, 59, 200): datetime.date(2006, 10, 25), - '2006-10-25': datetime.date(2006, 10, 25), - '25/10/2006': datetime.date(2006, 10, 25), - '25/10/06': datetime.date(2006, 10, 25), - 'Oct 25 2006': datetime.date(2006, 10, 25), - 'October 25 2006': datetime.date(2006, 10, 25), - 'October 25, 2006': datetime.date(2006, 10, 25), - '25 October 2006': datetime.date(2006, 10, 25), - '25 October, 2006': datetime.date(2006, 10, 25), - } - invalid = { - '2006-4-31': error_invalid, - '200a-10-25': error_invalid, - '10/25/06': error_invalid, - } - self.assertFieldOutput(DateField, valid, invalid, empty_value=None) - - # DateField with optional input_formats parameter - valid = { - datetime.date(2006, 10, 25): datetime.date(2006, 10, 25), - datetime.datetime(2006, 10, 25, 14, 30): datetime.date(2006, 10, 25), - '2006 10 25': datetime.date(2006, 10, 25), - } - invalid = { - '2006-10-25': error_invalid, - '25/10/2006': error_invalid, - '25/10/06': error_invalid, - } - kwargs = {'input_formats':['%Y %m %d'],} - self.assertFieldOutput(DateField, - valid, invalid, field_kwargs=kwargs, empty_value=None - ) - - def test_GenericDateTimeField(self): - error_invalid = [u'Enter a valid date/time.'] - valid = { - datetime.date(2006, 10, 25): datetime.datetime(2006, 10, 25, 0, 0), - datetime.datetime(2006, 10, 25, 14, 30): datetime.datetime(2006, 10, 25, 14, 30), - datetime.datetime(2006, 10, 25, 14, 30, 59): datetime.datetime(2006, 10, 25, 14, 30, 59), - datetime.datetime(2006, 10, 25, 14, 30, 59, 200): datetime.datetime(2006, 10, 25, 14, 30, 59, 200), - '2006-10-25 14:30:45': datetime.datetime(2006, 10, 25, 14, 30, 45), - '2006-10-25 14:30:00': datetime.datetime(2006, 10, 25, 14, 30), - '2006-10-25 14:30': datetime.datetime(2006, 10, 25, 14, 30), - '2006-10-25': datetime.datetime(2006, 10, 25, 0, 0), - '25/10/2006 14:30:45': datetime.datetime(2006, 10, 25, 14, 30, 45), - '25/10/2006 14:30:00': datetime.datetime(2006, 10, 25, 14, 30), - '25/10/2006 14:30': datetime.datetime(2006, 10, 25, 14, 30), - '25/10/2006': datetime.datetime(2006, 10, 25, 0, 0), - '25/10/06 14:30:45': datetime.datetime(2006, 10, 25, 14, 30, 45), - '25/10/06 14:30:00': datetime.datetime(2006, 10, 25, 14, 30), - '25/10/06 14:30': datetime.datetime(2006, 10, 25, 14, 30), - '25/10/06': datetime.datetime(2006, 10, 25, 0, 0), - } - invalid = { - 'hello': error_invalid, - '2006-10-25 4:30 p.m.': error_invalid, - } - self.assertFieldOutput(DateTimeField, valid, invalid, empty_value=None) - - # DateTimeField with optional input_formats paramter - valid = { - datetime.date(2006, 10, 25): datetime.datetime(2006, 10, 25, 0, 0), - datetime.datetime(2006, 10, 25, 14, 30): datetime.datetime(2006, 10, 25, 14, 30), - datetime.datetime(2006, 10, 25, 14, 30, 59): datetime.datetime(2006, 10, 25, 14, 30, 59), - datetime.datetime(2006, 10, 25, 14, 30, 59, 200): datetime.datetime(2006, 10, 25, 14, 30, 59, 200), - '2006 10 25 2:30 PM': datetime.datetime(2006, 10, 25, 14, 30), - } - invalid = { - '2006-10-25 14:30:45': error_invalid, - } - kwargs = {'input_formats':['%Y %m %d %I:%M %p'],} - self.assertFieldOutput(DateTimeField, - valid, invalid, field_kwargs=kwargs, empty_value=None - ) diff --git a/parts/django/tests/regressiontests/forms/localflavor/id.py b/parts/django/tests/regressiontests/forms/localflavor/id.py deleted file mode 100644 index cb346ef..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/id.py +++ /dev/null @@ -1,181 +0,0 @@ -from django.contrib.localflavor.id.forms import (IDPhoneNumberField, - IDPostCodeField, IDNationalIdentityNumberField, IDLicensePlateField, - IDProvinceSelect, IDLicensePlatePrefixSelect) - -from utils import LocalFlavorTestCase - - -class IDLocalFlavorTests(LocalFlavorTestCase): - def test_IDProvinceSelect(self): - f = IDProvinceSelect() - out = u'''<select name="provinces"> -<option value="BLI">Bali</option> -<option value="BTN">Banten</option> -<option value="BKL">Bengkulu</option> -<option value="DIY">Yogyakarta</option> -<option value="JKT">Jakarta</option> -<option value="GOR">Gorontalo</option> -<option value="JMB">Jambi</option> -<option value="JBR">Jawa Barat</option> -<option value="JTG">Jawa Tengah</option> -<option value="JTM">Jawa Timur</option> -<option value="KBR">Kalimantan Barat</option> -<option value="KSL">Kalimantan Selatan</option> -<option value="KTG">Kalimantan Tengah</option> -<option value="KTM">Kalimantan Timur</option> -<option value="BBL">Kepulauan Bangka-Belitung</option> -<option value="KRI">Kepulauan Riau</option> -<option value="LPG" selected="selected">Lampung</option> -<option value="MLK">Maluku</option> -<option value="MUT">Maluku Utara</option> -<option value="NAD">Nanggroe Aceh Darussalam</option> -<option value="NTB">Nusa Tenggara Barat</option> -<option value="NTT">Nusa Tenggara Timur</option> -<option value="PPA">Papua</option> -<option value="PPB">Papua Barat</option> -<option value="RIU">Riau</option> -<option value="SLB">Sulawesi Barat</option> -<option value="SLS">Sulawesi Selatan</option> -<option value="SLT">Sulawesi Tengah</option> -<option value="SLR">Sulawesi Tenggara</option> -<option value="SLU">Sulawesi Utara</option> -<option value="SMB">Sumatera Barat</option> -<option value="SMS">Sumatera Selatan</option> -<option value="SMU">Sumatera Utara</option> -</select>''' - self.assertEqual(f.render('provinces', 'LPG'), out) - - def test_IDLicensePlatePrefixSelect(self): - f = IDLicensePlatePrefixSelect() - out = u'''<select name="codes"> -<option value="A">Banten</option> -<option value="AA">Magelang</option> -<option value="AB">Yogyakarta</option> -<option value="AD">Surakarta - Solo</option> -<option value="AE">Madiun</option> -<option value="AG">Kediri</option> -<option value="B">Jakarta</option> -<option value="BA">Sumatera Barat</option> -<option value="BB">Tapanuli</option> -<option value="BD">Bengkulu</option> -<option value="BE" selected="selected">Lampung</option> -<option value="BG">Sumatera Selatan</option> -<option value="BH">Jambi</option> -<option value="BK">Sumatera Utara</option> -<option value="BL">Nanggroe Aceh Darussalam</option> -<option value="BM">Riau</option> -<option value="BN">Kepulauan Bangka Belitung</option> -<option value="BP">Kepulauan Riau</option> -<option value="CC">Corps Consulate</option> -<option value="CD">Corps Diplomatic</option> -<option value="D">Bandung</option> -<option value="DA">Kalimantan Selatan</option> -<option value="DB">Sulawesi Utara Daratan</option> -<option value="DC">Sulawesi Barat</option> -<option value="DD">Sulawesi Selatan</option> -<option value="DE">Maluku</option> -<option value="DG">Maluku Utara</option> -<option value="DH">NTT - Timor</option> -<option value="DK">Bali</option> -<option value="DL">Sulawesi Utara Kepulauan</option> -<option value="DM">Gorontalo</option> -<option value="DN">Sulawesi Tengah</option> -<option value="DR">NTB - Lombok</option> -<option value="DS">Papua dan Papua Barat</option> -<option value="DT">Sulawesi Tenggara</option> -<option value="E">Cirebon</option> -<option value="EA">NTB - Sumbawa</option> -<option value="EB">NTT - Flores</option> -<option value="ED">NTT - Sumba</option> -<option value="F">Bogor</option> -<option value="G">Pekalongan</option> -<option value="H">Semarang</option> -<option value="K">Pati</option> -<option value="KB">Kalimantan Barat</option> -<option value="KH">Kalimantan Tengah</option> -<option value="KT">Kalimantan Timur</option> -<option value="L">Surabaya</option> -<option value="M">Madura</option> -<option value="N">Malang</option> -<option value="P">Jember</option> -<option value="R">Banyumas</option> -<option value="RI">Federal Government</option> -<option value="S">Bojonegoro</option> -<option value="T">Purwakarta</option> -<option value="W">Sidoarjo</option> -<option value="Z">Garut</option> -</select>''' - self.assertEqual(f.render('codes', 'BE'), out) - - def test_IDPhoneNumberField(self): - error_invalid = [u'Enter a valid phone number'] - valid = { - '0812-3456789': u'0812-3456789', - '081234567890': u'081234567890', - '021 345 6789': u'021 345 6789', - '0213456789': u'0213456789', - '+62-21-3456789': u'+62-21-3456789', - '(021) 345 6789': u'(021) 345 6789', - } - invalid = { - '0123456789': error_invalid, - '+62-021-3456789': error_invalid, - '+62-021-3456789': error_invalid, - '+62-0812-3456789': error_invalid, - '0812345678901': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(IDPhoneNumberField, valid, invalid) - - def test_IDPostCodeField(self): - error_invalid = [u'Enter a valid post code'] - valid = { - '12340': u'12340', - '25412': u'25412', - ' 12340 ': u'12340', - } - invalid = { - '12 3 4 0': error_invalid, - '12345': error_invalid, - '10100': error_invalid, - '123456': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(IDPostCodeField, valid, invalid) - - def test_IDNationalIdentityNumberField(self): - error_invalid = [u'Enter a valid NIK/KTP number'] - valid = { - ' 12.3456.010178 3456 ': u'12.3456.010178.3456', - '1234560101783456': u'12.3456.010178.3456', - '12.3456.010101.3456': u'12.3456.010101.3456', - } - invalid = { - '12.3456.310278.3456': error_invalid, - '00.0000.010101.0000': error_invalid, - '1234567890123456': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(IDNationalIdentityNumberField, valid, invalid) - - def test_IDLicensePlateField(self): - error_invalid = [u'Enter a valid vehicle license plate number'] - valid = { - ' b 1234 ab ': u'B 1234 AB', - 'B 1234 ABC': u'B 1234 ABC', - 'A 12': u'A 12', - 'DK 12345 12': u'DK 12345 12', - 'RI 10': u'RI 10', - 'CD 12 12': u'CD 12 12', - } - invalid = { - 'CD 10 12': error_invalid, - 'CD 1234 12': error_invalid, - 'RI 10 AB': error_invalid, - 'B 12345 01': error_invalid, - 'N 1234 12': error_invalid, - 'A 12 XYZ': error_invalid, - 'Q 1234 AB': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(IDLicensePlateField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/ie.py b/parts/django/tests/regressiontests/forms/localflavor/ie.py deleted file mode 100644 index fab519b..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/ie.py +++ /dev/null @@ -1,43 +0,0 @@ -from django.contrib.localflavor.ie.forms import IECountySelect - -from utils import LocalFlavorTestCase - - -class IELocalFlavorTests(LocalFlavorTestCase): - def test_IECountySelect(self): - f = IECountySelect() - out = u'''<select name="counties"> -<option value="antrim">Antrim</option> -<option value="armagh">Armagh</option> -<option value="carlow">Carlow</option> -<option value="cavan">Cavan</option> -<option value="clare">Clare</option> -<option value="cork">Cork</option> -<option value="derry">Derry</option> -<option value="donegal">Donegal</option> -<option value="down">Down</option> -<option value="dublin" selected="selected">Dublin</option> -<option value="fermanagh">Fermanagh</option> -<option value="galway">Galway</option> -<option value="kerry">Kerry</option> -<option value="kildare">Kildare</option> -<option value="kilkenny">Kilkenny</option> -<option value="laois">Laois</option> -<option value="leitrim">Leitrim</option> -<option value="limerick">Limerick</option> -<option value="longford">Longford</option> -<option value="louth">Louth</option> -<option value="mayo">Mayo</option> -<option value="meath">Meath</option> -<option value="monaghan">Monaghan</option> -<option value="offaly">Offaly</option> -<option value="roscommon">Roscommon</option> -<option value="sligo">Sligo</option> -<option value="tipperary">Tipperary</option> -<option value="tyrone">Tyrone</option> -<option value="waterford">Waterford</option> -<option value="westmeath">Westmeath</option> -<option value="wexford">Wexford</option> -<option value="wicklow">Wicklow</option> -</select>''' - self.assertEqual(f.render('counties', 'dublin'), out) diff --git a/parts/django/tests/regressiontests/forms/localflavor/is_.py b/parts/django/tests/regressiontests/forms/localflavor/is_.py deleted file mode 100644 index fa6b133..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/is_.py +++ /dev/null @@ -1,199 +0,0 @@ -from django.contrib.localflavor.is_.forms import (ISIdNumberField, - ISPhoneNumberField, ISPostalCodeSelect) - -from utils import LocalFlavorTestCase - - -class ISLocalFlavorTests(LocalFlavorTestCase): - def test_ISPostalCodeSelect(self): - f = ISPostalCodeSelect() - out = u'''<select name="foo"> -<option value="101">101 Reykjav\xedk</option> -<option value="103">103 Reykjav\xedk</option> -<option value="104">104 Reykjav\xedk</option> -<option value="105">105 Reykjav\xedk</option> -<option value="107">107 Reykjav\xedk</option> -<option value="108">108 Reykjav\xedk</option> -<option value="109">109 Reykjav\xedk</option> -<option value="110">110 Reykjav\xedk</option> -<option value="111">111 Reykjav\xedk</option> -<option value="112">112 Reykjav\xedk</option> -<option value="113">113 Reykjav\xedk</option> -<option value="116">116 Kjalarnes</option> -<option value="121">121 Reykjav\xedk</option> -<option value="123">123 Reykjav\xedk</option> -<option value="124">124 Reykjav\xedk</option> -<option value="125">125 Reykjav\xedk</option> -<option value="127">127 Reykjav\xedk</option> -<option value="128">128 Reykjav\xedk</option> -<option value="129">129 Reykjav\xedk</option> -<option value="130">130 Reykjav\xedk</option> -<option value="132">132 Reykjav\xedk</option> -<option value="150">150 Reykjav\xedk</option> -<option value="155">155 Reykjav\xedk</option> -<option value="170">170 Seltjarnarnes</option> -<option value="172">172 Seltjarnarnes</option> -<option value="190">190 Vogar</option> -<option value="200">200 K\xf3pavogur</option> -<option value="201">201 K\xf3pavogur</option> -<option value="202">202 K\xf3pavogur</option> -<option value="203">203 K\xf3pavogur</option> -<option value="210">210 Gar\xf0ab\xe6r</option> -<option value="212">212 Gar\xf0ab\xe6r</option> -<option value="220">220 Hafnarfj\xf6r\xf0ur</option> -<option value="221">221 Hafnarfj\xf6r\xf0ur</option> -<option value="222">222 Hafnarfj\xf6r\xf0ur</option> -<option value="225">225 \xc1lftanes</option> -<option value="230">230 Reykjanesb\xe6r</option> -<option value="232">232 Reykjanesb\xe6r</option> -<option value="233">233 Reykjanesb\xe6r</option> -<option value="235">235 Keflav\xedkurflugv\xf6llur</option> -<option value="240">240 Grindav\xedk</option> -<option value="245">245 Sandger\xf0i</option> -<option value="250">250 Gar\xf0ur</option> -<option value="260">260 Reykjanesb\xe6r</option> -<option value="270">270 Mosfellsb\xe6r</option> -<option value="300">300 Akranes</option> -<option value="301">301 Akranes</option> -<option value="302">302 Akranes</option> -<option value="310">310 Borgarnes</option> -<option value="311">311 Borgarnes</option> -<option value="320">320 Reykholt \xed Borgarfir\xf0i</option> -<option value="340">340 Stykkish\xf3lmur</option> -<option value="345">345 Flatey \xe1 Brei\xf0afir\xf0i</option> -<option value="350">350 Grundarfj\xf6r\xf0ur</option> -<option value="355">355 \xd3lafsv\xedk</option> -<option value="356">356 Sn\xe6fellsb\xe6r</option> -<option value="360">360 Hellissandur</option> -<option value="370">370 B\xfa\xf0ardalur</option> -<option value="371">371 B\xfa\xf0ardalur</option> -<option value="380">380 Reykh\xf3lahreppur</option> -<option value="400">400 \xcdsafj\xf6r\xf0ur</option> -<option value="401">401 \xcdsafj\xf6r\xf0ur</option> -<option value="410">410 Hn\xedfsdalur</option> -<option value="415">415 Bolungarv\xedk</option> -<option value="420">420 S\xfa\xf0av\xedk</option> -<option value="425">425 Flateyri</option> -<option value="430">430 Su\xf0ureyri</option> -<option value="450">450 Patreksfj\xf6r\xf0ur</option> -<option value="451">451 Patreksfj\xf6r\xf0ur</option> -<option value="460">460 T\xe1lknafj\xf6r\xf0ur</option> -<option value="465">465 B\xedldudalur</option> -<option value="470">470 \xdeingeyri</option> -<option value="471">471 \xdeingeyri</option> -<option value="500">500 Sta\xf0ur</option> -<option value="510">510 H\xf3lmav\xedk</option> -<option value="512">512 H\xf3lmav\xedk</option> -<option value="520">520 Drangsnes</option> -<option value="522">522 Kj\xf6rvogur</option> -<option value="523">523 B\xe6r</option> -<option value="524">524 Nor\xf0urfj\xf6r\xf0ur</option> -<option value="530">530 Hvammstangi</option> -<option value="531">531 Hvammstangi</option> -<option value="540">540 Bl\xf6ndu\xf3s</option> -<option value="541">541 Bl\xf6ndu\xf3s</option> -<option value="545">545 Skagastr\xf6nd</option> -<option value="550">550 Sau\xf0\xe1rkr\xf3kur</option> -<option value="551">551 Sau\xf0\xe1rkr\xf3kur</option> -<option value="560">560 Varmahl\xed\xf0</option> -<option value="565">565 Hofs\xf3s</option> -<option value="566">566 Hofs\xf3s</option> -<option value="570">570 Flj\xf3t</option> -<option value="580">580 Siglufj\xf6r\xf0ur</option> -<option value="600">600 Akureyri</option> -<option value="601">601 Akureyri</option> -<option value="602">602 Akureyri</option> -<option value="603">603 Akureyri</option> -<option value="610">610 Greniv\xedk</option> -<option value="611">611 Gr\xedmsey</option> -<option value="620">620 Dalv\xedk</option> -<option value="621">621 Dalv\xedk</option> -<option value="625">625 \xd3lafsfj\xf6r\xf0ur</option> -<option value="630">630 Hr\xedsey</option> -<option value="640">640 H\xfasav\xedk</option> -<option value="641">641 H\xfasav\xedk</option> -<option value="645">645 Fossh\xf3ll</option> -<option value="650">650 Laugar</option> -<option value="660">660 M\xfdvatn</option> -<option value="670">670 K\xf3pasker</option> -<option value="671">671 K\xf3pasker</option> -<option value="675">675 Raufarh\xf6fn</option> -<option value="680">680 \xde\xf3rsh\xf6fn</option> -<option value="681">681 \xde\xf3rsh\xf6fn</option> -<option value="685">685 Bakkafj\xf6r\xf0ur</option> -<option value="690">690 Vopnafj\xf6r\xf0ur</option> -<option value="700">700 Egilssta\xf0ir</option> -<option value="701">701 Egilssta\xf0ir</option> -<option value="710">710 Sey\xf0isfj\xf6r\xf0ur</option> -<option value="715">715 Mj\xf3ifj\xf6r\xf0ur</option> -<option value="720">720 Borgarfj\xf6r\xf0ur eystri</option> -<option value="730">730 Rey\xf0arfj\xf6r\xf0ur</option> -<option value="735">735 Eskifj\xf6r\xf0ur</option> -<option value="740">740 Neskaupsta\xf0ur</option> -<option value="750">750 F\xe1skr\xfa\xf0sfj\xf6r\xf0ur</option> -<option value="755">755 St\xf6\xf0varfj\xf6r\xf0ur</option> -<option value="760">760 Brei\xf0dalsv\xedk</option> -<option value="765">765 Dj\xfapivogur</option> -<option value="780">780 H\xf6fn \xed Hornafir\xf0i</option> -<option value="781">781 H\xf6fn \xed Hornafir\xf0i</option> -<option value="785">785 \xd6r\xe6fi</option> -<option value="800">800 Selfoss</option> -<option value="801">801 Selfoss</option> -<option value="802">802 Selfoss</option> -<option value="810">810 Hverager\xf0i</option> -<option value="815">815 \xdeorl\xe1ksh\xf6fn</option> -<option value="820">820 Eyrarbakki</option> -<option value="825">825 Stokkseyri</option> -<option value="840">840 Laugarvatn</option> -<option value="845">845 Fl\xfa\xf0ir</option> -<option value="850">850 Hella</option> -<option value="851">851 Hella</option> -<option value="860">860 Hvolsv\xf6llur</option> -<option value="861">861 Hvolsv\xf6llur</option> -<option value="870">870 V\xedk</option> -<option value="871">871 V\xedk</option> -<option value="880">880 Kirkjub\xe6jarklaustur</option> -<option value="900">900 Vestmannaeyjar</option> -<option value="902">902 Vestmannaeyjar</option> -</select>''' - self.assertEqual(f.render('foo', 'bar'), out) - - def test_ISIdNumberField(self): - error_atleast = [u'Ensure this value has at least 10 characters (it has 9).'] - error_invalid = [u'Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.'] - error_atmost = [u'Ensure this value has at most 11 characters (it has 12).'] - error_notvalid = [u'The Icelandic identification number is not valid.'] - valid = { - '2308803449': '230880-3449', - '230880-3449': '230880-3449', - '230880 3449': '230880-3449', - '2308803440': '230880-3440', - } - invalid = { - '230880343': error_atleast + error_invalid, - '230880343234': error_atmost + error_invalid, - 'abcdefghijk': error_invalid, - '2308803439': error_notvalid, - - } - self.assertFieldOutput(ISIdNumberField, valid, invalid) - - def test_ISPhoneNumberField(self): - error_invalid = [u'Enter a valid value.'] - error_atleast = [u'Ensure this value has at least 7 characters (it has 6).'] - error_atmost = [u'Ensure this value has at most 8 characters (it has 9).'] - valid = { - '1234567': '1234567', - '123 4567': '1234567', - '123-4567': '1234567', - } - invalid = { - '123-456': error_invalid, - '123456': error_atleast + error_invalid, - '123456555': error_atmost + error_invalid, - 'abcdefg': error_invalid, - ' 1234567 ': error_atmost + error_invalid, - ' 12367 ': error_invalid - } - self.assertFieldOutput(ISPhoneNumberField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/it.py b/parts/django/tests/regressiontests/forms/localflavor/it.py deleted file mode 100644 index 7181e25..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/it.py +++ /dev/null @@ -1,70 +0,0 @@ -from django.contrib.localflavor.it.forms import (ITZipCodeField, ITRegionSelect, - ITSocialSecurityNumberField, ITVatNumberField) - -from utils import LocalFlavorTestCase - - -class ITLocalFlavorTests(LocalFlavorTestCase): - def test_ITRegionSelect(self): - f = ITRegionSelect() - out = u'''<select name="regions"> -<option value="ABR">Abruzzo</option> -<option value="BAS">Basilicata</option> -<option value="CAL">Calabria</option> -<option value="CAM">Campania</option> -<option value="EMR">Emilia-Romagna</option> -<option value="FVG">Friuli-Venezia Giulia</option> -<option value="LAZ">Lazio</option> -<option value="LIG">Liguria</option> -<option value="LOM">Lombardia</option> -<option value="MAR">Marche</option> -<option value="MOL">Molise</option> -<option value="PMN" selected="selected">Piemonte</option> -<option value="PUG">Puglia</option> -<option value="SAR">Sardegna</option> -<option value="SIC">Sicilia</option> -<option value="TOS">Toscana</option> -<option value="TAA">Trentino-Alto Adige</option> -<option value="UMB">Umbria</option> -<option value="VAO">Valle d\u2019Aosta</option> -<option value="VEN">Veneto</option> -</select>''' - self.assertEqual(f.render('regions', 'PMN'), out) - - def test_ITZipCodeField(self): - error_invalid = [u'Enter a valid zip code.'] - valid = { - '00100': '00100', - } - invalid = { - ' 00100': error_invalid, - } - self.assertFieldOutput(ITZipCodeField, valid, invalid) - - def test_ITSocialSecurityNumberField(self): - error_invalid = [u'Enter a valid Social Security number.'] - valid = { - 'LVSGDU99T71H501L': 'LVSGDU99T71H501L', - 'LBRRME11A01L736W': 'LBRRME11A01L736W', - 'lbrrme11a01l736w': 'LBRRME11A01L736W', - 'LBR RME 11A01 L736W': 'LBRRME11A01L736W', - } - invalid = { - 'LBRRME11A01L736A': error_invalid, - '%BRRME11A01L736W': error_invalid, - } - self.assertFieldOutput(ITSocialSecurityNumberField, valid, invalid) - - def test_ITVatNumberField(self): - error_invalid = [u'Enter a valid VAT number.'] - valid = { - '07973780013': '07973780013', - '7973780013': '07973780013', - 7973780013: '07973780013', - } - invalid = { - '07973780014': error_invalid, - 'A7973780013': error_invalid, - } - self.assertFieldOutput(ITVatNumberField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/jp.py b/parts/django/tests/regressiontests/forms/localflavor/jp.py deleted file mode 100644 index 1f8362a..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/jp.py +++ /dev/null @@ -1,73 +0,0 @@ -from django.contrib.localflavor.jp.forms import (JPPostalCodeField, - JPPrefectureSelect) - -from utils import LocalFlavorTestCase - - -class JPLocalFlavorTests(LocalFlavorTestCase): - def test_JPPrefectureSelect(self): - f = JPPrefectureSelect() - out = u'''<select name="prefecture"> -<option value="hokkaido">Hokkaido</option> -<option value="aomori">Aomori</option> -<option value="iwate">Iwate</option> -<option value="miyagi">Miyagi</option> -<option value="akita">Akita</option> -<option value="yamagata">Yamagata</option> -<option value="fukushima">Fukushima</option> -<option value="ibaraki">Ibaraki</option> -<option value="tochigi">Tochigi</option> -<option value="gunma">Gunma</option> -<option value="saitama">Saitama</option> -<option value="chiba">Chiba</option> -<option value="tokyo">Tokyo</option> -<option value="kanagawa" selected="selected">Kanagawa</option> -<option value="yamanashi">Yamanashi</option> -<option value="nagano">Nagano</option> -<option value="niigata">Niigata</option> -<option value="toyama">Toyama</option> -<option value="ishikawa">Ishikawa</option> -<option value="fukui">Fukui</option> -<option value="gifu">Gifu</option> -<option value="shizuoka">Shizuoka</option> -<option value="aichi">Aichi</option> -<option value="mie">Mie</option> -<option value="shiga">Shiga</option> -<option value="kyoto">Kyoto</option> -<option value="osaka">Osaka</option> -<option value="hyogo">Hyogo</option> -<option value="nara">Nara</option> -<option value="wakayama">Wakayama</option> -<option value="tottori">Tottori</option> -<option value="shimane">Shimane</option> -<option value="okayama">Okayama</option> -<option value="hiroshima">Hiroshima</option> -<option value="yamaguchi">Yamaguchi</option> -<option value="tokushima">Tokushima</option> -<option value="kagawa">Kagawa</option> -<option value="ehime">Ehime</option> -<option value="kochi">Kochi</option> -<option value="fukuoka">Fukuoka</option> -<option value="saga">Saga</option> -<option value="nagasaki">Nagasaki</option> -<option value="kumamoto">Kumamoto</option> -<option value="oita">Oita</option> -<option value="miyazaki">Miyazaki</option> -<option value="kagoshima">Kagoshima</option> -<option value="okinawa">Okinawa</option> -</select>''' - self.assertEqual(f.render('prefecture', 'kanagawa'), out) - - def test_JPPostalCodeField(self): - error_format = [u'Enter a postal code in the format XXXXXXX or XXX-XXXX.'] - valid = { - '251-0032': '2510032', - '2510032': '2510032', - } - invalid = { - '2510-032': error_format, - '251a0032': error_format, - 'a51-0032': error_format, - '25100321': error_format, - } - self.assertFieldOutput(JPPostalCodeField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/kw.py b/parts/django/tests/regressiontests/forms/localflavor/kw.py deleted file mode 100644 index af998bd..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/kw.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.contrib.localflavor.kw.forms import KWCivilIDNumberField - -from utils import LocalFlavorTestCase - - -class KWLocalFlavorTests(LocalFlavorTestCase): - def test_KWCivilIDNumberField(self): - error_invalid = [u'Enter a valid Kuwaiti Civil ID number'] - valid = { - '282040701483': '282040701483', - } - invalid = { - '289332013455': error_invalid, - } - self.assertFieldOutput(KWCivilIDNumberField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/nl.py b/parts/django/tests/regressiontests/forms/localflavor/nl.py deleted file mode 100644 index 8ef0ae9..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/nl.py +++ /dev/null @@ -1,62 +0,0 @@ -from django.contrib.localflavor.nl.forms import (NLPhoneNumberField, - NLZipCodeField, NLSoFiNumberField, NLProvinceSelect) - -from utils import LocalFlavorTestCase - - -class NLLocalFlavorTests(LocalFlavorTestCase): - def test_NLProvinceSelect(self): - f = NLProvinceSelect() - out = u'''<select name="provinces"> -<option value="DR">Drenthe</option> -<option value="FL">Flevoland</option> -<option value="FR">Friesland</option> -<option value="GL">Gelderland</option> -<option value="GR">Groningen</option> -<option value="LB">Limburg</option> -<option value="NB">Noord-Brabant</option> -<option value="NH">Noord-Holland</option> -<option value="OV" selected="selected">Overijssel</option> -<option value="UT">Utrecht</option> -<option value="ZE">Zeeland</option> -<option value="ZH">Zuid-Holland</option> -</select>''' - self.assertEqual(f.render('provinces', 'OV'), out) - - def test_NLPhoneNumberField(self): - error_invalid = [u'Enter a valid phone number'] - valid = { - '012-3456789': '012-3456789', - '0123456789': '0123456789', - '+31-12-3456789': '+31-12-3456789', - '(0123) 456789': '(0123) 456789', - } - invalid = { - 'foo': error_invalid, - } - self.assertFieldOutput(NLPhoneNumberField, valid, invalid) - - def test_NLZipCodeField(self): - error_invalid = [u'Enter a valid postal code'] - valid = { - '1234ab': '1234 AB', - '1234 ab': '1234 AB', - '1234 AB': '1234 AB', - } - invalid = { - '0123AB': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(NLZipCodeField, valid, invalid) - - def test_NLSoFiNumberField(self): - error_invalid = [u'Enter a valid SoFi number'] - valid = { - '123456782': '123456782', - } - invalid = { - '000000000': error_invalid, - '123456789': error_invalid, - 'foo': error_invalid, - } - self.assertFieldOutput(NLSoFiNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/pl.py b/parts/django/tests/regressiontests/forms/localflavor/pl.py deleted file mode 100644 index 51721f8..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/pl.py +++ /dev/null @@ -1,462 +0,0 @@ -from django.contrib.localflavor.pl.forms import (PLProvinceSelect, - PLCountySelect, PLPostalCodeField, PLNIPField, PLPESELField, PLREGONField) - -from utils import LocalFlavorTestCase - - -class PLLocalFlavorTests(LocalFlavorTestCase): - def test_PLProvinceSelect(self): - f = PLProvinceSelect() - out = u'''<select name="voivodeships"> -<option value="lower_silesia">Lower Silesia</option> -<option value="kuyavia-pomerania">Kuyavia-Pomerania</option> -<option value="lublin">Lublin</option> -<option value="lubusz">Lubusz</option> -<option value="lodz">Lodz</option> -<option value="lesser_poland">Lesser Poland</option> -<option value="masovia">Masovia</option> -<option value="opole">Opole</option> -<option value="subcarpatia">Subcarpatia</option> -<option value="podlasie">Podlasie</option> -<option value="pomerania" selected="selected">Pomerania</option> -<option value="silesia">Silesia</option> -<option value="swietokrzyskie">Swietokrzyskie</option> -<option value="warmia-masuria">Warmia-Masuria</option> -<option value="greater_poland">Greater Poland</option> -<option value="west_pomerania">West Pomerania</option> -</select>''' - self.assertEqual(f.render('voivodeships', 'pomerania'), out) - - def test_PLCountrySelect(self): - f = PLCountySelect() - out = u'''<select name="administrativeunit"> -<option value="wroclaw">Wroc\u0142aw</option> -<option value="jeleniagora">Jelenia G\xf3ra</option> -<option value="legnica">Legnica</option> -<option value="boleslawiecki">boles\u0142awiecki</option> -<option value="dzierzoniowski">dzier\u017coniowski</option> -<option value="glogowski">g\u0142ogowski</option> -<option value="gorowski">g\xf3rowski</option> -<option value="jaworski">jaworski</option> -<option value="jeleniogorski">jeleniog\xf3rski</option> -<option value="kamiennogorski">kamiennog\xf3rski</option> -<option value="klodzki">k\u0142odzki</option> -<option value="legnicki">legnicki</option> -<option value="lubanski">luba\u0144ski</option> -<option value="lubinski">lubi\u0144ski</option> -<option value="lwowecki">lw\xf3wecki</option> -<option value="milicki">milicki</option> -<option value="olesnicki">ole\u015bnicki</option> -<option value="olawski">o\u0142awski</option> -<option value="polkowicki">polkowicki</option> -<option value="strzelinski">strzeli\u0144ski</option> -<option value="sredzki">\u015bredzki</option> -<option value="swidnicki">\u015bwidnicki</option> -<option value="trzebnicki">trzebnicki</option> -<option value="walbrzyski">wa\u0142brzyski</option> -<option value="wolowski">wo\u0142owski</option> -<option value="wroclawski">wroc\u0142awski</option> -<option value="zabkowicki">z\u0105bkowicki</option> -<option value="zgorzelecki">zgorzelecki</option> -<option value="zlotoryjski">z\u0142otoryjski</option> -<option value="bydgoszcz">Bydgoszcz</option> -<option value="torun">Toru\u0144</option> -<option value="wloclawek">W\u0142oc\u0142awek</option> -<option value="grudziadz">Grudzi\u0105dz</option> -<option value="aleksandrowski">aleksandrowski</option> -<option value="brodnicki">brodnicki</option> -<option value="bydgoski">bydgoski</option> -<option value="chelminski">che\u0142mi\u0144ski</option> -<option value="golubsko-dobrzynski">golubsko-dobrzy\u0144ski</option> -<option value="grudziadzki">grudzi\u0105dzki</option> -<option value="inowroclawski">inowroc\u0142awski</option> -<option value="lipnowski">lipnowski</option> -<option value="mogilenski">mogile\u0144ski</option> -<option value="nakielski">nakielski</option> -<option value="radziejowski">radziejowski</option> -<option value="rypinski">rypi\u0144ski</option> -<option value="sepolenski">s\u0119pole\u0144ski</option> -<option value="swiecki">\u015bwiecki</option> -<option value="torunski">toru\u0144ski</option> -<option value="tucholski">tucholski</option> -<option value="wabrzeski">w\u0105brzeski</option> -<option value="wloclawski">wroc\u0142awski</option> -<option value="zninski">\u017ani\u0144ski</option> -<option value="lublin">Lublin</option> -<option value="biala-podlaska">Bia\u0142a Podlaska</option> -<option value="chelm">Che\u0142m</option> -<option value="zamosc">Zamo\u015b\u0107</option> -<option value="bialski">bialski</option> -<option value="bilgorajski">bi\u0142gorajski</option> -<option value="chelmski">che\u0142mski</option> -<option value="hrubieszowski">hrubieszowski</option> -<option value="janowski">janowski</option> -<option value="krasnostawski">krasnostawski</option> -<option value="krasnicki">kra\u015bnicki</option> -<option value="lubartowski">lubartowski</option> -<option value="lubelski">lubelski</option> -<option value="leczynski">\u0142\u0119czy\u0144ski</option> -<option value="lukowski">\u0142ukowski</option> -<option value="opolski">opolski</option> -<option value="parczewski">parczewski</option> -<option value="pulawski">pu\u0142awski</option> -<option value="radzynski">radzy\u0144ski</option> -<option value="rycki">rycki</option> -<option value="swidnicki">\u015bwidnicki</option> -<option value="tomaszowski">tomaszowski</option> -<option value="wlodawski">w\u0142odawski</option> -<option value="zamojski">zamojski</option> -<option value="gorzow-wielkopolski">Gorz\xf3w Wielkopolski</option> -<option value="zielona-gora">Zielona G\xf3ra</option> -<option value="gorzowski">gorzowski</option> -<option value="krosnienski">kro\u015bnie\u0144ski</option> -<option value="miedzyrzecki">mi\u0119dzyrzecki</option> -<option value="nowosolski">nowosolski</option> -<option value="slubicki">s\u0142ubicki</option> -<option value="strzelecko-drezdenecki">strzelecko-drezdenecki</option> -<option value="sulecinski">sule\u0144ci\u0144ski</option> -<option value="swiebodzinski">\u015bwiebodzi\u0144ski</option> -<option value="wschowski">wschowski</option> -<option value="zielonogorski">zielonog\xf3rski</option> -<option value="zaganski">\u017caga\u0144ski</option> -<option value="zarski">\u017carski</option> -<option value="lodz">\u0141\xf3d\u017a</option> -<option value="piotrkow-trybunalski">Piotrk\xf3w Trybunalski</option> -<option value="skierniewice">Skierniewice</option> -<option value="belchatowski">be\u0142chatowski</option> -<option value="brzezinski">brzezi\u0144ski</option> -<option value="kutnowski">kutnowski</option> -<option value="laski">\u0142aski</option> -<option value="leczycki">\u0142\u0119czycki</option> -<option value="lowicki">\u0142owicki</option> -<option value="lodzki wschodni">\u0142\xf3dzki wschodni</option> -<option value="opoczynski">opoczy\u0144ski</option> -<option value="pabianicki">pabianicki</option> -<option value="pajeczanski">paj\u0119cza\u0144ski</option> -<option value="piotrkowski">piotrkowski</option> -<option value="poddebicki">podd\u0119bicki</option> -<option value="radomszczanski">radomszcza\u0144ski</option> -<option value="rawski">rawski</option> -<option value="sieradzki">sieradzki</option> -<option value="skierniewicki">skierniewicki</option> -<option value="tomaszowski">tomaszowski</option> -<option value="wielunski">wielu\u0144ski</option> -<option value="wieruszowski">wieruszowski</option> -<option value="zdunskowolski">zdu\u0144skowolski</option> -<option value="zgierski">zgierski</option> -<option value="krakow">Krak\xf3w</option> -<option value="tarnow">Tarn\xf3w</option> -<option value="nowy-sacz">Nowy S\u0105cz</option> -<option value="bochenski">boche\u0144ski</option> -<option value="brzeski">brzeski</option> -<option value="chrzanowski">chrzanowski</option> -<option value="dabrowski">d\u0105browski</option> -<option value="gorlicki">gorlicki</option> -<option value="krakowski">krakowski</option> -<option value="limanowski">limanowski</option> -<option value="miechowski">miechowski</option> -<option value="myslenicki">my\u015blenicki</option> -<option value="nowosadecki">nowos\u0105decki</option> -<option value="nowotarski">nowotarski</option> -<option value="olkuski">olkuski</option> -<option value="oswiecimski">o\u015bwi\u0119cimski</option> -<option value="proszowicki">proszowicki</option> -<option value="suski">suski</option> -<option value="tarnowski">tarnowski</option> -<option value="tatrzanski">tatrza\u0144ski</option> -<option value="wadowicki">wadowicki</option> -<option value="wielicki">wielicki</option> -<option value="warszawa">Warszawa</option> -<option value="ostroleka">Ostro\u0142\u0119ka</option> -<option value="plock">P\u0142ock</option> -<option value="radom">Radom</option> -<option value="siedlce">Siedlce</option> -<option value="bialobrzeski">bia\u0142obrzeski</option> -<option value="ciechanowski">ciechanowski</option> -<option value="garwolinski">garwoli\u0144ski</option> -<option value="gostyninski">gostyni\u0144ski</option> -<option value="grodziski">grodziski</option> -<option value="grojecki">gr\xf3jecki</option> -<option value="kozienicki">kozenicki</option> -<option value="legionowski">legionowski</option> -<option value="lipski">lipski</option> -<option value="losicki">\u0142osicki</option> -<option value="makowski">makowski</option> -<option value="minski">mi\u0144ski</option> -<option value="mlawski">m\u0142awski</option> -<option value="nowodworski">nowodworski</option> -<option value="ostrolecki">ostro\u0142\u0119cki</option> -<option value="ostrowski">ostrowski</option> -<option value="otwocki">otwocki</option> -<option value="piaseczynski">piaseczy\u0144ski</option> -<option value="plocki">p\u0142ocki</option> -<option value="plonski">p\u0142o\u0144ski</option> -<option value="pruszkowski">pruszkowski</option> -<option value="przasnyski">przasnyski</option> -<option value="przysuski">przysuski</option> -<option value="pultuski">pu\u0142tuski</option> -<option value="radomski">radomski</option> -<option value="siedlecki">siedlecki</option> -<option value="sierpecki">sierpecki</option> -<option value="sochaczewski">sochaczewski</option> -<option value="sokolowski">soko\u0142owski</option> -<option value="szydlowiecki">szyd\u0142owiecki</option> -<option value="warszawski-zachodni">warszawski zachodni</option> -<option value="wegrowski">w\u0119growski</option> -<option value="wolominski">wo\u0142omi\u0144ski</option> -<option value="wyszkowski">wyszkowski</option> -<option value="zwolenski">zwole\u0144ski</option> -<option value="zurominski">\u017curomi\u0144ski</option> -<option value="zyrardowski">\u017cyrardowski</option> -<option value="opole">Opole</option> -<option value="brzeski">brzeski</option> -<option value="glubczycki">g\u0142ubczyski</option> -<option value="kedzierzynsko-kozielski">k\u0119dzierzy\u0144ski-kozielski</option> -<option value="kluczborski">kluczborski</option> -<option value="krapkowicki">krapkowicki</option> -<option value="namyslowski">namys\u0142owski</option> -<option value="nyski">nyski</option> -<option value="oleski">oleski</option> -<option value="opolski">opolski</option> -<option value="prudnicki">prudnicki</option> -<option value="strzelecki">strzelecki</option> -<option value="rzeszow">Rzesz\xf3w</option> -<option value="krosno">Krosno</option> -<option value="przemysl">Przemy\u015bl</option> -<option value="tarnobrzeg">Tarnobrzeg</option> -<option value="bieszczadzki">bieszczadzki</option> -<option value="brzozowski">brzozowski</option> -<option value="debicki">d\u0119bicki</option> -<option value="jaroslawski">jaros\u0142awski</option> -<option value="jasielski">jasielski</option> -<option value="kolbuszowski">kolbuszowski</option> -<option value="krosnienski">kro\u015bnie\u0144ski</option> -<option value="leski">leski</option> -<option value="lezajski">le\u017cajski</option> -<option value="lubaczowski">lubaczowski</option> -<option value="lancucki">\u0142a\u0144cucki</option> -<option value="mielecki">mielecki</option> -<option value="nizanski">ni\u017ca\u0144ski</option> -<option value="przemyski">przemyski</option> -<option value="przeworski">przeworski</option> -<option value="ropczycko-sedziszowski">ropczycko-s\u0119dziszowski</option> -<option value="rzeszowski">rzeszowski</option> -<option value="sanocki">sanocki</option> -<option value="stalowowolski">stalowowolski</option> -<option value="strzyzowski">strzy\u017cowski</option> -<option value="tarnobrzeski">tarnobrzeski</option> -<option value="bialystok">Bia\u0142ystok</option> -<option value="lomza">\u0141om\u017ca</option> -<option value="suwalki">Suwa\u0142ki</option> -<option value="augustowski">augustowski</option> -<option value="bialostocki">bia\u0142ostocki</option> -<option value="bielski">bielski</option> -<option value="grajewski">grajewski</option> -<option value="hajnowski">hajnowski</option> -<option value="kolnenski">kolne\u0144ski</option> -<option value="\u0142omzynski">\u0142om\u017cy\u0144ski</option> -<option value="moniecki">moniecki</option> -<option value="sejnenski">sejne\u0144ski</option> -<option value="siemiatycki">siematycki</option> -<option value="sokolski">sok\xf3lski</option> -<option value="suwalski">suwalski</option> -<option value="wysokomazowiecki">wysokomazowiecki</option> -<option value="zambrowski">zambrowski</option> -<option value="gdansk">Gda\u0144sk</option> -<option value="gdynia">Gdynia</option> -<option value="slupsk">S\u0142upsk</option> -<option value="sopot">Sopot</option> -<option value="bytowski">bytowski</option> -<option value="chojnicki">chojnicki</option> -<option value="czluchowski">cz\u0142uchowski</option> -<option value="kartuski">kartuski</option> -<option value="koscierski">ko\u015bcierski</option> -<option value="kwidzynski">kwidzy\u0144ski</option> -<option value="leborski">l\u0119borski</option> -<option value="malborski">malborski</option> -<option value="nowodworski">nowodworski</option> -<option value="gdanski">gda\u0144ski</option> -<option value="pucki">pucki</option> -<option value="slupski">s\u0142upski</option> -<option value="starogardzki">starogardzki</option> -<option value="sztumski">sztumski</option> -<option value="tczewski">tczewski</option> -<option value="wejherowski">wejcherowski</option> -<option value="katowice" selected="selected">Katowice</option> -<option value="bielsko-biala">Bielsko-Bia\u0142a</option> -<option value="bytom">Bytom</option> -<option value="chorzow">Chorz\xf3w</option> -<option value="czestochowa">Cz\u0119stochowa</option> -<option value="dabrowa-gornicza">D\u0105browa G\xf3rnicza</option> -<option value="gliwice">Gliwice</option> -<option value="jastrzebie-zdroj">Jastrz\u0119bie Zdr\xf3j</option> -<option value="jaworzno">Jaworzno</option> -<option value="myslowice">Mys\u0142owice</option> -<option value="piekary-slaskie">Piekary \u015al\u0105skie</option> -<option value="ruda-slaska">Ruda \u015al\u0105ska</option> -<option value="rybnik">Rybnik</option> -<option value="siemianowice-slaskie">Siemianowice \u015al\u0105skie</option> -<option value="sosnowiec">Sosnowiec</option> -<option value="swietochlowice">\u015awi\u0119toch\u0142owice</option> -<option value="tychy">Tychy</option> -<option value="zabrze">Zabrze</option> -<option value="zory">\u017bory</option> -<option value="bedzinski">b\u0119dzi\u0144ski</option> -<option value="bielski">bielski</option> -<option value="bierunsko-ledzinski">bieru\u0144sko-l\u0119dzi\u0144ski</option> -<option value="cieszynski">cieszy\u0144ski</option> -<option value="czestochowski">cz\u0119stochowski</option> -<option value="gliwicki">gliwicki</option> -<option value="klobucki">k\u0142obucki</option> -<option value="lubliniecki">lubliniecki</option> -<option value="mikolowski">miko\u0142owski</option> -<option value="myszkowski">myszkowski</option> -<option value="pszczynski">pszczy\u0144ski</option> -<option value="raciborski">raciborski</option> -<option value="rybnicki">rybnicki</option> -<option value="tarnogorski">tarnog\xf3rski</option> -<option value="wodzislawski">wodzis\u0142awski</option> -<option value="zawiercianski">zawiercia\u0144ski</option> -<option value="zywiecki">\u017cywiecki</option> -<option value="kielce">Kielce</option> -<option value="buski">buski</option> -<option value="jedrzejowski">j\u0119drzejowski</option> -<option value="kazimierski">kazimierski</option> -<option value="kielecki">kielecki</option> -<option value="konecki">konecki</option> -<option value="opatowski">opatowski</option> -<option value="ostrowiecki">ostrowiecki</option> -<option value="pinczowski">pi\u0144czowski</option> -<option value="sandomierski">sandomierski</option> -<option value="skarzyski">skar\u017cyski</option> -<option value="starachowicki">starachowicki</option> -<option value="staszowski">staszowski</option> -<option value="wloszczowski">w\u0142oszczowski</option> -<option value="olsztyn">Olsztyn</option> -<option value="elblag">Elbl\u0105g</option> -<option value="bartoszycki">bartoszycki</option> -<option value="braniewski">braniewski</option> -<option value="dzialdowski">dzia\u0142dowski</option> -<option value="elblaski">elbl\u0105ski</option> -<option value="elcki">e\u0142cki</option> -<option value="gizycki">gi\u017cycki</option> -<option value="goldapski">go\u0142dapski</option> -<option value="ilawski">i\u0142awski</option> -<option value="ketrzynski">k\u0119trzy\u0144ski</option> -<option value="lidzbarski">lidzbarski</option> -<option value="mragowski">mr\u0105gowski</option> -<option value="nidzicki">nidzicki</option> -<option value="nowomiejski">nowomiejski</option> -<option value="olecki">olecki</option> -<option value="olsztynski">olszty\u0144ski</option> -<option value="ostrodzki">ostr\xf3dzki</option> -<option value="piski">piski</option> -<option value="szczycienski">szczycie\u0144ski</option> -<option value="wegorzewski">w\u0119gorzewski</option> -<option value="poznan">Pozna\u0144</option> -<option value="kalisz">Kalisz</option> -<option value="konin">Konin</option> -<option value="leszno">Leszno</option> -<option value="chodzieski">chodziejski</option> -<option value="czarnkowsko-trzcianecki">czarnkowsko-trzcianecki</option> -<option value="gnieznienski">gnie\u017anie\u0144ski</option> -<option value="gostynski">gosty\u0144ski</option> -<option value="grodziski">grodziski</option> -<option value="jarocinski">jaroci\u0144ski</option> -<option value="kaliski">kaliski</option> -<option value="kepinski">k\u0119pi\u0144ski</option> -<option value="kolski">kolski</option> -<option value="koninski">koni\u0144ski</option> -<option value="koscianski">ko\u015bcia\u0144ski</option> -<option value="krotoszynski">krotoszy\u0144ski</option> -<option value="leszczynski">leszczy\u0144ski</option> -<option value="miedzychodzki">mi\u0119dzychodzki</option> -<option value="nowotomyski">nowotomyski</option> -<option value="obornicki">obornicki</option> -<option value="ostrowski">ostrowski</option> -<option value="ostrzeszowski">ostrzeszowski</option> -<option value="pilski">pilski</option> -<option value="pleszewski">pleszewski</option> -<option value="poznanski">pozna\u0144ski</option> -<option value="rawicki">rawicki</option> -<option value="slupecki">s\u0142upecki</option> -<option value="szamotulski">szamotulski</option> -<option value="sredzki">\u015bredzki</option> -<option value="sremski">\u015bremski</option> -<option value="turecki">turecki</option> -<option value="wagrowiecki">w\u0105growiecki</option> -<option value="wolsztynski">wolszty\u0144ski</option> -<option value="wrzesinski">wrzesi\u0144ski</option> -<option value="zlotowski">z\u0142otowski</option> -<option value="bialogardzki">bia\u0142ogardzki</option> -<option value="choszczenski">choszcze\u0144ski</option> -<option value="drawski">drawski</option> -<option value="goleniowski">goleniowski</option> -<option value="gryficki">gryficki</option> -<option value="gryfinski">gryfi\u0144ski</option> -<option value="kamienski">kamie\u0144ski</option> -<option value="kolobrzeski">ko\u0142obrzeski</option> -<option value="koszalinski">koszali\u0144ski</option> -<option value="lobeski">\u0142obeski</option> -<option value="mysliborski">my\u015bliborski</option> -<option value="policki">policki</option> -<option value="pyrzycki">pyrzycki</option> -<option value="slawienski">s\u0142awie\u0144ski</option> -<option value="stargardzki">stargardzki</option> -<option value="szczecinecki">szczecinecki</option> -<option value="swidwinski">\u015bwidwi\u0144ski</option> -<option value="walecki">wa\u0142ecki</option> -</select>''' - self.assertEqual(f.render('administrativeunit', 'katowice'), out) - - def test_PLPostalCodeField(self): - error_format = [u'Enter a postal code in the format XX-XXX.'] - valid = { - '41-403': '41-403', - } - invalid = { - '43--434': error_format, - } - self.assertFieldOutput(PLPostalCodeField, valid, invalid) - - def test_PLNIPField(self): - error_format = [u'Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX.'] - error_checksum = [u'Wrong checksum for the Tax Number (NIP).'] - valid = { - '64-62-414-124': '6462414124', - '646-241-41-24': '6462414124', - } - invalid = { - '43-343-234-323': error_format, - '646-241-41-23': error_checksum, - } - self.assertFieldOutput(PLNIPField, valid, invalid) - - def test_PLPESELField(self): - error_checksum = [u'Wrong checksum for the National Identification Number.'] - error_format = [u'National Identification Number consists of 11 digits.'] - valid = { - '80071610614': '80071610614', - } - invalid = { - '80071610610': error_checksum, - '80': error_format, - '800716106AA': error_format, - } - self.assertFieldOutput(PLPESELField, valid, invalid) - - def test_PLREGONField(self): - error_checksum = [u'Wrong checksum for the National Business Register Number (REGON).'] - error_format = [u'National Business Register Number (REGON) consists of 9 or 14 digits.'] - valid = { - '12345678512347': '12345678512347', - '590096454': '590096454', - } - invalid = { - '123456784': error_checksum, - '12345678412342': error_checksum, - '590096453': error_checksum, - '590096': error_format, - } - self.assertFieldOutput(PLREGONField, valid, invalid) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/pt.py b/parts/django/tests/regressiontests/forms/localflavor/pt.py deleted file mode 100644 index b8d784a..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/pt.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.contrib.localflavor.pt.forms import PTZipCodeField, PTPhoneNumberField - -from utils import LocalFlavorTestCase - - -class PTLocalFlavorTests(LocalFlavorTestCase): - def test_PTZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXX-XXX.'] - valid = { - '3030-034': '3030-034', - '1003456': '1003-456', - } - invalid = { - '2A200': error_format, - '980001': error_format, - } - self.assertFieldOutput(PTZipCodeField, valid, invalid) - - def test_PTPhoneNumberField(self): - error_format = [u'Phone numbers must have 9 digits, or start by + or 00.'] - valid = { - '917845189': '917845189', - '91 784 5189': '917845189', - '91 784 5189': '917845189', - '+351 91 111': '+35191111', - '00351873': '00351873', - } - invalid = { - '91 784 51 8': error_format, - '091 456 987 1': error_format, - } - self.assertFieldOutput(PTPhoneNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/ro.py b/parts/django/tests/regressiontests/forms/localflavor/ro.py deleted file mode 100644 index c3dd403..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/ro.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -from django.contrib.localflavor.ro.forms import (ROCIFField, ROCNPField, - ROCountyField, ROCountySelect, ROIBANField, ROPhoneNumberField, - ROPostalCodeField) - -from utils import LocalFlavorTestCase - - -class ROLocalFlavorTests(LocalFlavorTestCase): - def test_ROCountySelect(self): - f = ROCountySelect() - out = u'''<select name="county"> -<option value="AB">Alba</option> -<option value="AR">Arad</option> -<option value="AG">Arge\u015f</option> -<option value="BC">Bac\u0103u</option> -<option value="BH">Bihor</option> -<option value="BN">Bistri\u0163a-N\u0103s\u0103ud</option> -<option value="BT">Boto\u015fani</option> -<option value="BV">Bra\u015fov</option> -<option value="BR">Br\u0103ila</option> -<option value="B">Bucure\u015fti</option> -<option value="BZ">Buz\u0103u</option> -<option value="CS">Cara\u015f-Severin</option> -<option value="CL">C\u0103l\u0103ra\u015fi</option> -<option value="CJ" selected="selected">Cluj</option> -<option value="CT">Constan\u0163a</option> -<option value="CV">Covasna</option> -<option value="DB">D\xe2mbovi\u0163a</option> -<option value="DJ">Dolj</option> -<option value="GL">Gala\u0163i</option> -<option value="GR">Giurgiu</option> -<option value="GJ">Gorj</option> -<option value="HR">Harghita</option> -<option value="HD">Hunedoara</option> -<option value="IL">Ialomi\u0163a</option> -<option value="IS">Ia\u015fi</option> -<option value="IF">Ilfov</option> -<option value="MM">Maramure\u015f</option> -<option value="MH">Mehedin\u0163i</option> -<option value="MS">Mure\u015f</option> -<option value="NT">Neam\u0163</option> -<option value="OT">Olt</option> -<option value="PH">Prahova</option> -<option value="SM">Satu Mare</option> -<option value="SJ">S\u0103laj</option> -<option value="SB">Sibiu</option> -<option value="SV">Suceava</option> -<option value="TR">Teleorman</option> -<option value="TM">Timi\u015f</option> -<option value="TL">Tulcea</option> -<option value="VS">Vaslui</option> -<option value="VL">V\xe2lcea</option> -<option value="VN">Vrancea</option> -</select>''' - self.assertEqual(f.render('county', 'CJ'), out) - - def test_ROCIFField(self): - error_invalid = [u'Enter a valid CIF.'] - error_atmost = [u'Ensure this value has at most 10 characters (it has 11).'] - error_atleast = [u'Ensure this value has at least 2 characters (it has 1).'] - valid = { - '21694681': u'21694681', - 'RO21694681': u'21694681', - } - invalid = { - '21694680': error_invalid, - '21694680000': error_atmost, - '0': error_atleast + error_invalid, - } - self.assertFieldOutput(ROCIFField, valid, invalid) - - def test_ROCNPField(self): - error_invalid = [u'Enter a valid CNP.'] - error_atleast = [u'Ensure this value has at least 13 characters (it has 10).'] - error_atmost = [u'Ensure this value has at most 13 characters (it has 14).'] - valid = { - '1981211204489': '1981211204489', - } - invalid = { - '1981211204487': error_invalid, - '1981232204489': error_invalid, - '9981211204489': error_invalid, - '9981211209': error_atleast + error_invalid, - '19812112044891': error_atmost, - } - self.assertFieldOutput(ROCNPField, valid, invalid) - - def test_ROCountyField(self): - error_format = [u'Enter a Romanian county code or name.'] - valid = { - 'CJ': 'CJ', - 'cj': 'CJ', - u'Argeş': 'AG', - u'argeş': 'AG', - } - invalid = { - 'Arges': error_format, - } - self.assertFieldOutput(ROCountyField, valid, invalid) - - def test_ROIBANField(self): - error_invalid = [u'Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format'] - error_atleast = [u'Ensure this value has at least 24 characters (it has 23).'] - valid = { - 'RO56RZBR0000060003291177': 'RO56RZBR0000060003291177', - 'RO56-RZBR-0000-0600-0329-1177': 'RO56RZBR0000060003291177', - } - invalid = { - 'RO56RZBR0000060003291176': error_invalid, - 'AT61 1904 3002 3457 3201': error_invalid, - 'RO56RZBR000006000329117': error_atleast + error_invalid, - } - self.assertFieldOutput(ROIBANField, valid, invalid) - - def test_ROPhoneNumberField(self): - error_format = [u'Phone numbers must be in XXXX-XXXXXX format.'] - error_atleast = [u'Ensure this value has at least 10 characters (it has 9).'] - valid = { - '0264485936': '0264485936', - '(0264)-485936': '0264485936', - } - invalid = { - '02644859368': error_format, - '026448593': error_atleast + error_format - , - } - self.assertFieldOutput(ROPhoneNumberField, valid, invalid) - - def test_ROPostalCodeField(self): - error_atleast = [u'Ensure this value has at least 6 characters (it has 5).'] - error_atmost = [u'Ensure this value has at most 6 characters (it has 7).'] - error_invalid = [u'Enter a valid postal code in the format XXXXXX'] - - valid = { - '400473': '400473', - } - invalid = { - '40047': error_atleast + error_invalid, - '4004731': error_atmost + error_invalid, - } - self.assertFieldOutput(ROPostalCodeField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/se.py b/parts/django/tests/regressiontests/forms/localflavor/se.py deleted file mode 100644 index 316a612..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/se.py +++ /dev/null @@ -1,331 +0,0 @@ -# -*- coding: utf-8 -*- -# Tests for the contrib/localflavor/se form fields. - -tests = r""" -# Monkey-patch datetime.date ->>> import datetime ->>> class MockDate(datetime.date): -... def today(cls): -... return datetime.date(2008, 5, 14) -... today = classmethod(today) -... ->>> olddate = datetime.date ->>> datetime.date = MockDate ->>> datetime.date.today() == olddate(2008, 5, 14) -True - -# SECountySelect ##################################################### ->>> from django.contrib.localflavor.se.forms import SECountySelect - ->>> w = SECountySelect() ->>> w.render('swedish_county', 'E') -u'<select name="swedish_county">\n<option value="AB">Stockholm</option>\n<option value="AC">V\xe4sterbotten</option>\n<option value="BD">Norrbotten</option>\n<option value="C">Uppsala</option>\n<option value="D">S\xf6dermanland</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland</option>\n<option value="F">J\xf6nk\xf6ping</option>\n<option value="G">Kronoberg</option>\n<option value="H">Kalmar</option>\n<option value="I">Gotland</option>\n<option value="K">Blekinge</option>\n<option value="M">Sk\xe5ne</option>\n<option value="N">Halland</option>\n<option value="O">V\xe4stra G\xf6taland</option>\n<option value="S">V\xe4rmland</option>\n<option value="T">\xd6rebro</option>\n<option value="U">V\xe4stmanland</option>\n<option value="W">Dalarna</option>\n<option value="X">G\xe4vleborg</option>\n<option value="Y">V\xe4sternorrland</option>\n<option value="Z">J\xe4mtland</option>\n</select>' - -# SEOrganisationNumberField ####################################### - ->>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField - ->>> f = SEOrganisationNumberField() - -# Ordinary personal identity numbers for sole proprietors -# The same rules as for SEPersonalIdentityField applies here ->>> f.clean('870512-1989') -u'198705121989' ->>> f.clean('19870512-1989') -u'198705121989' ->>> f.clean('870512-2128') -u'198705122128' ->>> f.clean('081015-6315') -u'190810156315' ->>> f.clean('081015+6315') -u'180810156315' ->>> f.clean('0810156315') -u'190810156315' - ->>> f.clean('081015 6315') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] ->>> f.clean('950231-4496') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] ->>> f.clean('6914104499') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] ->>> f.clean('950d314496') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] ->>> f.clean('invalid!!!') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] ->>> f.clean('870514-1111') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - - -# Empty values ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - ->>> f.clean(None) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - -# Co-ordination number checking -# Co-ordination numbers are not valid organisation numbers ->>> f.clean('870574-1315') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - ->>> f.clean('870573-1311') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - -# Test some different organisation numbers ->>> f.clean('556074-7569') # IKEA Linköping -u'5560747569' - ->>> f.clean('556074-3089') # Volvo Personvagnar -u'5560743089' - ->>> f.clean('822001-5476') # LJS (organisation) -u'8220015476' - ->>> f.clean('8220015476') # LJS (organisation) -u'8220015476' - ->>> f.clean('2120000449') # Katedralskolan Linköping (school) -u'2120000449' - -# Faux organisation number, which tests that the checksum can be 0 ->>> f.clean('232518-5060') -u'2325185060' - ->>> f.clean('556074+3089') # Volvo Personvagnar, bad format -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - - -# Invalid checksum ->>> f.clean('2120000441') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - -# Valid checksum but invalid organisation type -f.clean('1120000441') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish organisation number.'] - -# Empty values with required=False ->>> f = SEOrganisationNumberField(required=False) - ->>> f.clean(None) -u'' - ->>> f.clean('') -u'' - - -# SEPersonalIdentityNumberField ####################################### - ->>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField - ->>> f = SEPersonalIdentityNumberField() - -# Valid id numbers ->>> f.clean('870512-1989') -u'198705121989' - ->>> f.clean('870512-2128') -u'198705122128' - ->>> f.clean('19870512-1989') -u'198705121989' - ->>> f.clean('198705121989') -u'198705121989' - ->>> f.clean('081015-6315') -u'190810156315' - ->>> f.clean('0810156315') -u'190810156315' - -# This is a "special-case" in the checksum calculation, -# where the sum is divisible by 10 (the checksum digit == 0) ->>> f.clean('8705141060') -u'198705141060' - -# + means that the person is older than 100 years ->>> f.clean('081015+6315') -u'180810156315' - -# Bogus values ->>> f.clean('081015 6315') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - ->>> f.clean('950d314496') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - ->>> f.clean('invalid!!!') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - - -# Invalid dates - -# February 31st does not exist ->>> f.clean('950231-4496') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - -# Month 14 does not exist ->>> f.clean('6914104499') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - -# There are no Swedish personal id numbers where year < 1800 ->>> f.clean('17430309-7135') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - -# Invalid checksum ->>> f.clean('870514-1111') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - -# Empty values ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - ->>> f.clean(None) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - -# Co-ordination number checking ->>> f.clean('870574-1315') -u'198705741315' - ->>> f.clean('870574+1315') -u'188705741315' - ->>> f.clean('198705741315') -u'198705741315' - -# Co-ordination number with bad checksum ->>> f.clean('870573-1311') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - - -# Check valid co-ordination numbers, that should not be accepted -# because of coordination_number=False ->>> f = SEPersonalIdentityNumberField(coordination_number=False) - ->>> f.clean('870574-1315') -Traceback (most recent call last): -... -ValidationError: [u'Co-ordination numbers are not allowed.'] - ->>> f.clean('870574+1315') -Traceback (most recent call last): -... -ValidationError: [u'Co-ordination numbers are not allowed.'] - ->>> f.clean('8705741315') -Traceback (most recent call last): -... -ValidationError: [u'Co-ordination numbers are not allowed.'] - -# Invalid co-ordination numbers should be treated as invalid, and not -# as co-ordination numbers ->>> f.clean('870573-1311') -Traceback (most recent call last): -... -ValidationError: [u'Enter a valid Swedish personal identity number.'] - -# Empty values with required=False ->>> f = SEPersonalIdentityNumberField(required=False) - ->>> f.clean(None) -u'' - ->>> f.clean('') -u'' - -# SEPostalCodeField ############################################### ->>> from django.contrib.localflavor.se.forms import SEPostalCodeField ->>> f = SEPostalCodeField() ->>> -Postal codes can have spaces ->>> f.clean('589 37') -u'58937' - -... but the dont have to ->>> f.clean('58937') -u'58937' ->>> f.clean('abcasfassadf') -Traceback (most recent call last): -... -ValidationError: [u'Enter a Swedish postal code in the format XXXXX.'] - -# Only one space is allowed for separation ->>> f.clean('589 37') -Traceback (most recent call last): -... -ValidationError: [u'Enter a Swedish postal code in the format XXXXX.'] - -# The postal code must not start with 0 ->>> f.clean('01234') -Traceback (most recent call last): -... -ValidationError: [u'Enter a Swedish postal code in the format XXXXX.'] - -# Empty values ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - ->>> f.clean(None) -Traceback (most recent call last): -... -ValidationError: [u'This field is required.'] - -# Empty values, required=False ->>> f = SEPostalCodeField(required=False) ->>> f.clean('') -u'' ->>> f.clean(None) -u'' - -# Revert the monkey patching ->>> datetime.date = olddate - -""" diff --git a/parts/django/tests/regressiontests/forms/localflavor/sk.py b/parts/django/tests/regressiontests/forms/localflavor/sk.py deleted file mode 100644 index a5bed6f..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/sk.py +++ /dev/null @@ -1,116 +0,0 @@ -from django.contrib.localflavor.sk.forms import (SKRegionSelect, - SKPostalCodeField, SKDistrictSelect) - -from utils import LocalFlavorTestCase - - -class SKLocalFlavorTests(LocalFlavorTestCase): - def test_SKRegionSelect(self): - f = SKRegionSelect() - out = u'''<select name="regions"> -<option value="BB">Banska Bystrica region</option> -<option value="BA">Bratislava region</option> -<option value="KE">Kosice region</option> -<option value="NR">Nitra region</option> -<option value="PO">Presov region</option> -<option value="TN">Trencin region</option> -<option value="TT" selected="selected">Trnava region</option> -<option value="ZA">Zilina region</option> -</select>''' - self.assertEqual(f.render('regions', 'TT'), out) - - def test_SKDistrictSelect(self): - f = SKDistrictSelect() - out = u'''<select name="Districts"> -<option value="BB">Banska Bystrica</option> -<option value="BS">Banska Stiavnica</option> -<option value="BJ">Bardejov</option> -<option value="BN">Banovce nad Bebravou</option> -<option value="BR">Brezno</option> -<option value="BA1">Bratislava I</option> -<option value="BA2">Bratislava II</option> -<option value="BA3">Bratislava III</option> -<option value="BA4">Bratislava IV</option> -<option value="BA5">Bratislava V</option> -<option value="BY">Bytca</option> -<option value="CA">Cadca</option> -<option value="DT">Detva</option> -<option value="DK">Dolny Kubin</option> -<option value="DS">Dunajska Streda</option> -<option value="GA">Galanta</option> -<option value="GL">Gelnica</option> -<option value="HC">Hlohovec</option> -<option value="HE">Humenne</option> -<option value="IL">Ilava</option> -<option value="KK">Kezmarok</option> -<option value="KN">Komarno</option> -<option value="KE1">Kosice I</option> -<option value="KE2">Kosice II</option> -<option value="KE3">Kosice III</option> -<option value="KE4">Kosice IV</option> -<option value="KEO">Kosice - okolie</option> -<option value="KA">Krupina</option> -<option value="KM">Kysucke Nove Mesto</option> -<option value="LV">Levice</option> -<option value="LE">Levoca</option> -<option value="LM">Liptovsky Mikulas</option> -<option value="LC">Lucenec</option> -<option value="MA">Malacky</option> -<option value="MT">Martin</option> -<option value="ML">Medzilaborce</option> -<option value="MI">Michalovce</option> -<option value="MY">Myjava</option> -<option value="NO">Namestovo</option> -<option value="NR">Nitra</option> -<option value="NM">Nove Mesto nad Vahom</option> -<option value="NZ">Nove Zamky</option> -<option value="PE">Partizanske</option> -<option value="PK">Pezinok</option> -<option value="PN">Piestany</option> -<option value="PT">Poltar</option> -<option value="PP">Poprad</option> -<option value="PB">Povazska Bystrica</option> -<option value="PO">Presov</option> -<option value="PD">Prievidza</option> -<option value="PU">Puchov</option> -<option value="RA">Revuca</option> -<option value="RS">Rimavska Sobota</option> -<option value="RV">Roznava</option> -<option value="RK" selected="selected">Ruzomberok</option> -<option value="SB">Sabinov</option> -<option value="SC">Senec</option> -<option value="SE">Senica</option> -<option value="SI">Skalica</option> -<option value="SV">Snina</option> -<option value="SO">Sobrance</option> -<option value="SN">Spisska Nova Ves</option> -<option value="SL">Stara Lubovna</option> -<option value="SP">Stropkov</option> -<option value="SK">Svidnik</option> -<option value="SA">Sala</option> -<option value="TO">Topolcany</option> -<option value="TV">Trebisov</option> -<option value="TN">Trencin</option> -<option value="TT">Trnava</option> -<option value="TR">Turcianske Teplice</option> -<option value="TS">Tvrdosin</option> -<option value="VK">Velky Krtis</option> -<option value="VT">Vranov nad Toplou</option> -<option value="ZM">Zlate Moravce</option> -<option value="ZV">Zvolen</option> -<option value="ZC">Zarnovica</option> -<option value="ZH">Ziar nad Hronom</option> -<option value="ZA">Zilina</option> -</select>''' - self.assertEqual(f.render('Districts', 'RK'), out) - - def test_SKPostalCodeField(self): - error_format = [u'Enter a postal code in the format XXXXX or XXX XX.'] - valid = { - '91909': '91909', - '917 01': '91701', - } - invalid = { - '84545x': error_format, - } - self.assertFieldOutput(SKPostalCodeField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/uk.py b/parts/django/tests/regressiontests/forms/localflavor/uk.py deleted file mode 100644 index 6fd536f..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/uk.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.contrib.localflavor.uk.forms import UKPostcodeField - -from utils import LocalFlavorTestCase - - -class UKLocalFlavorTests(LocalFlavorTestCase): - def test_UKPostcodeField(self): - error_invalid = [u'Enter a valid postcode.'] - valid = { - 'BT32 4PX': 'BT32 4PX', - 'GIR 0AA': 'GIR 0AA', - 'BT324PX': 'BT32 4PX', - ' so11aa ': 'SO1 1AA', - ' so1 1aa ': 'SO1 1AA', - 'G2 3wt': 'G2 3WT', - 'EC1A 1BB': 'EC1A 1BB', - 'Ec1a1BB': 'EC1A 1BB', - } - invalid = { - '1NV 4L1D': error_invalid, - '1NV4L1D': error_invalid, - ' b0gUS': error_invalid, - } - self.assertFieldOutput(UKPostcodeField, valid, invalid) - valid = {} - invalid = { - '1NV 4L1D': [u'Enter a bloody postcode!'], - } - kwargs = {'error_messages': {'invalid': 'Enter a bloody postcode!'}} - self.assertFieldOutput(UKPostcodeField, valid, invalid, field_kwargs=kwargs) diff --git a/parts/django/tests/regressiontests/forms/localflavor/us.py b/parts/django/tests/regressiontests/forms/localflavor/us.py deleted file mode 100644 index 65dd1bb..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/us.py +++ /dev/null @@ -1,126 +0,0 @@ -from django.contrib.localflavor.us.forms import (USZipCodeField, - USPhoneNumberField, USStateField, USStateSelect, USSocialSecurityNumberField) - -from utils import LocalFlavorTestCase - - -class USLocalFlavorTests(LocalFlavorTestCase): - def test_USStateSelect(self): - f = USStateSelect() - out = u'''<select name="state"> -<option value="AL">Alabama</option> -<option value="AK">Alaska</option> -<option value="AS">American Samoa</option> -<option value="AZ">Arizona</option> -<option value="AR">Arkansas</option> -<option value="CA">California</option> -<option value="CO">Colorado</option> -<option value="CT">Connecticut</option> -<option value="DE">Delaware</option> -<option value="DC">District of Columbia</option> -<option value="FL">Florida</option> -<option value="GA">Georgia</option> -<option value="GU">Guam</option> -<option value="HI">Hawaii</option> -<option value="ID">Idaho</option> -<option value="IL" selected="selected">Illinois</option> -<option value="IN">Indiana</option> -<option value="IA">Iowa</option> -<option value="KS">Kansas</option> -<option value="KY">Kentucky</option> -<option value="LA">Louisiana</option> -<option value="ME">Maine</option> -<option value="MD">Maryland</option> -<option value="MA">Massachusetts</option> -<option value="MI">Michigan</option> -<option value="MN">Minnesota</option> -<option value="MS">Mississippi</option> -<option value="MO">Missouri</option> -<option value="MT">Montana</option> -<option value="NE">Nebraska</option> -<option value="NV">Nevada</option> -<option value="NH">New Hampshire</option> -<option value="NJ">New Jersey</option> -<option value="NM">New Mexico</option> -<option value="NY">New York</option> -<option value="NC">North Carolina</option> -<option value="ND">North Dakota</option> -<option value="MP">Northern Mariana Islands</option> -<option value="OH">Ohio</option> -<option value="OK">Oklahoma</option> -<option value="OR">Oregon</option> -<option value="PA">Pennsylvania</option> -<option value="PR">Puerto Rico</option> -<option value="RI">Rhode Island</option> -<option value="SC">South Carolina</option> -<option value="SD">South Dakota</option> -<option value="TN">Tennessee</option> -<option value="TX">Texas</option> -<option value="UT">Utah</option> -<option value="VT">Vermont</option> -<option value="VI">Virgin Islands</option> -<option value="VA">Virginia</option> -<option value="WA">Washington</option> -<option value="WV">West Virginia</option> -<option value="WI">Wisconsin</option> -<option value="WY">Wyoming</option> -</select>''' - self.assertEquals(f.render('state', 'IL'), out) - - def test_USZipCodeField(self): - error_format = [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.'] - valid = { - '60606': '60606', - 60606: '60606', - '04000': '04000', - '60606-1234': '60606-1234', - } - invalid = { - '4000': error_format, - '6060-1234': error_format, - '60606-': error_format, - } - self.assertFieldOutput(USZipCodeField, valid, invalid) - - def test_USPhoneNumberField(self): - error_format = [u'Phone numbers must be in XXX-XXX-XXXX format.'] - valid = { - '312-555-1212': '312-555-1212', - '3125551212': '312-555-1212', - '312 555-1212': '312-555-1212', - '(312) 555-1212': '312-555-1212', - '312 555 1212': '312-555-1212', - '312.555.1212': '312-555-1212', - '312.555-1212': '312-555-1212', - ' (312) 555.1212 ': '312-555-1212', - } - invalid = { - '555-1212': error_format, - '312-55-1212': error_format, - } - self.assertFieldOutput(USPhoneNumberField, valid, invalid) - - def test_USStateField(self): - error_invalid = [u'Enter a U.S. state or territory.'] - valid = { - 'il': 'IL', - 'IL': 'IL', - 'illinois': 'IL', - ' illinois ': 'IL', - } - invalid = { - 60606: error_invalid, - } - self.assertFieldOutput(USStateField, valid, invalid) - - def test_USSocialSecurityNumberField(self): - error_invalid = [u'Enter a valid U.S. Social Security number in XXX-XX-XXXX format.'] - - valid = { - '987-65-4330': '987-65-4330', - '987654330': '987-65-4330', - } - invalid = { - '078-05-1120': error_invalid, - } - self.assertFieldOutput(USSocialSecurityNumberField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavor/utils.py b/parts/django/tests/regressiontests/forms/localflavor/utils.py deleted file mode 100644 index a10258f..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/utils.py +++ /dev/null @@ -1,51 +0,0 @@ -from unittest import TestCase - -from django.core.exceptions import ValidationError -from django.core.validators import EMPTY_VALUES - - -class LocalFlavorTestCase(TestCase): - def assertFieldOutput(self, fieldclass, valid, invalid, field_args=[], - field_kwargs={}, empty_value=u''): - """Asserts that a field behaves correctly with various inputs. - - Args: - fieldclass: the class of the field to be tested. - valid: a dictionary mapping valid inputs to their expected - cleaned values. - invalid: a dictionary mapping invalid inputs to one or more - raised error messages. - fieldargs: the args passed to instantiate the field - fieldkwargs: the kwargs passed to instantiate the field - emptyvalue: the expected clean output for inputs in EMPTY_VALUES - """ - required = fieldclass(*field_args, **field_kwargs) - optional = fieldclass(*field_args, **dict(field_kwargs, required=False)) - # test valid inputs - for input, output in valid.items(): - self.assertEqual(required.clean(input), output) - self.assertEqual(optional.clean(input), output) - # test invalid inputs - for input, errors in invalid.items(): - try: - required.clean(input) - except ValidationError, e: - self.assertEqual(errors, e.messages) - else: - self.fail() - try: - optional.clean(input) - except ValidationError, e: - self.assertEqual(errors, e.messages) - else: - self.fail() - # test required inputs - error_required = [u'This field is required.'] - for val in EMPTY_VALUES: - try: - required.clean(val) - except ValidationError, e: - self.assertEqual(error_required, e.messages) - else: - self.fail() - self.assertEqual(optional.clean(val), empty_value) diff --git a/parts/django/tests/regressiontests/forms/localflavor/uy.py b/parts/django/tests/regressiontests/forms/localflavor/uy.py deleted file mode 100644 index 2b9e134..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/uy.py +++ /dev/null @@ -1,52 +0,0 @@ -from django.contrib.localflavor.uy.forms import UYDepartamentSelect, UYCIField -from django.contrib.localflavor.uy.util import get_validation_digit - -from utils import LocalFlavorTestCase - - -class UYLocalFlavorTests(LocalFlavorTestCase): - def test_UYDepartmentSelect(self): - f = UYDepartamentSelect() - out = u'''<select name="departamentos"> -<option value="G">Artigas</option> -<option value="A">Canelones</option> -<option value="E">Cerro Largo</option> -<option value="L">Colonia</option> -<option value="Q">Durazno</option> -<option value="N">Flores</option> -<option value="O">Florida</option> -<option value="P">Lavalleja</option> -<option value="B">Maldonado</option> -<option value="S" selected="selected">Montevideo</option> -<option value="I">Paysand\xfa</option> -<option value="J">R\xedo Negro</option> -<option value="F">Rivera</option> -<option value="C">Rocha</option> -<option value="H">Salto</option> -<option value="M">San Jos\xe9</option> -<option value="K">Soriano</option> -<option value="R">Tacuaremb\xf3</option> -<option value="D">Treinta y Tres</option> -</select>''' - self.assertEqual(f.render('departamentos', 'S'), out) - - def test_UYCIField(self): - error_format = [u'Enter a valid CI number in X.XXX.XXX-X,XXXXXXX-X or XXXXXXXX format.'] - error_invalid = [u'Enter a valid CI number.'] - valid = { - '4098053': '4098053', - '409805-3': '409805-3', - '409.805-3': '409.805-3', - '10054112': '10054112', - '1005411-2': '1005411-2', - '1.005.411-2': '1.005.411-2', - } - invalid = { - 'foo': [u'Enter a valid CI number in X.XXX.XXX-X,XXXXXXX-X or XXXXXXXX format.'], - '409805-2': [u'Enter a valid CI number.'], - '1.005.411-5': [u'Enter a valid CI number.'], - } - self.assertFieldOutput(UYCIField, valid, invalid) - self.assertEqual(get_validation_digit(409805), 3) - self.assertEqual(get_validation_digit(1005411), 2) - diff --git a/parts/django/tests/regressiontests/forms/localflavor/za.py b/parts/django/tests/regressiontests/forms/localflavor/za.py deleted file mode 100644 index c912421..0000000 --- a/parts/django/tests/regressiontests/forms/localflavor/za.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.contrib.localflavor.za.forms import ZAIDField, ZAPostCodeField - -from utils import LocalFlavorTestCase - - -class ZALocalFlavorTests(LocalFlavorTestCase): - def test_ZAIDField(self): - error_invalid = [u'Enter a valid South African ID number'] - valid = { - '0002290001003': '0002290001003', - '000229 0001 003': '0002290001003', - } - invalid = { - '0102290001001': error_invalid, - '811208': error_invalid, - '0002290001004': error_invalid, - } - self.assertFieldOutput(ZAIDField, valid, invalid) - - def test_ZAPostCodeField(self): - error_invalid = [u'Enter a valid South African postal code'] - valid = { - '0000': '0000', - } - invalid = { - 'abcd': error_invalid, - ' 7530': error_invalid, - } - self.assertFieldOutput(ZAPostCodeField, valid, invalid) diff --git a/parts/django/tests/regressiontests/forms/localflavortests.py b/parts/django/tests/regressiontests/forms/localflavortests.py deleted file mode 100644 index 2582656..0000000 --- a/parts/django/tests/regressiontests/forms/localflavortests.py +++ /dev/null @@ -1,37 +0,0 @@ -from localflavor.cz import tests as localflavor_cz_tests -from localflavor.se import tests as localflavor_se_tests - -from localflavor.ar import ARLocalFlavorTests -from localflavor.at import ATLocalFlavorTests -from localflavor.au import AULocalFlavorTests -from localflavor.at import ATLocalFlavorTests -from localflavor.br import BRLocalFlavorTests -from localflavor.ca import CALocalFlavorTests -from localflavor.ch import CHLocalFlavorTests -from localflavor.cl import CLLocalFlavorTests -from localflavor.de import DELocalFlavorTests -from localflavor.es import ESLocalFlavorTests -from localflavor.fi import FILocalFlavorTests -from localflavor.fr import FRLocalFlavorTests -from localflavor.generic import GenericLocalFlavorTests -from localflavor.id import IDLocalFlavorTests -from localflavor.ie import IELocalFlavorTests -from localflavor.is_ import ISLocalFlavorTests -from localflavor.it import ITLocalFlavorTests -from localflavor.jp import JPLocalFlavorTests -from localflavor.kw import KWLocalFlavorTests -from localflavor.nl import NLLocalFlavorTests -from localflavor.pl import PLLocalFlavorTests -from localflavor.pt import PTLocalFlavorTests -from localflavor.ro import ROLocalFlavorTests -from localflavor.sk import SKLocalFlavorTests -from localflavor.uk import UKLocalFlavorTests -from localflavor.us import USLocalFlavorTests -from localflavor.uy import UYLocalFlavorTests -from localflavor.za import ZALocalFlavorTests - - -__test__ = { - 'localflavor_cz_tests': localflavor_cz_tests, - 'localflavor_se_tests': localflavor_se_tests, -} diff --git a/parts/django/tests/regressiontests/forms/models.py b/parts/django/tests/regressiontests/forms/models.py deleted file mode 100644 index 203980c..0000000 --- a/parts/django/tests/regressiontests/forms/models.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -import tempfile - -from django.db import models -from django.core.files.storage import FileSystemStorage - - -temp_storage_location = tempfile.mkdtemp() -temp_storage = FileSystemStorage(location=temp_storage_location) - - -class BoundaryModel(models.Model): - positive_integer = models.PositiveIntegerField(null=True, blank=True) - - -callable_default_value = 0 -def callable_default(): - global callable_default_value - callable_default_value = callable_default_value + 1 - return callable_default_value - - -class Defaults(models.Model): - name = models.CharField(max_length=255, default='class default value') - def_date = models.DateField(default = datetime.date(1980, 1, 1)) - value = models.IntegerField(default=42) - callable_default = models.IntegerField(default=callable_default) - - -class ChoiceModel(models.Model): - """For ModelChoiceField and ModelMultipleChoiceField tests.""" - name = models.CharField(max_length=10) - - -class ChoiceOptionModel(models.Model): - """Destination for ChoiceFieldModel's ForeignKey. - Can't reuse ChoiceModel because error_message tests require that it have no instances.""" - name = models.CharField(max_length=10) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return u'ChoiceOption %d' % self.pk - - -class ChoiceFieldModel(models.Model): - """Model with ForeignKey to another model, for testing ModelForm - generation with ModelChoiceField.""" - choice = models.ForeignKey(ChoiceOptionModel, blank=False, - default=lambda: ChoiceOptionModel.objects.get(name='default')) - choice_int = models.ForeignKey(ChoiceOptionModel, blank=False, related_name='choice_int', - default=lambda: 1) - - multi_choice = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='multi_choice', - default=lambda: ChoiceOptionModel.objects.filter(name='default')) - multi_choice_int = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='multi_choice_int', - default=lambda: [1]) - - -class FileModel(models.Model): - file = models.FileField(storage=temp_storage, upload_to='tests') - - -class Group(models.Model): - name = models.CharField(max_length=10) - - def __unicode__(self): - return u'%s' % self.name - - -class Cheese(models.Model): - name = models.CharField(max_length=100) diff --git a/parts/django/tests/regressiontests/forms/tests/__init__.py b/parts/django/tests/regressiontests/forms/tests/__init__.py deleted file mode 100644 index 95df6a1..0000000 --- a/parts/django/tests/regressiontests/forms/tests/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -from error_messages import * -from extra import * -from fields import FieldsTests -from forms import * -from formsets import * -from input_formats import * -from media import * -from models import * -from regressions import * -from util import * -from validators import TestFieldWithValidators -from widgets import * - -from regressiontests.forms.localflavortests import ( - __test__, - ARLocalFlavorTests, - ATLocalFlavorTests, - AULocalFlavorTests, - BRLocalFlavorTests, - CALocalFlavorTests, - CHLocalFlavorTests, - CLLocalFlavorTests, - DELocalFlavorTests, - ESLocalFlavorTests, - FILocalFlavorTests, - FRLocalFlavorTests, - GenericLocalFlavorTests, - IDLocalFlavorTests, - IELocalFlavorTests, - ISLocalFlavorTests, - ITLocalFlavorTests, - JPLocalFlavorTests, - KWLocalFlavorTests, - NLLocalFlavorTests, - PLLocalFlavorTests, - PTLocalFlavorTests, - ROLocalFlavorTests, - SKLocalFlavorTests, - UKLocalFlavorTests, - USLocalFlavorTests, - UYLocalFlavorTests, - ZALocalFlavorTests, -) diff --git a/parts/django/tests/regressiontests/forms/tests/error_messages.py b/parts/django/tests/regressiontests/forms/tests/error_messages.py deleted file mode 100644 index 39d88a6..0000000 --- a/parts/django/tests/regressiontests/forms/tests/error_messages.py +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest -from django.core.files.uploadedfile import SimpleUploadedFile -from django.forms import * -from django.test import TestCase -from django.utils.safestring import mark_safe - -class AssertFormErrorsMixin(object): - def assertFormErrors(self, expected, the_callable, *args, **kwargs): - try: - the_callable(*args, **kwargs) - self.fail("Testing the 'clean' method on %s failed to raise a ValidationError.") - except ValidationError, e: - self.assertEqual(e.messages, expected) - - -class FormsErrorMessagesTestCase(unittest.TestCase, AssertFormErrorsMixin): - def test_charfield(self): - e = { - 'required': 'REQUIRED', - 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', - 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', - } - f = CharField(min_length=5, max_length=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'LENGTH 4, MIN LENGTH 5'], f.clean, '1234') - self.assertFormErrors([u'LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901') - - def test_integerfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'min_value': 'MIN VALUE IS %(limit_value)s', - 'max_value': 'MAX VALUE IS %(limit_value)s', - } - f = IntegerField(min_value=5, max_value=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - self.assertFormErrors([u'MIN VALUE IS 5'], f.clean, '4') - self.assertFormErrors([u'MAX VALUE IS 10'], f.clean, '11') - - def test_floatfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'min_value': 'MIN VALUE IS %(limit_value)s', - 'max_value': 'MAX VALUE IS %(limit_value)s', - } - f = FloatField(min_value=5, max_value=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - self.assertFormErrors([u'MIN VALUE IS 5'], f.clean, '4') - self.assertFormErrors([u'MAX VALUE IS 10'], f.clean, '11') - - def test_decimalfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'min_value': 'MIN VALUE IS %(limit_value)s', - 'max_value': 'MAX VALUE IS %(limit_value)s', - 'max_digits': 'MAX DIGITS IS %s', - 'max_decimal_places': 'MAX DP IS %s', - 'max_whole_digits': 'MAX DIGITS BEFORE DP IS %s', - } - f = DecimalField(min_value=5, max_value=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - self.assertFormErrors([u'MIN VALUE IS 5'], f.clean, '4') - self.assertFormErrors([u'MAX VALUE IS 10'], f.clean, '11') - - f2 = DecimalField(max_digits=4, decimal_places=2, error_messages=e) - self.assertFormErrors([u'MAX DIGITS IS 4'], f2.clean, '123.45') - self.assertFormErrors([u'MAX DP IS 2'], f2.clean, '1.234') - self.assertFormErrors([u'MAX DIGITS BEFORE DP IS 2'], f2.clean, '123.4') - - def test_datefield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - } - f = DateField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - - def test_timefield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - } - f = TimeField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - - def test_datetimefield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - } - f = DateTimeField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - - def test_regexfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', - 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', - } - f = RegexField(r'^\d+$', min_length=5, max_length=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abcde') - self.assertFormErrors([u'LENGTH 4, MIN LENGTH 5'], f.clean, '1234') - self.assertFormErrors([u'LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901') - - def test_emailfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', - 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', - } - f = EmailField(min_length=8, max_length=10, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abcdefgh') - self.assertFormErrors([u'LENGTH 7, MIN LENGTH 8'], f.clean, 'a@b.com') - self.assertFormErrors([u'LENGTH 11, MAX LENGTH 10'], f.clean, 'aye@bee.com') - - def test_filefield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'missing': 'MISSING', - 'empty': 'EMPTY FILE', - } - f = FileField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc') - self.assertFormErrors([u'EMPTY FILE'], f.clean, SimpleUploadedFile('name', None)) - self.assertFormErrors([u'EMPTY FILE'], f.clean, SimpleUploadedFile('name', '')) - - def test_urlfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID', - 'invalid_link': 'INVALID LINK', - } - f = URLField(verify_exists=True, error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID'], f.clean, 'abc.c') - self.assertFormErrors([u'INVALID LINK'], f.clean, 'http://www.broken.djangoproject.com') - - def test_booleanfield(self): - e = { - 'required': 'REQUIRED', - } - f = BooleanField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - - def test_choicefield(self): - e = { - 'required': 'REQUIRED', - 'invalid_choice': '%(value)s IS INVALID CHOICE', - } - f = ChoiceField(choices=[('a', 'aye')], error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'b IS INVALID CHOICE'], f.clean, 'b') - - def test_multiplechoicefield(self): - e = { - 'required': 'REQUIRED', - 'invalid_choice': '%(value)s IS INVALID CHOICE', - 'invalid_list': 'NOT A LIST', - } - f = MultipleChoiceField(choices=[('a', 'aye')], error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'NOT A LIST'], f.clean, 'b') - self.assertFormErrors([u'b IS INVALID CHOICE'], f.clean, ['b']) - - def test_splitdatetimefield(self): - e = { - 'required': 'REQUIRED', - 'invalid_date': 'INVALID DATE', - 'invalid_time': 'INVALID TIME', - } - f = SplitDateTimeField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID DATE', u'INVALID TIME'], f.clean, ['a', 'b']) - - def test_ipaddressfield(self): - e = { - 'required': 'REQUIRED', - 'invalid': 'INVALID IP ADDRESS', - } - f = IPAddressField(error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID IP ADDRESS'], f.clean, '127.0.0') - - def test_subclassing_errorlist(self): - class TestForm(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - def clean(self): - raise ValidationError("I like to be awkward.") - - class CustomErrorList(util.ErrorList): - def __unicode__(self): - return self.as_divs() - - def as_divs(self): - if not self: return u'' - return mark_safe(u'<div class="error">%s</div>' % ''.join([u'<p>%s</p>' % e for e in self])) - - # This form should print errors the default way. - form1 = TestForm({'first_name': 'John'}) - self.assertEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>') - self.assertEqual(str(form1.errors['__all__']), '<ul class="errorlist"><li>I like to be awkward.</li></ul>') - - # This one should wrap error groups in the customized way. - form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList) - self.assertEqual(str(form2['last_name'].errors), '<div class="error"><p>This field is required.</p></div>') - self.assertEqual(str(form2.errors['__all__']), '<div class="error"><p>I like to be awkward.</p></div>') - - -class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin): - def test_modelchoicefield(self): - # Create choices for the model choice field tests below. - from regressiontests.forms.models import ChoiceModel - c1 = ChoiceModel.objects.create(pk=1, name='a') - c2 = ChoiceModel.objects.create(pk=2, name='b') - c3 = ChoiceModel.objects.create(pk=3, name='c') - - # ModelChoiceField - e = { - 'required': 'REQUIRED', - 'invalid_choice': 'INVALID CHOICE', - } - f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'INVALID CHOICE'], f.clean, '4') - - # ModelMultipleChoiceField - e = { - 'required': 'REQUIRED', - 'invalid_choice': '%s IS INVALID CHOICE', - 'list': 'NOT A LIST OF VALUES', - } - f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) - self.assertFormErrors([u'REQUIRED'], f.clean, '') - self.assertFormErrors([u'NOT A LIST OF VALUES'], f.clean, '3') - self.assertFormErrors([u'4 IS INVALID CHOICE'], f.clean, ['4']) diff --git a/parts/django/tests/regressiontests/forms/tests/extra.py b/parts/django/tests/regressiontests/forms/tests/extra.py deleted file mode 100644 index bcdf4dd..0000000 --- a/parts/django/tests/regressiontests/forms/tests/extra.py +++ /dev/null @@ -1,610 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from decimal import Decimal -import re -import time -import unittest -from django.conf import settings -from django.forms import * -from django.forms.extras import SelectDateWidget -from django.forms.util import ErrorList -from django.test import TestCase -from django.utils import translation -from django.utils.encoding import force_unicode -from django.utils.encoding import smart_unicode -from error_messages import AssertFormErrorsMixin - - -class FormsExtraTestCase(unittest.TestCase, AssertFormErrorsMixin): - ############### - # Extra stuff # - ############### - - # The forms library comes with some extra, higher-level Field and Widget - def test_selectdate(self): - w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016')) - self.assertEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month"> -<option value="0">---</option> -<option value="1">January</option> -<option value="2">February</option> -<option value="3">March</option> -<option value="4">April</option> -<option value="5">May</option> -<option value="6">June</option> -<option value="7">July</option> -<option value="8">August</option> -<option value="9">September</option> -<option value="10">October</option> -<option value="11">November</option> -<option value="12">December</option> -</select> -<select name="mydate_day" id="id_mydate_day"> -<option value="0">---</option> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13">13</option> -<option value="14">14</option> -<option value="15">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31">31</option> -</select> -<select name="mydate_year" id="id_mydate_year"> -<option value="0">---</option> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - self.assertEqual(w.render('mydate', None), w.render('mydate', '')) - - self.assertEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month"> -<option value="1">January</option> -<option value="2">February</option> -<option value="3">March</option> -<option value="4" selected="selected">April</option> -<option value="5">May</option> -<option value="6">June</option> -<option value="7">July</option> -<option value="8">August</option> -<option value="9">September</option> -<option value="10">October</option> -<option value="11">November</option> -<option value="12">December</option> -</select> -<select name="mydate_day" id="id_mydate_day"> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13">13</option> -<option value="14">14</option> -<option value="15" selected="selected">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31">31</option> -</select> -<select name="mydate_year" id="id_mydate_year"> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010" selected="selected">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - - # Accepts a datetime or a string: - self.assertEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15')) - - # Invalid dates still render the failed date: - self.assertEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month"> -<option value="1">January</option> -<option value="2" selected="selected">February</option> -<option value="3">March</option> -<option value="4">April</option> -<option value="5">May</option> -<option value="6">June</option> -<option value="7">July</option> -<option value="8">August</option> -<option value="9">September</option> -<option value="10">October</option> -<option value="11">November</option> -<option value="12">December</option> -</select> -<select name="mydate_day" id="id_mydate_day"> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13">13</option> -<option value="14">14</option> -<option value="15">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31" selected="selected">31</option> -</select> -<select name="mydate_year" id="id_mydate_year"> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010" selected="selected">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - - # Using a SelectDateWidget in a form: - w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False) - self.assertEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month"> -<option value="0">---</option> -<option value="1">January</option> -<option value="2">February</option> -<option value="3">March</option> -<option value="4">April</option> -<option value="5">May</option> -<option value="6">June</option> -<option value="7">July</option> -<option value="8">August</option> -<option value="9">September</option> -<option value="10">October</option> -<option value="11">November</option> -<option value="12">December</option> -</select> -<select name="mydate_day" id="id_mydate_day"> -<option value="0">---</option> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13">13</option> -<option value="14">14</option> -<option value="15">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31">31</option> -</select> -<select name="mydate_year" id="id_mydate_year"> -<option value="0">---</option> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - self.assertEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month"> -<option value="0">---</option> -<option value="1">January</option> -<option value="2">February</option> -<option value="3">March</option> -<option value="4" selected="selected">April</option> -<option value="5">May</option> -<option value="6">June</option> -<option value="7">July</option> -<option value="8">August</option> -<option value="9">September</option> -<option value="10">October</option> -<option value="11">November</option> -<option value="12">December</option> -</select> -<select name="mydate_day" id="id_mydate_day"> -<option value="0">---</option> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13">13</option> -<option value="14">14</option> -<option value="15" selected="selected">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31">31</option> -</select> -<select name="mydate_year" id="id_mydate_year"> -<option value="0">---</option> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010" selected="selected">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - - class GetDate(Form): - mydate = DateField(widget=SelectDateWidget) - - a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'}) - self.assertTrue(a.is_valid()) - self.assertEqual(a.cleaned_data['mydate'], datetime.date(2008, 4, 1)) - - # As with any widget that implements get_value_from_datadict, - # we must be prepared to accept the input from the "as_hidden" - # rendering as well. - - self.assertEqual(a['mydate'].as_hidden(), '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />') - - b = GetDate({'mydate':'2008-4-1'}) - self.assertTrue(b.is_valid()) - self.assertEqual(b.cleaned_data['mydate'], datetime.date(2008, 4, 1)) - - def test_multiwidget(self): - # MultiWidget and MultiValueField ############################################# - # MultiWidgets are widgets composed of other widgets. They are usually - # combined with MultiValueFields - a field that is composed of other fields. - # MulitWidgets can themselved be composed of other MultiWidgets. - # SplitDateTimeWidget is one example of a MultiWidget. - - class ComplexMultiWidget(MultiWidget): - def __init__(self, attrs=None): - widgets = ( - TextInput(), - SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), - SplitDateTimeWidget(), - ) - super(ComplexMultiWidget, self).__init__(widgets, attrs) - - def decompress(self, value): - if value: - data = value.split(',') - return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])] - return [None, None, None] - - def format_output(self, rendered_widgets): - return u'\n'.join(rendered_widgets) - - w = ComplexMultiWidget() - self.assertEqual(w.render('name', 'some text,JP,2007-04-25 06:24:00'), """<input type="text" name="name_0" value="some text" /> -<select multiple="multiple" name="name_1"> -<option value="J" selected="selected">John</option> -<option value="P" selected="selected">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select> -<input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />""") - - class ComplexField(MultiValueField): - def __init__(self, required=True, widget=None, label=None, initial=None): - fields = ( - CharField(), - MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), - SplitDateTimeField() - ) - super(ComplexField, self).__init__(fields, required, widget, label, initial) - - def compress(self, data_list): - if data_list: - return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2]) - return None - - f = ComplexField(widget=w) - self.assertEqual(f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']]), u'some text,JP,2007-04-25 06:24:00') - self.assertFormErrors([u'Select a valid choice. X is not one of the available choices.'], f.clean, ['some text',['X'], ['2007-04-25','6:24:00']]) - - # If insufficient data is provided, None is substituted - self.assertFormErrors([u'This field is required.'], f.clean, ['some text',['JP']]) - - class ComplexFieldForm(Form): - field1 = ComplexField(widget=w) - - f = ComplexFieldForm() - self.assertEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" /> -<select multiple="multiple" name="field1_1" id="id_field1_1"> -<option value="J">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select> -<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>""") - - f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'}) - self.assertEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" /> -<select multiple="multiple" name="field1_1" id="id_field1_1"> -<option value="J" selected="selected">John</option> -<option value="P" selected="selected">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select> -<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>""") - - self.assertEqual(f.cleaned_data['field1'], u'some text,JP,2007-04-25 06:24:00') - - def test_ipaddress(self): - f = IPAddressField() - self.assertFormErrors([u'This field is required.'], f.clean, '') - self.assertFormErrors([u'This field is required.'], f.clean, None) - self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'foo') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '127.0.0.') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') - - f = IPAddressField(required=False) - self.assertEqual(f.clean(''), u'') - self.assertEqual(f.clean(None), u'') - self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'foo') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '127.0.0.') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') - self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') - - def test_smart_unicode(self): - class Test: - def __str__(self): - return 'ŠĐĆŽćžšđ' - - class TestU: - def __str__(self): - return 'Foo' - def __unicode__(self): - return u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111' - - self.assertEqual(smart_unicode(Test()), u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') - self.assertEqual(smart_unicode(TestU()), u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') - self.assertEqual(smart_unicode(1), u'1') - self.assertEqual(smart_unicode('foo'), u'foo') - - def test_accessing_clean(self): - class UserForm(Form): - username = CharField(max_length=10) - password = CharField(widget=PasswordInput) - - def clean(self): - data = self.cleaned_data - - if not self.errors: - data['username'] = data['username'].lower() - - return data - - f = UserForm({'username': 'SirRobin', 'password': 'blue'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data['username'], u'sirrobin') - - def test_overriding_errorlist(self): - class DivErrorList(ErrorList): - def __unicode__(self): - return self.as_divs() - - def as_divs(self): - if not self: return u'' - return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % force_unicode(e) for e in self]) - - class CommentForm(Form): - name = CharField(max_length=50, required=False) - email = EmailField() - comment = CharField() - - data = dict(email='invalid') - f = CommentForm(data, auto_id=False, error_class=DivErrorList) - self.assertEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p> -<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div> -<p>Email: <input type="text" name="email" value="invalid" /></p> -<div class="errorlist"><div class="error">This field is required.</div></div> -<p>Comment: <input type="text" name="comment" /></p>""") - - def test_multipart_encoded_form(self): - class FormWithoutFile(Form): - username = CharField() - - class FormWithFile(Form): - username = CharField() - file = FileField() - - class FormWithImage(Form): - image = ImageField() - - self.assertFalse(FormWithoutFile().is_multipart()) - self.assertTrue(FormWithFile().is_multipart()) - self.assertTrue(FormWithImage().is_multipart()) - - -class FormsExtraL10NTestCase(unittest.TestCase): - def setUp(self): - super(FormsExtraL10NTestCase, self).setUp() - self.old_use_l10n = getattr(settings, 'USE_L10N', False) - settings.USE_L10N = True - translation.activate('nl') - - def tearDown(self): - translation.deactivate() - settings.USE_L10N = self.old_use_l10n - super(FormsExtraL10NTestCase, self).tearDown() - - def test_l10n(self): - w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False) - self.assertEqual(w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-2010') - - self.assertEqual(w.render('date', '13-08-2010'), """<select name="date_day" id="id_date_day"> -<option value="0">---</option> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -<option value="6">6</option> -<option value="7">7</option> -<option value="8">8</option> -<option value="9">9</option> -<option value="10">10</option> -<option value="11">11</option> -<option value="12">12</option> -<option value="13" selected="selected">13</option> -<option value="14">14</option> -<option value="15">15</option> -<option value="16">16</option> -<option value="17">17</option> -<option value="18">18</option> -<option value="19">19</option> -<option value="20">20</option> -<option value="21">21</option> -<option value="22">22</option> -<option value="23">23</option> -<option value="24">24</option> -<option value="25">25</option> -<option value="26">26</option> -<option value="27">27</option> -<option value="28">28</option> -<option value="29">29</option> -<option value="30">30</option> -<option value="31">31</option> -</select> -<select name="date_month" id="id_date_month"> -<option value="0">---</option> -<option value="1">januari</option> -<option value="2">februari</option> -<option value="3">maart</option> -<option value="4">april</option> -<option value="5">mei</option> -<option value="6">juni</option> -<option value="7">juli</option> -<option value="8" selected="selected">augustus</option> -<option value="9">september</option> -<option value="10">oktober</option> -<option value="11">november</option> -<option value="12">december</option> -</select> -<select name="date_year" id="id_date_year"> -<option value="0">---</option> -<option value="2007">2007</option> -<option value="2008">2008</option> -<option value="2009">2009</option> -<option value="2010" selected="selected">2010</option> -<option value="2011">2011</option> -<option value="2012">2012</option> -<option value="2013">2013</option> -<option value="2014">2014</option> -<option value="2015">2015</option> -<option value="2016">2016</option> -</select>""") - - # Years before 1900 work - w = SelectDateWidget(years=('1899',)) - self.assertEqual(w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-1899') diff --git a/parts/django/tests/regressiontests/forms/tests/fields.py b/parts/django/tests/regressiontests/forms/tests/fields.py deleted file mode 100644 index 133a183..0000000 --- a/parts/django/tests/regressiontests/forms/tests/fields.py +++ /dev/null @@ -1,862 +0,0 @@ -# -*- coding: utf-8 -*- -""" -########## -# Fields # -########## - -Each Field class does some sort of validation. Each Field has a clean() method, -which either raises django.forms.ValidationError or returns the "clean" -data -- usually a Unicode object, but, in some rare cases, a list. - -Each Field's __init__() takes at least these parameters: - required -- Boolean that specifies whether the field is required. - True by default. - widget -- A Widget class, or instance of a Widget class, that should be - used for this Field when displaying it. Each Field has a default - Widget that it'll use if you don't specify this. In most cases, - the default widget is TextInput. - label -- A verbose name for this field, for use in displaying this field in - a form. By default, Django will use a "pretty" version of the form - field name, if the Field is part of a Form. - initial -- A value to use in this Field's initial display. This value is - *not* used as a fallback if data isn't given. - -Other than that, the Field subclasses have class-specific options for -__init__(). For example, CharField has a max_length option. -""" -import datetime -import time -import re -import os -from decimal import Decimal - -from unittest import TestCase - -from django.core.files.uploadedfile import SimpleUploadedFile -from django.forms import * -from django.forms.widgets import RadioFieldRenderer - - -def fix_os_paths(x): - if isinstance(x, basestring): - return x.replace('\\', '/') - elif isinstance(x, tuple): - return tuple(fix_os_paths(list(x))) - elif isinstance(x, list): - return [fix_os_paths(y) for y in x] - else: - return x - - -class FieldsTests(TestCase): - - def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - # CharField ################################################################### - - def test_charfield_1(self): - f = CharField() - self.assertEqual(u'1', f.clean(1)) - self.assertEqual(u'hello', f.clean('hello')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3])) - - def test_charfield_2(self): - f = CharField(required=False) - self.assertEqual(u'1', f.clean(1)) - self.assertEqual(u'hello', f.clean('hello')) - self.assertEqual(u'', f.clean(None)) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3])) - - def test_charfield_3(self): - f = CharField(max_length=10, required=False) - self.assertEqual(u'12345', f.clean('12345')) - self.assertEqual(u'1234567890', f.clean('1234567890')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '1234567890a') - - def test_charfield_4(self): - f = CharField(min_length=10, required=False) - self.assertEqual(u'', f.clean('')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345') - self.assertEqual(u'1234567890', f.clean('1234567890')) - self.assertEqual(u'1234567890a', f.clean('1234567890a')) - - def test_charfield_5(self): - f = CharField(min_length=10, required=True) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345') - self.assertEqual(u'1234567890', f.clean('1234567890')) - self.assertEqual(u'1234567890a', f.clean('1234567890a')) - - # IntegerField ################################################################ - - def test_integerfield_1(self): - f = IntegerField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(1, f.clean('1')) - self.assertEqual(True, isinstance(f.clean('1'), int)) - self.assertEqual(23, f.clean('23')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a') - self.assertEqual(42, f.clean(42)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 3.14) - self.assertEqual(1, f.clean('1 ')) - self.assertEqual(1, f.clean(' 1')) - self.assertEqual(1, f.clean(' 1 ')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a') - - def test_integerfield_2(self): - f = IntegerField(required=False) - self.assertEqual(None, f.clean('')) - self.assertEqual('None', repr(f.clean(''))) - self.assertEqual(None, f.clean(None)) - self.assertEqual('None', repr(f.clean(None))) - self.assertEqual(1, f.clean('1')) - self.assertEqual(True, isinstance(f.clean('1'), int)) - self.assertEqual(23, f.clean('23')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a') - self.assertEqual(1, f.clean('1 ')) - self.assertEqual(1, f.clean(' 1')) - self.assertEqual(1, f.clean(' 1 ')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a') - - def test_integerfield_3(self): - f = IntegerField(max_value=10) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(1, f.clean(1)) - self.assertEqual(10, f.clean(10)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, 11) - self.assertEqual(10, f.clean('10')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, '11') - - def test_integerfield_4(self): - f = IntegerField(min_value=10) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1) - self.assertEqual(10, f.clean(10)) - self.assertEqual(11, f.clean(11)) - self.assertEqual(10, f.clean('10')) - self.assertEqual(11, f.clean('11')) - - def test_integerfield_5(self): - f = IntegerField(min_value=10, max_value=20) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1) - self.assertEqual(10, f.clean(10)) - self.assertEqual(11, f.clean(11)) - self.assertEqual(10, f.clean('10')) - self.assertEqual(11, f.clean('11')) - self.assertEqual(20, f.clean(20)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 20.']", f.clean, 21) - - # FloatField ################################################################## - - def test_floatfield_1(self): - f = FloatField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(1.0, f.clean('1')) - self.assertEqual(True, isinstance(f.clean('1'), float)) - self.assertEqual(23.0, f.clean('23')) - self.assertEqual(3.1400000000000001, f.clean('3.14')) - self.assertEqual(3.1400000000000001, f.clean(3.14)) - self.assertEqual(42.0, f.clean(42)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a') - self.assertEqual(1.0, f.clean('1.0 ')) - self.assertEqual(1.0, f.clean(' 1.0')) - self.assertEqual(1.0, f.clean(' 1.0 ')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a') - - def test_floatfield_2(self): - f = FloatField(required=False) - self.assertEqual(None, f.clean('')) - self.assertEqual(None, f.clean(None)) - self.assertEqual(1.0, f.clean('1')) - - def test_floatfield_3(self): - f = FloatField(max_value=1.5, min_value=0.5) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4') - self.assertEqual(1.5, f.clean('1.5')) - self.assertEqual(0.5, f.clean('0.5')) - - # DecimalField ################################################################ - - def test_decimalfield_1(self): - f = DecimalField(max_digits=4, decimal_places=2) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(f.clean('1'), Decimal("1")) - self.assertEqual(True, isinstance(f.clean('1'), Decimal)) - self.assertEqual(f.clean('23'), Decimal("23")) - self.assertEqual(f.clean('3.14'), Decimal("3.14")) - self.assertEqual(f.clean(3.14), Decimal("3.14")) - self.assertEqual(f.clean(Decimal('3.14')), Decimal("3.14")) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'NaN') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'Inf') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '-Inf') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, u'łąść') - self.assertEqual(f.clean('1.0 '), Decimal("1.0")) - self.assertEqual(f.clean(' 1.0'), Decimal("1.0")) - self.assertEqual(f.clean(' 1.0 '), Decimal("1.0")) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '123.45') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '1.234') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 digits before the decimal point.']", f.clean, '123.4') - self.assertEqual(f.clean('-12.34'), Decimal("-12.34")) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-123.45') - self.assertEqual(f.clean('-.12'), Decimal("-0.12")) - self.assertEqual(f.clean('-00.12'), Decimal("-0.12")) - self.assertEqual(f.clean('-000.12'), Decimal("-0.12")) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '-000.123') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-000.12345') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '--0.12') - - def test_decimalfield_2(self): - f = DecimalField(max_digits=4, decimal_places=2, required=False) - self.assertEqual(None, f.clean('')) - self.assertEqual(None, f.clean(None)) - self.assertEqual(f.clean('1'), Decimal("1")) - - def test_decimalfield_3(self): - f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4') - self.assertEqual(f.clean('1.5'), Decimal("1.5")) - self.assertEqual(f.clean('0.5'), Decimal("0.5")) - self.assertEqual(f.clean('.5'), Decimal("0.5")) - self.assertEqual(f.clean('00.50'), Decimal("0.50")) - - def test_decimalfield_4(self): - f = DecimalField(decimal_places=2) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '0.00000001') - - def test_decimalfield_5(self): - f = DecimalField(max_digits=3) - # Leading whole zeros "collapse" to one digit. - self.assertEqual(f.clean('0000000.10'), Decimal("0.1")) - # But a leading 0 before the . doesn't count towards max_digits - self.assertEqual(f.clean('0000000.100'), Decimal("0.100")) - # Only leading whole zeros "collapse" to one digit. - self.assertEqual(f.clean('000000.02'), Decimal('0.02')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 3 digits in total.']", f.clean, '000000.0002') - self.assertEqual(f.clean('.002'), Decimal("0.002")) - - def test_decimalfield_6(self): - f = DecimalField(max_digits=2, decimal_places=2) - self.assertEqual(f.clean('.01'), Decimal(".01")) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 0 digits before the decimal point.']", f.clean, '1.1') - - # DateField ################################################################### - - def test_datefield_1(self): - f = DateField() - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006-10-25')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/2006')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/06')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('Oct 25 2006')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25 2006')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25, 2006')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October 2006')) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October, 2006')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-4-31') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '200a-10-25') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '25/10/06') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - - def test_datefield_2(self): - f = DateField(required=False) - self.assertEqual(None, f.clean(None)) - self.assertEqual('None', repr(f.clean(None))) - self.assertEqual(None, f.clean('')) - self.assertEqual('None', repr(f.clean(''))) - - def test_datefield_3(self): - f = DateField(input_formats=['%Y %m %d']) - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30))) - self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006 10 25')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-10-25') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/2006') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/06') - - # TimeField ################################################################### - - def test_timefield_1(self): - f = TimeField() - self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25))) - self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59))) - self.assertEqual(datetime.time(14, 25), f.clean('14:25')) - self.assertEqual(datetime.time(14, 25, 59), f.clean('14:25:59')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, 'hello') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '1:24 p.m.') - - def test_timefield_2(self): - f = TimeField(input_formats=['%I:%M %p']) - self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25))) - self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59))) - self.assertEqual(datetime.time(4, 25), f.clean('4:25 AM')) - self.assertEqual(datetime.time(16, 25), f.clean('4:25 PM')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '14:30:45') - - # DateTimeField ############################################################### - - def test_datetimefield_1(self): - f = DateTimeField() - self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('2006-10-25 14:30:45')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30:00')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30')) - self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('2006-10-25')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/2006 14:30:45')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30:00')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30')) - self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/2006')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/06 14:30:45')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30:00')) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30')) - self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/06')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, 'hello') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 4:30 p.m.') - - def test_datetimefield_2(self): - f = DateTimeField(input_formats=['%Y %m %d %I:%M %p']) - self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))) - self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006 10 25 2:30 PM')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 14:30:45') - - def test_datetimefield_3(self): - f = DateTimeField(required=False) - self.assertEqual(None, f.clean(None)) - self.assertEqual('None', repr(f.clean(None))) - self.assertEqual(None, f.clean('')) - self.assertEqual('None', repr(f.clean(''))) - - # RegexField ################################################################## - - def test_regexfield_1(self): - f = RegexField('^\d[A-F]\d$') - self.assertEqual(u'2A2', f.clean('2A2')) - self.assertEqual(u'3F3', f.clean('3F3')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - - def test_regexfield_2(self): - f = RegexField('^\d[A-F]\d$', required=False) - self.assertEqual(u'2A2', f.clean('2A2')) - self.assertEqual(u'3F3', f.clean('3F3')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3') - self.assertEqual(u'', f.clean('')) - - def test_regexfield_3(self): - f = RegexField(re.compile('^\d[A-F]\d$')) - self.assertEqual(u'2A2', f.clean('2A2')) - self.assertEqual(u'3F3', f.clean('3F3')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ') - - def test_regexfield_4(self): - f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.') - self.assertEqual(u'1234', f.clean('1234')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, '123') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, 'abcd') - - def test_regexfield_5(self): - f = RegexField('^\d+$', min_length=5, max_length=10) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).']", f.clean, '123') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).', u'Enter a valid value.']", f.clean, 'abc') - self.assertEqual(u'12345', f.clean('12345')) - self.assertEqual(u'1234567890', f.clean('1234567890')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '12345678901') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '12345a') - - # EmailField ################################################################## - - def test_emailfield_1(self): - f = EmailField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(u'person@example.com', f.clean('person@example.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@invalid-.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@-invalid.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.alid-.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.-alid.com') - self.assertEqual(u'example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com')) - self.assertEqual(u'example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@.com') - self.assertEqual(u'local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com', f.clean('local@domain.with.idn.xyzäöüßabc.part.com')) - - def test_email_regexp_for_performance(self): - f = EmailField() - # Check for runaway regex security problem. This will take for-freeking-ever - # if the security fix isn't in place. - self.assertRaisesErrorWithMessage( - ValidationError, - "[u'Enter a valid e-mail address.']", - f.clean, - 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058' - ) - - def test_emailfield_2(self): - f = EmailField(required=False) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'', f.clean(None)) - self.assertEqual(u'person@example.com', f.clean('person@example.com')) - self.assertEqual(u'example@example.com', f.clean(' example@example.com \t \t ')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar') - - def test_emailfield_3(self): - f = EmailField(min_length=10, max_length=15) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 9).']", f.clean, 'a@foo.com') - self.assertEqual(u'alf@foo.com', f.clean('alf@foo.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 15 characters (it has 20).']", f.clean, 'alf123456788@foo.com') - - # FileField ################################################################## - - def test_filefield_1(self): - f = FileField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '', '') - self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None, '') - self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', '')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''), '') - self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, 'some content that is not a file') - self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', None)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', '')) - self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content')))) - self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')))) - self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'), 'files/test4.pdf'))) - - def test_filefield_2(self): - f = FileField(max_length = 5) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this filename has at most 5 characters (it has 18).']", f.clean, SimpleUploadedFile('test_maxlength.txt', 'hello world')) - self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf')) - self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf')) - self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content')))) - - # URLField ################################################################## - - def test_urlfield_1(self): - f = URLField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(u'http://localhost/', f.clean('http://localhost')) - self.assertEqual(u'http://example.com/', f.clean('http://example.com')) - self.assertEqual(u'http://example.com./', f.clean('http://example.com.')) - self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com')) - self.assertEqual(u'http://www.example.com:8000/test', f.clean('http://www.example.com:8000/test')) - self.assertEqual(u'http://valid-with-hyphens.com/', f.clean('valid-with-hyphens.com')) - self.assertEqual(u'http://subdomain.domain.com/', f.clean('subdomain.domain.com')) - self.assertEqual(u'http://200.8.9.10/', f.clean('http://200.8.9.10')) - self.assertEqual(u'http://200.8.9.10:8000/test', f.clean('http://200.8.9.10:8000/test')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'com.') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, '.') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://invalid-.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://-invalid.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.alid-.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com') - self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com')) - self.assertEqual(u'http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah', f.clean('http://some.idn.xyzäöüßabc.domain.com:123/blah')) - self.assertEqual(u'http://www.example.com/s/http://code.djangoproject.com/ticket/13804', f.clean('www.example.com/s/http://code.djangoproject.com/ticket/13804')) - - def test_url_regex_ticket11198(self): - f = URLField() - # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*200,)) - - # a second test, to make sure the problem is really addressed, even on - # domains that don't fail the domain label length check in the regex - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,)) - - def test_urlfield_2(self): - f = URLField(required=False) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'', f.clean(None)) - self.assertEqual(u'http://example.com/', f.clean('http://example.com')) - self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com') - - def test_urlfield_3(self): - f = URLField(verify_exists=True) - self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example') - self.assertRaises(ValidationError, f.clean, 'http://www.broken.djangoproject.com') # bad domain - try: - f.clean('http://www.broken.djangoproject.com') # bad domain - except ValidationError, e: - self.assertEqual("[u'This URL appears to be a broken link.']", str(e)) - self.assertRaises(ValidationError, f.clean, 'http://google.com/we-love-microsoft.html') # good domain, bad page - try: - f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page - except ValidationError, e: - self.assertEqual("[u'This URL appears to be a broken link.']", str(e)) - # Valid and existent IDN - self.assertEqual(u'http://\u05e2\u05d1\u05e8\u05d9\u05ea.idn.icann.org/', f.clean(u'http://עברית.idn.icann.org/')) - # Valid but non-existent IDN - try: - f.clean(u'http://broken.עברית.idn.icann.org/') - except ValidationError, e: - self.assertEqual("[u'This URL appears to be a broken link.']", str(e)) - - def test_urlfield_4(self): - f = URLField(verify_exists=True, required=False) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection - - def test_urlfield_5(self): - f = URLField(min_length=15, max_length=20) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 15 characters (it has 13).']", f.clean, 'http://f.com') - self.assertEqual(u'http://example.com/', f.clean('http://example.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 38).']", f.clean, 'http://abcdefghijklmnopqrstuvwxyz.com') - - def test_urlfield_6(self): - f = URLField(required=False) - self.assertEqual(u'http://example.com/', f.clean('example.com')) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'https://example.com/', f.clean('https://example.com')) - - def test_urlfield_7(self): - f = URLField() - self.assertEqual(u'http://example.com/', f.clean('http://example.com')) - self.assertEqual(u'http://example.com/test', f.clean('http://example.com/test')) - - def test_urlfield_ticket11826(self): - f = URLField() - self.assertEqual(u'http://example.com/?some_param=some_value', f.clean('http://example.com?some_param=some_value')) - - # BooleanField ################################################################ - - def test_booleanfield_1(self): - f = BooleanField() - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(True, f.clean(True)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, False) - self.assertEqual(True, f.clean(1)) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 0) - self.assertEqual(True, f.clean('Django rocks')) - self.assertEqual(True, f.clean('True')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 'False') - - def test_booleanfield_2(self): - f = BooleanField(required=False) - self.assertEqual(False, f.clean('')) - self.assertEqual(False, f.clean(None)) - self.assertEqual(True, f.clean(True)) - self.assertEqual(False, f.clean(False)) - self.assertEqual(True, f.clean(1)) - self.assertEqual(False, f.clean(0)) - self.assertEqual(True, f.clean('1')) - self.assertEqual(False, f.clean('0')) - self.assertEqual(True, f.clean('Django rocks')) - self.assertEqual(False, f.clean('False')) - - # ChoiceField ################################################################# - - def test_choicefield_1(self): - f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')]) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual(u'1', f.clean(1)) - self.assertEqual(u'1', f.clean('1')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3') - - def test_choicefield_2(self): - f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False) - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'', f.clean(None)) - self.assertEqual(u'1', f.clean(1)) - self.assertEqual(u'1', f.clean('1')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3') - - def test_choicefield_3(self): - f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')]) - self.assertEqual(u'J', f.clean('J')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. John is not one of the available choices.']", f.clean, 'John') - - def test_choicefield_4(self): - f = ChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')]) - self.assertEqual(u'1', f.clean(1)) - self.assertEqual(u'1', f.clean('1')) - self.assertEqual(u'3', f.clean(3)) - self.assertEqual(u'3', f.clean('3')) - self.assertEqual(u'5', f.clean(5)) - self.assertEqual(u'5', f.clean('5')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, '6') - - # TypedChoiceField ############################################################ - # TypedChoiceField is just like ChoiceField, except that coerced types will - # be returned: - - def test_typedchoicefield_1(self): - f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int) - self.assertEqual(1, f.clean('1')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 2 is not one of the available choices.']", f.clean, '2') - - def test_typedchoicefield_2(self): - # Different coercion, same validation. - f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=float) - self.assertEqual(1.0, f.clean('1')) - - def test_typedchoicefield_3(self): - # This can also cause weirdness: be careful (bool(-1) == True, remember) - f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=bool) - self.assertEqual(True, f.clean('-1')) - - def test_typedchoicefield_4(self): - # Even more weirdness: if you have a valid choice but your coercion function - # can't coerce, you'll still get a validation error. Don't do this! - f = TypedChoiceField(choices=[('A', 'A'), ('B', 'B')], coerce=int) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. B is not one of the available choices.']", f.clean, 'B') - # Required fields require values - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - - def test_typedchoicefield_5(self): - # Non-required fields aren't required - f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False) - self.assertEqual('', f.clean('')) - # If you want cleaning an empty value to return a different type, tell the field - - def test_typedchoicefield_6(self): - f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None) - self.assertEqual(None, f.clean('')) - - # NullBooleanField ############################################################ - - def test_nullbooleanfield_1(self): - f = NullBooleanField() - self.assertEqual(None, f.clean('')) - self.assertEqual(True, f.clean(True)) - self.assertEqual(False, f.clean(False)) - self.assertEqual(None, f.clean(None)) - self.assertEqual(False, f.clean('0')) - self.assertEqual(True, f.clean('1')) - self.assertEqual(None, f.clean('2')) - self.assertEqual(None, f.clean('3')) - self.assertEqual(None, f.clean('hello')) - - - def test_nullbooleanfield_2(self): - # Make sure that the internal value is preserved if using HiddenInput (#7753) - class HiddenNullBooleanForm(Form): - hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True) - hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False) - f = HiddenNullBooleanForm() - self.assertEqual('<input type="hidden" name="hidden_nullbool1" value="True" id="id_hidden_nullbool1" /><input type="hidden" name="hidden_nullbool2" value="False" id="id_hidden_nullbool2" />', str(f)) - - def test_nullbooleanfield_3(self): - class HiddenNullBooleanForm(Form): - hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True) - hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False) - f = HiddenNullBooleanForm({ 'hidden_nullbool1': 'True', 'hidden_nullbool2': 'False' }) - self.assertEqual(None, f.full_clean()) - self.assertEqual(True, f.cleaned_data['hidden_nullbool1']) - self.assertEqual(False, f.cleaned_data['hidden_nullbool2']) - - def test_nullbooleanfield_4(self): - # Make sure we're compatible with MySQL, which uses 0 and 1 for its boolean - # values. (#9609) - NULLBOOL_CHOICES = (('1', 'Yes'), ('0', 'No'), ('', 'Unknown')) - class MySQLNullBooleanForm(Form): - nullbool0 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES)) - nullbool1 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES)) - nullbool2 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES)) - f = MySQLNullBooleanForm({ 'nullbool0': '1', 'nullbool1': '0', 'nullbool2': '' }) - self.assertEqual(None, f.full_clean()) - self.assertEqual(True, f.cleaned_data['nullbool0']) - self.assertEqual(False, f.cleaned_data['nullbool1']) - self.assertEqual(None, f.cleaned_data['nullbool2']) - - # MultipleChoiceField ######################################################### - - def test_multiplechoicefield_1(self): - f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')]) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertEqual([u'1'], f.clean([1])) - self.assertEqual([u'1'], f.clean(['1'])) - self.assertEqual([u'1', u'2'], f.clean(['1', '2'])) - self.assertEqual([u'1', u'2'], f.clean([1, '2'])) - self.assertEqual([u'1', u'2'], f.clean((1, '2'))) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, []) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ()) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3']) - - def test_multiplechoicefield_2(self): - f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False) - self.assertEqual([], f.clean('')) - self.assertEqual([], f.clean(None)) - self.assertEqual([u'1'], f.clean([1])) - self.assertEqual([u'1'], f.clean(['1'])) - self.assertEqual([u'1', u'2'], f.clean(['1', '2'])) - self.assertEqual([u'1', u'2'], f.clean([1, '2'])) - self.assertEqual([u'1', u'2'], f.clean((1, '2'))) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello') - self.assertEqual([], f.clean([])) - self.assertEqual([], f.clean(())) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3']) - - def test_multiplechoicefield_3(self): - f = MultipleChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')]) - self.assertEqual([u'1'], f.clean([1])) - self.assertEqual([u'1'], f.clean(['1'])) - self.assertEqual([u'1', u'5'], f.clean([1, 5])) - self.assertEqual([u'1', u'5'], f.clean([1, '5'])) - self.assertEqual([u'1', u'5'], f.clean(['1', 5])) - self.assertEqual([u'1', u'5'], f.clean(['1', '5'])) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['6']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['1','6']) - - # ComboField ################################################################## - - def test_combofield_1(self): - f = ComboField(fields=[CharField(max_length=20), EmailField()]) - self.assertEqual(u'test@example.com', f.clean('test@example.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 28).']", f.clean, 'longemailaddress@example.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'not an e-mail') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - - def test_combofield_2(self): - f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False) - self.assertEqual(u'test@example.com', f.clean('test@example.com')) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 28).']", f.clean, 'longemailaddress@example.com') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'not an e-mail') - self.assertEqual(u'', f.clean('')) - self.assertEqual(u'', f.clean(None)) - - # FilePathField ############################################################### - - def test_filepathfield_1(self): - path = os.path.abspath(forms.__file__) - path = os.path.dirname(path) + '/' - self.assertTrue(fix_os_paths(path).endswith('/django/forms/')) - - def test_filepathfield_2(self): - path = forms.__file__ - path = os.path.dirname(os.path.abspath(path)) + '/' - f = FilePathField(path=path) - f.choices = [p for p in f.choices if p[0].endswith('.py')] - f.choices.sort() - expected = [ - ('/django/forms/__init__.py', '__init__.py'), - ('/django/forms/fields.py', 'fields.py'), - ('/django/forms/forms.py', 'forms.py'), - ('/django/forms/formsets.py', 'formsets.py'), - ('/django/forms/models.py', 'models.py'), - ('/django/forms/util.py', 'util.py'), - ('/django/forms/widgets.py', 'widgets.py') - ] - for exp, got in zip(expected, fix_os_paths(f.choices)): - self.assertEqual(exp[1], got[1]) - self.assertTrue(got[0].endswith(exp[0])) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. fields.py is not one of the available choices.']", f.clean, 'fields.py') - assert fix_os_paths(f.clean(path + 'fields.py')).endswith('/django/forms/fields.py') - - def test_filepathfield_3(self): - path = forms.__file__ - path = os.path.dirname(os.path.abspath(path)) + '/' - f = FilePathField(path=path, match='^.*?\.py$') - f.choices.sort() - expected = [ - ('/django/forms/__init__.py', '__init__.py'), - ('/django/forms/fields.py', 'fields.py'), - ('/django/forms/forms.py', 'forms.py'), - ('/django/forms/formsets.py', 'formsets.py'), - ('/django/forms/models.py', 'models.py'), - ('/django/forms/util.py', 'util.py'), - ('/django/forms/widgets.py', 'widgets.py') - ] - for exp, got in zip(expected, fix_os_paths(f.choices)): - self.assertEqual(exp[1], got[1]) - self.assertTrue(got[0].endswith(exp[0])) - - def test_filepathfield_4(self): - path = os.path.abspath(forms.__file__) - path = os.path.dirname(path) + '/' - f = FilePathField(path=path, recursive=True, match='^.*?\.py$') - f.choices.sort() - expected = [ - ('/django/forms/__init__.py', '__init__.py'), - ('/django/forms/extras/__init__.py', 'extras/__init__.py'), - ('/django/forms/extras/widgets.py', 'extras/widgets.py'), - ('/django/forms/fields.py', 'fields.py'), - ('/django/forms/forms.py', 'forms.py'), - ('/django/forms/formsets.py', 'formsets.py'), - ('/django/forms/models.py', 'models.py'), - ('/django/forms/util.py', 'util.py'), - ('/django/forms/widgets.py', 'widgets.py') - ] - for exp, got in zip(expected, fix_os_paths(f.choices)): - self.assertEqual(exp[1], got[1]) - self.assertTrue(got[0].endswith(exp[0])) - - # SplitDateTimeField ########################################################## - - def test_splitdatetimefield_1(self): - from django.forms.widgets import SplitDateTimeWidget - f = SplitDateTimeField() - assert isinstance(f.widget, SplitDateTimeWidget) - self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) - self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.', u'Enter a valid time.']", f.clean, ['hello', 'there']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', 'there']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['hello', '07:30']) - - def test_splitdatetimefield_2(self): - f = SplitDateTimeField(required=False) - self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])) - self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean(['2006-01-10', '07:30'])) - self.assertEqual(None, f.clean(None)) - self.assertEqual(None, f.clean('')) - self.assertEqual(None, f.clean([''])) - self.assertEqual(None, f.clean(['', ''])) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello') - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.', u'Enter a valid time.']", f.clean, ['hello', 'there']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', 'there']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['hello', '07:30']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', '']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10']) - self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['', '07:30']) diff --git a/parts/django/tests/regressiontests/forms/tests/forms.py b/parts/django/tests/regressiontests/forms/tests/forms.py deleted file mode 100644 index e555a77..0000000 --- a/parts/django/tests/regressiontests/forms/tests/forms.py +++ /dev/null @@ -1,1700 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from decimal import Decimal -import re -import time -from unittest import TestCase -from django.core.files.uploadedfile import SimpleUploadedFile -from django.forms import * -from django.http import QueryDict -from django.template import Template, Context -from django.utils.datastructures import MultiValueDict, MergeDict -from django.utils.safestring import mark_safe - - -class Person(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - -class PersonNew(Form): - first_name = CharField(widget=TextInput(attrs={'id': 'first_name_id'})) - last_name = CharField() - birthday = DateField() - - -class FormsTestCase(TestCase): - # A Form is a collection of Fields. It knows how to validate a set of data and it - # knows how to render itself in a couple of default ways (e.g., an HTML table). - # You can pass it data in __init__(), as a dictionary. - - def test_form(self): - # Pass a dictionary to a Form's __init__(). - p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'}) - - self.assertTrue(p.is_bound) - self.assertEqual(p.errors, {}) - self.assertTrue(p.is_valid()) - self.assertEqual(p.errors.as_ul(), u'') - self.assertEqual(p.errors.as_text(), u'') - self.assertEqual(p.cleaned_data["first_name"], u'John') - self.assertEqual(p.cleaned_data["last_name"], u'Lennon') - self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9)) - self.assertEqual(str(p['first_name']), '<input type="text" name="first_name" value="John" id="id_first_name" />') - self.assertEqual(str(p['last_name']), '<input type="text" name="last_name" value="Lennon" id="id_last_name" />') - self.assertEqual(str(p['birthday']), '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />') - try: - p['nonexistentfield'] - self.fail('Attempts to access non-existent fields should fail.') - except KeyError: - pass - - form_output = [] - - for boundfield in p: - form_output.append(str(boundfield)) - - self.assertEqual('\n'.join(form_output), """<input type="text" name="first_name" value="John" id="id_first_name" /> -<input type="text" name="last_name" value="Lennon" id="id_last_name" /> -<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />""") - - form_output = [] - - for boundfield in p: - form_output.append([boundfield.label, boundfield.data]) - - self.assertEqual(form_output, [ - ['First name', u'John'], - ['Last name', u'Lennon'], - ['Birthday', u'1940-10-9'] - ]) - self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>""") - - def test_empty_dict(self): - # Empty dictionaries are valid, too. - p = Person({}) - self.assertTrue(p.is_bound) - self.assertEqual(p.errors['first_name'], [u'This field is required.']) - self.assertEqual(p.errors['last_name'], [u'This field is required.']) - self.assertEqual(p.errors['birthday'], [u'This field is required.']) - self.assertFalse(p.is_valid()) - try: - p.cleaned_data - self.fail('Attempts to access cleaned_data when validation fails should fail.') - except AttributeError: - pass - self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""") - self.assertEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>""") - self.assertEqual(p.as_p(), """<ul class="errorlist"><li>This field is required.</li></ul> -<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> -<ul class="errorlist"><li>This field is required.</li></ul> -<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> -<ul class="errorlist"><li>This field is required.</li></ul> -<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>""") - - def test_unbound_form(self): - # If you don't pass any values to the Form's __init__(), or if you pass None, - # the Form will be considered unbound and won't do any validation. Form.errors - # will be an empty dictionary *but* Form.is_valid() will return False. - p = Person() - self.assertFalse(p.is_bound) - self.assertEqual(p.errors, {}) - self.assertFalse(p.is_valid()) - try: - p.cleaned_data - self.fail('Attempts to access cleaned_data when validation fails should fail.') - except AttributeError: - pass - self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>""") - self.assertEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> -<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> -<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>""") - self.assertEqual(p.as_p(), """<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> -<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> -<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>""") - - def test_unicode_values(self): - # Unicode values are handled properly. - p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'}) - self.assertEqual(p.as_table(), u'<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>\n<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></td></tr>\n<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>') - self.assertEqual(p.as_ul(), u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>') - self.assertEqual(p.as_p(), u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>') - - p = Person({'last_name': u'Lennon'}) - self.assertEqual(p.errors['first_name'], [u'This field is required.']) - self.assertEqual(p.errors['birthday'], [u'This field is required.']) - self.assertFalse(p.is_valid()) - self.assertEqual(p.errors.as_ul(), u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>birthday<ul class="errorlist"><li>This field is required.</li></ul></li></ul>') - self.assertEqual(p.errors.as_text(), """* first_name - * This field is required. -* birthday - * This field is required.""") - try: - p.cleaned_data - self.fail('Attempts to access cleaned_data when validation fails should fail.') - except AttributeError: - pass - self.assertEqual(p['first_name'].errors, [u'This field is required.']) - self.assertEqual(p['first_name'].errors.as_ul(), u'<ul class="errorlist"><li>This field is required.</li></ul>') - self.assertEqual(p['first_name'].errors.as_text(), u'* This field is required.') - - p = Person() - self.assertEqual(str(p['first_name']), '<input type="text" name="first_name" id="id_first_name" />') - self.assertEqual(str(p['last_name']), '<input type="text" name="last_name" id="id_last_name" />') - self.assertEqual(str(p['birthday']), '<input type="text" name="birthday" id="id_birthday" />') - - def test_cleaned_data_only_fields(self): - # cleaned_data will always *only* contain a key for fields defined in the - # Form, even if you pass extra data when you define the Form. In this - # example, we pass a bunch of extra fields to the form constructor, - # but cleaned_data contains only the form's fields. - data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'} - p = Person(data) - self.assertTrue(p.is_valid()) - self.assertEqual(p.cleaned_data['first_name'], u'John') - self.assertEqual(p.cleaned_data['last_name'], u'Lennon') - self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9)) - - def test_optional_data(self): - # cleaned_data will include a key and value for *all* fields defined in the Form, - # even if the Form's data didn't include a value for fields that are not - # required. In this example, the data dictionary doesn't include a value for the - # "nick_name" field, but cleaned_data includes it. For CharFields, it's set to the - # empty string. - class OptionalPersonForm(Form): - first_name = CharField() - last_name = CharField() - nick_name = CharField(required=False) - - data = {'first_name': u'John', 'last_name': u'Lennon'} - f = OptionalPersonForm(data) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data['nick_name'], u'') - self.assertEqual(f.cleaned_data['first_name'], u'John') - self.assertEqual(f.cleaned_data['last_name'], u'Lennon') - - # For DateFields, it's set to None. - class OptionalPersonForm(Form): - first_name = CharField() - last_name = CharField() - birth_date = DateField(required=False) - - data = {'first_name': u'John', 'last_name': u'Lennon'} - f = OptionalPersonForm(data) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data['birth_date'], None) - self.assertEqual(f.cleaned_data['first_name'], u'John') - self.assertEqual(f.cleaned_data['last_name'], u'Lennon') - - def test_auto_id(self): - # "auto_id" tells the Form to add an "id" attribute to each form element. - # If it's a string that contains '%s', Django will use that as a format string - # into which the field's name will be inserted. It will also put a <label> around - # the human-readable labels for a field. - p = Person(auto_id='%s_id') - self.assertEqual(p.as_table(), """<tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr> -<tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr> -<tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li> -<li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li> -<li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>""") - self.assertEqual(p.as_p(), """<p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p> -<p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p> -<p><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>""") - - def test_auto_id_true(self): - # If auto_id is any True value whose str() does not contain '%s', the "id" - # attribute will be the name of the field. - p = Person(auto_id=True) - self.assertEqual(p.as_ul(), """<li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li> -<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li> -<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>""") - - def test_auto_id_false(self): - # If auto_id is any False value, an "id" attribute won't be output unless it - # was manually entered. - p = Person(auto_id=False) - self.assertEqual(p.as_ul(), """<li>First name: <input type="text" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /></li>""") - - def test_id_on_field(self): - # In this example, auto_id is False, but the "id" attribute for the "first_name" - # field is given. Also note that field gets a <label>, while the others don't. - p = PersonNew(auto_id=False) - self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /></li>""") - - def test_auto_id_on_form_and_field(self): - # If the "id" attribute is specified in the Form and auto_id is True, the "id" - # attribute in the Form gets precedence. - p = PersonNew(auto_id=True) - self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li> -<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li> -<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>""") - - def test_various_boolean_values(self): - class SignupForm(Form): - email = EmailField() - get_spam = BooleanField() - - f = SignupForm(auto_id=False) - self.assertEqual(str(f['email']), '<input type="text" name="email" />') - self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />') - - f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False) - self.assertEqual(str(f['email']), '<input type="text" name="email" value="test@example.com" />') - self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />') - - # 'True' or 'true' should be rendered without a value attribute - f = SignupForm({'email': 'test@example.com', 'get_spam': 'True'}, auto_id=False) - self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />') - - f = SignupForm({'email': 'test@example.com', 'get_spam': 'true'}, auto_id=False) - self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />') - - # A value of 'False' or 'false' should be rendered unchecked - f = SignupForm({'email': 'test@example.com', 'get_spam': 'False'}, auto_id=False) - self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />') - - f = SignupForm({'email': 'test@example.com', 'get_spam': 'false'}, auto_id=False) - self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />') - - def test_widget_output(self): - # Any Field can have a Widget class passed to its constructor: - class ContactForm(Form): - subject = CharField() - message = CharField(widget=Textarea) - - f = ContactForm(auto_id=False) - self.assertEqual(str(f['subject']), '<input type="text" name="subject" />') - self.assertEqual(str(f['message']), '<textarea rows="10" cols="40" name="message"></textarea>') - - # as_textarea(), as_text() and as_hidden() are shortcuts for changing the output - # widget type: - self.assertEqual(f['subject'].as_textarea(), u'<textarea rows="10" cols="40" name="subject"></textarea>') - self.assertEqual(f['message'].as_text(), u'<input type="text" name="message" />') - self.assertEqual(f['message'].as_hidden(), u'<input type="hidden" name="message" />') - - # The 'widget' parameter to a Field can also be an instance: - class ContactForm(Form): - subject = CharField() - message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20})) - - f = ContactForm(auto_id=False) - self.assertEqual(str(f['message']), '<textarea rows="80" cols="20" name="message"></textarea>') - - # Instance-level attrs are *not* carried over to as_textarea(), as_text() and - # as_hidden(): - self.assertEqual(f['message'].as_text(), u'<input type="text" name="message" />') - f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False) - self.assertEqual(f['subject'].as_textarea(), u'<textarea rows="10" cols="40" name="subject">Hello</textarea>') - self.assertEqual(f['message'].as_text(), u'<input type="text" name="message" value="I love you." />') - self.assertEqual(f['message'].as_hidden(), u'<input type="hidden" name="message" value="I love you." />') - - def test_forms_with_choices(self): - # For a form with a <select>, use ChoiceField: - class FrameworkForm(Form): - name = CharField() - language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')]) - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<select name="language"> -<option value="P">Python</option> -<option value="J">Java</option> -</select>""") - f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertEqual(str(f['language']), """<select name="language"> -<option value="P" selected="selected">Python</option> -<option value="J">Java</option> -</select>""") - - # A subtlety: If one of the choices' value is the empty string and the form is - # unbound, then the <option> for the empty-string choice will get selected="selected". - class FrameworkForm(Form): - name = CharField() - language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')]) - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<select name="language"> -<option value="" selected="selected">------</option> -<option value="P">Python</option> -<option value="J">Java</option> -</select>""") - - # You can specify widget attributes in the Widget constructor. - class FrameworkForm(Form): - name = CharField() - language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(attrs={'class': 'foo'})) - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<select class="foo" name="language"> -<option value="P">Python</option> -<option value="J">Java</option> -</select>""") - f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertEqual(str(f['language']), """<select class="foo" name="language"> -<option value="P" selected="selected">Python</option> -<option value="J">Java</option> -</select>""") - - # When passing a custom widget instance to ChoiceField, note that setting - # 'choices' on the widget is meaningless. The widget will use the choices - # defined on the Field, not the ones defined on the Widget. - class FrameworkForm(Form): - name = CharField() - language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(choices=[('R', 'Ruby'), ('P', 'Perl')], attrs={'class': 'foo'})) - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<select class="foo" name="language"> -<option value="P">Python</option> -<option value="J">Java</option> -</select>""") - f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertEqual(str(f['language']), """<select class="foo" name="language"> -<option value="P" selected="selected">Python</option> -<option value="J">Java</option> -</select>""") - - # You can set a ChoiceField's choices after the fact. - class FrameworkForm(Form): - name = CharField() - language = ChoiceField() - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<select name="language"> -</select>""") - f.fields['language'].choices = [('P', 'Python'), ('J', 'Java')] - self.assertEqual(str(f['language']), """<select name="language"> -<option value="P">Python</option> -<option value="J">Java</option> -</select>""") - - def test_forms_with_radio(self): - # Add widget=RadioSelect to use that widget with a ChoiceField. - class FrameworkForm(Form): - name = CharField() - language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=RadioSelect) - - f = FrameworkForm(auto_id=False) - self.assertEqual(str(f['language']), """<ul> -<li><label><input type="radio" name="language" value="P" /> Python</label></li> -<li><label><input type="radio" name="language" value="J" /> Java</label></li> -</ul>""") - self.assertEqual(f.as_table(), """<tr><th>Name:</th><td><input type="text" name="name" /></td></tr> -<tr><th>Language:</th><td><ul> -<li><label><input type="radio" name="language" value="P" /> Python</label></li> -<li><label><input type="radio" name="language" value="J" /> Java</label></li> -</ul></td></tr>""") - self.assertEqual(f.as_ul(), """<li>Name: <input type="text" name="name" /></li> -<li>Language: <ul> -<li><label><input type="radio" name="language" value="P" /> Python</label></li> -<li><label><input type="radio" name="language" value="J" /> Java</label></li> -</ul></li>""") - - # Regarding auto_id and <label>, RadioSelect is a special case. Each radio button - # gets a distinct ID, formed by appending an underscore plus the button's - # zero-based index. - f = FrameworkForm(auto_id='id_%s') - self.assertEqual(str(f['language']), """<ul> -<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> -<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> -</ul>""") - - # When RadioSelect is used with auto_id, and the whole form is printed using - # either as_table() or as_ul(), the label for the RadioSelect will point to the - # ID of the *first* radio button. - self.assertEqual(f.as_table(), """<tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" /></td></tr> -<tr><th><label for="id_language_0">Language:</label></th><td><ul> -<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> -<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> -</ul></td></tr>""") - self.assertEqual(f.as_ul(), """<li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li> -<li><label for="id_language_0">Language:</label> <ul> -<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> -<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> -</ul></li>""") - self.assertEqual(f.as_p(), """<p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> -<p><label for="id_language_0">Language:</label> <ul> -<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> -<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> -</ul></p>""") - - def test_forms_wit_hmultiple_choice(self): - # MultipleChoiceField is a special case, as its data is required to be a list: - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField() - - f = SongForm(auto_id=False) - self.assertEqual(str(f['composers']), """<select multiple="multiple" name="composers"> -</select>""") - - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')]) - - f = SongForm(auto_id=False) - self.assertEqual(str(f['composers']), """<select multiple="multiple" name="composers"> -<option value="J">John Lennon</option> -<option value="P">Paul McCartney</option> -</select>""") - f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False) - self.assertEqual(str(f['name']), '<input type="text" name="name" value="Yesterday" />') - self.assertEqual(str(f['composers']), """<select multiple="multiple" name="composers"> -<option value="J">John Lennon</option> -<option value="P" selected="selected">Paul McCartney</option> -</select>""") - - def test_hidden_data(self): - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')]) - - # MultipleChoiceField rendered as_hidden() is a special case. Because it can - # have multiple values, its as_hidden() renders multiple <input type="hidden"> - # tags. - f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False) - self.assertEqual(f['composers'].as_hidden(), '<input type="hidden" name="composers" value="P" />') - f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False) - self.assertEqual(f['composers'].as_hidden(), """<input type="hidden" name="composers" value="P" /> -<input type="hidden" name="composers" value="J" />""") - - def test_mulitple_choice_checkbox(self): - # MultipleChoiceField can also be used with the CheckboxSelectMultiple widget. - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) - - f = SongForm(auto_id=False) - self.assertEqual(str(f['composers']), """<ul> -<li><label><input type="checkbox" name="composers" value="J" /> John Lennon</label></li> -<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> -</ul>""") - f = SongForm({'composers': ['J']}, auto_id=False) - self.assertEqual(str(f['composers']), """<ul> -<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li> -<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> -</ul>""") - f = SongForm({'composers': ['J', 'P']}, auto_id=False) - self.assertEqual(str(f['composers']), """<ul> -<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li> -<li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> -</ul>""") - - def test_checkbox_auto_id(self): - # Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox - # gets a distinct ID, formed by appending an underscore plus the checkbox's - # zero-based index. - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) - - f = SongForm(auto_id='%s_id') - self.assertEqual(str(f['composers']), """<ul> -<li><label for="composers_id_0"><input type="checkbox" name="composers" value="J" id="composers_id_0" /> John Lennon</label></li> -<li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li> -</ul>""") - - def test_multiple_choice_list_data(self): - # Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and - # MergeDict (when created as a merge of MultiValueDicts) conveniently work with - # this. - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) - - data = {'name': 'Yesterday', 'composers': ['J', 'P']} - f = SongForm(data) - self.assertEqual(f.errors, {}) - - data = QueryDict('name=Yesterday&composers=J&composers=P') - f = SongForm(data) - self.assertEqual(f.errors, {}) - - data = MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])) - f = SongForm(data) - self.assertEqual(f.errors, {}) - - data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))) - f = SongForm(data) - self.assertEqual(f.errors, {}) - - def test_multiple_hidden(self): - class SongForm(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) - - # The MultipleHiddenInput widget renders multiple values as hidden fields. - class SongFormHidden(Form): - name = CharField() - composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=MultipleHiddenInput) - - f = SongFormHidden(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])), auto_id=False) - self.assertEqual(f.as_ul(), """<li>Name: <input type="text" name="name" value="Yesterday" /><input type="hidden" name="composers" value="J" /> -<input type="hidden" name="composers" value="P" /></li>""") - - # When using CheckboxSelectMultiple, the framework expects a list of input and - # returns a list of input. - f = SongForm({'name': 'Yesterday'}, auto_id=False) - self.assertEqual(f.errors['composers'], [u'This field is required.']) - f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False) - self.assertEqual(f.errors, {}) - self.assertEqual(f.cleaned_data['composers'], [u'J']) - self.assertEqual(f.cleaned_data['name'], u'Yesterday') - f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False) - self.assertEqual(f.errors, {}) - self.assertEqual(f.cleaned_data['composers'], [u'J', u'P']) - self.assertEqual(f.cleaned_data['name'], u'Yesterday') - - def test_escaping(self): - # Validation errors are HTML-escaped when output as HTML. - class EscapingForm(Form): - special_name = CharField(label="<em>Special</em> Field") - special_safe_name = CharField(label=mark_safe("<em>Special</em> Field")) - - def clean_special_name(self): - raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name']) - - def clean_special_safe_name(self): - raise ValidationError(mark_safe("'<b>%s</b>' is a safe string" % self.cleaned_data['special_safe_name'])) - - f = EscapingForm({'special_name': "Nothing to escape", 'special_safe_name': "Nothing to escape"}, auto_id=False) - self.assertEqual(f.as_table(), """<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>Something's wrong with 'Nothing to escape'</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr> -<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b>Nothing to escape</b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="Nothing to escape" /></td></tr>""") - f = EscapingForm({ - 'special_name': "Should escape < & > and <script>alert('xss')</script>", - 'special_safe_name': "<i>Do not escape</i>" - }, auto_id=False) - self.assertEqual(f.as_table(), """<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>Something's wrong with 'Should escape < & > and <script>alert('xss')</script>'</li></ul><input type="text" name="special_name" value="Should escape < & > and <script>alert('xss')</script>" /></td></tr> -<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b><i>Do not escape</i></b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="<i>Do not escape</i>" /></td></tr>""") - - def test_validating_multiple_fields(self): - # There are a couple of ways to do multiple-field validation. If you want the - # validation message to be associated with a particular field, implement the - # clean_XXX() method on the Form, where XXX is the field name. As in - # Field.clean(), the clean_XXX() method should return the cleaned value. In the - # clean_XXX() method, you have access to self.cleaned_data, which is a dictionary - # of all the data that has been cleaned *so far*, in order by the fields, - # including the current field (e.g., the field XXX if you're in clean_XXX()). - class UserRegistration(Form): - username = CharField(max_length=10) - password1 = CharField(widget=PasswordInput) - password2 = CharField(widget=PasswordInput) - - def clean_password2(self): - if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']: - raise ValidationError(u'Please make sure your passwords match.') - - return self.cleaned_data['password2'] - - f = UserRegistration(auto_id=False) - self.assertEqual(f.errors, {}) - f = UserRegistration({}, auto_id=False) - self.assertEqual(f.errors['username'], [u'This field is required.']) - self.assertEqual(f.errors['password1'], [u'This field is required.']) - self.assertEqual(f.errors['password2'], [u'This field is required.']) - f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False) - self.assertEqual(f.errors['password2'], [u'Please make sure your passwords match.']) - f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) - self.assertEqual(f.errors, {}) - self.assertEqual(f.cleaned_data['username'], u'adrian') - self.assertEqual(f.cleaned_data['password1'], u'foo') - self.assertEqual(f.cleaned_data['password2'], u'foo') - - # Another way of doing multiple-field validation is by implementing the - # Form's clean() method. If you do this, any ValidationError raised by that - # method will not be associated with a particular field; it will have a - # special-case association with the field named '__all__'. - # Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of - # all the fields/values that have *not* raised a ValidationError. Also note - # Form.clean() is required to return a dictionary of all clean data. - class UserRegistration(Form): - username = CharField(max_length=10) - password1 = CharField(widget=PasswordInput) - password2 = CharField(widget=PasswordInput) - - def clean(self): - if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']: - raise ValidationError(u'Please make sure your passwords match.') - - return self.cleaned_data - - f = UserRegistration(auto_id=False) - self.assertEqual(f.errors, {}) - f = UserRegistration({}, auto_id=False) - self.assertEqual(f.as_table(), """<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr> -<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr> -<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>""") - self.assertEqual(f.errors['username'], [u'This field is required.']) - self.assertEqual(f.errors['password1'], [u'This field is required.']) - self.assertEqual(f.errors['password2'], [u'This field is required.']) - f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False) - self.assertEqual(f.errors['__all__'], [u'Please make sure your passwords match.']) - self.assertEqual(f.as_table(), """<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> -<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr> -<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr> -<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>""") - self.assertEqual(f.as_ul(), """<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li> -<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li> -<li>Password1: <input type="password" name="password1" value="foo" /></li> -<li>Password2: <input type="password" name="password2" value="bar" /></li>""") - f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) - self.assertEqual(f.errors, {}) - self.assertEqual(f.cleaned_data['username'], u'adrian') - self.assertEqual(f.cleaned_data['password1'], u'foo') - self.assertEqual(f.cleaned_data['password2'], u'foo') - - def test_dynamic_construction(self): - # It's possible to construct a Form dynamically by adding to the self.fields - # dictionary in __init__(). Don't forget to call Form.__init__() within the - # subclass' __init__(). - class Person(Form): - first_name = CharField() - last_name = CharField() - - def __init__(self, *args, **kwargs): - super(Person, self).__init__(*args, **kwargs) - self.fields['birthday'] = DateField() - - p = Person(auto_id=False) - self.assertEqual(p.as_table(), """<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr> -<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr> -<tr><th>Birthday:</th><td><input type="text" name="birthday" /></td></tr>""") - - # Instances of a dynamic Form do not persist fields from one Form instance to - # the next. - class MyForm(Form): - def __init__(self, data=None, auto_id=False, field_list=[]): - Form.__init__(self, data, auto_id=auto_id) - - for field in field_list: - self.fields[field[0]] = field[1] - - field_list = [('field1', CharField()), ('field2', CharField())] - my_form = MyForm(field_list=field_list) - self.assertEqual(my_form.as_table(), """<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr> -<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>""") - field_list = [('field3', CharField()), ('field4', CharField())] - my_form = MyForm(field_list=field_list) - self.assertEqual(my_form.as_table(), """<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr> -<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>""") - - class MyForm(Form): - default_field_1 = CharField() - default_field_2 = CharField() - - def __init__(self, data=None, auto_id=False, field_list=[]): - Form.__init__(self, data, auto_id=auto_id) - - for field in field_list: - self.fields[field[0]] = field[1] - - field_list = [('field1', CharField()), ('field2', CharField())] - my_form = MyForm(field_list=field_list) - self.assertEqual(my_form.as_table(), """<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr> -<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr> -<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr> -<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>""") - field_list = [('field3', CharField()), ('field4', CharField())] - my_form = MyForm(field_list=field_list) - self.assertEqual(my_form.as_table(), """<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr> -<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr> -<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr> -<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>""") - - # Similarly, changes to field attributes do not persist from one Form instance - # to the next. - class Person(Form): - first_name = CharField(required=False) - last_name = CharField(required=False) - - def __init__(self, names_required=False, *args, **kwargs): - super(Person, self).__init__(*args, **kwargs) - - if names_required: - self.fields['first_name'].required = True - self.fields['first_name'].widget.attrs['class'] = 'required' - self.fields['last_name'].required = True - self.fields['last_name'].widget.attrs['class'] = 'required' - - f = Person(names_required=False) - self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (False, False)) - self.assertEqual(f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs, ({}, {})) - f = Person(names_required=True) - self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (True, True)) - self.assertEqual(f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs, ({'class': 'required'}, {'class': 'required'})) - f = Person(names_required=False) - self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (False, False)) - self.assertEqual(f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs, ({}, {})) - - class Person(Form): - first_name = CharField(max_length=30) - last_name = CharField(max_length=30) - - def __init__(self, name_max_length=None, *args, **kwargs): - super(Person, self).__init__(*args, **kwargs) - - if name_max_length: - self.fields['first_name'].max_length = name_max_length - self.fields['last_name'].max_length = name_max_length - - f = Person(name_max_length=None) - self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (30, 30)) - f = Person(name_max_length=20) - self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (20, 20)) - f = Person(name_max_length=None) - self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (30, 30)) - - def test_hidden_widget(self): - # HiddenInput widgets are displayed differently in the as_table(), as_ul()) - # and as_p() output of a Form -- their verbose names are not displayed, and a - # separate row is not displayed. They're displayed in the last row of the - # form, directly after that row's form element. - class Person(Form): - first_name = CharField() - last_name = CharField() - hidden_text = CharField(widget=HiddenInput) - birthday = DateField() - - p = Person(auto_id=False) - self.assertEqual(p.as_table(), """<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr> -<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr> -<tr><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li>First name: <input type="text" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li>""") - self.assertEqual(p.as_p(), """<p>First name: <input type="text" name="first_name" /></p> -<p>Last name: <input type="text" name="last_name" /></p> -<p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p>""") - - # With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. - p = Person(auto_id='id_%s') - self.assertEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr> -<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr> -<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> -<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> -<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></li>""") - self.assertEqual(p.as_p(), """<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> -<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> -<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></p>""") - - # If a field with a HiddenInput has errors, the as_table() and as_ul() output - # will include the error message(s) with the text "(Hidden field [fieldname]) " - # prepended. This message is displayed at the top of the output, regardless of - # its field's order in the form. - p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False) - self.assertEqual(p.as_table(), """<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr> -<tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr> -<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr> -<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>""") - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li> -<li>First name: <input type="text" name="first_name" value="John" /></li> -<li>Last name: <input type="text" name="last_name" value="Lennon" /></li> -<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li>""") - self.assertEqual(p.as_p(), """<ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul> -<p>First name: <input type="text" name="first_name" value="John" /></p> -<p>Last name: <input type="text" name="last_name" value="Lennon" /></p> -<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p>""") - - # A corner case: It's possible for a form to have only HiddenInputs. - class TestForm(Form): - foo = CharField(widget=HiddenInput) - bar = CharField(widget=HiddenInput) - - p = TestForm(auto_id=False) - self.assertEqual(p.as_table(), '<input type="hidden" name="foo" /><input type="hidden" name="bar" />') - self.assertEqual(p.as_ul(), '<input type="hidden" name="foo" /><input type="hidden" name="bar" />') - self.assertEqual(p.as_p(), '<input type="hidden" name="foo" /><input type="hidden" name="bar" />') - - def test_field_order(self): - # A Form's fields are displayed in the same order in which they were defined. - class TestForm(Form): - field1 = CharField() - field2 = CharField() - field3 = CharField() - field4 = CharField() - field5 = CharField() - field6 = CharField() - field7 = CharField() - field8 = CharField() - field9 = CharField() - field10 = CharField() - field11 = CharField() - field12 = CharField() - field13 = CharField() - field14 = CharField() - - p = TestForm(auto_id=False) - self.assertEqual(p.as_table(), """<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr> -<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr> -<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr> -<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr> -<tr><th>Field5:</th><td><input type="text" name="field5" /></td></tr> -<tr><th>Field6:</th><td><input type="text" name="field6" /></td></tr> -<tr><th>Field7:</th><td><input type="text" name="field7" /></td></tr> -<tr><th>Field8:</th><td><input type="text" name="field8" /></td></tr> -<tr><th>Field9:</th><td><input type="text" name="field9" /></td></tr> -<tr><th>Field10:</th><td><input type="text" name="field10" /></td></tr> -<tr><th>Field11:</th><td><input type="text" name="field11" /></td></tr> -<tr><th>Field12:</th><td><input type="text" name="field12" /></td></tr> -<tr><th>Field13:</th><td><input type="text" name="field13" /></td></tr> -<tr><th>Field14:</th><td><input type="text" name="field14" /></td></tr>""") - - def test_form_html_attributes(self): - # Some Field classes have an effect on the HTML attributes of their associated - # Widget. If you set max_length in a CharField and its associated widget is - # either a TextInput or PasswordInput, then the widget's rendered HTML will - # include the "maxlength" attribute. - class UserRegistration(Form): - username = CharField(max_length=10) # uses TextInput by default - password = CharField(max_length=10, widget=PasswordInput) - realname = CharField(max_length=10, widget=TextInput) # redundantly define widget, just to test - address = CharField() # no max_length defined here - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" maxlength="10" /></li> -<li>Password: <input type="password" name="password" maxlength="10" /></li> -<li>Realname: <input type="text" name="realname" maxlength="10" /></li> -<li>Address: <input type="text" name="address" /></li>""") - - # If you specify a custom "attrs" that includes the "maxlength" attribute, - # the Field's max_length attribute will override whatever "maxlength" you specify - # in "attrs". - class UserRegistration(Form): - username = CharField(max_length=10, widget=TextInput(attrs={'maxlength': 20})) - password = CharField(max_length=10, widget=PasswordInput) - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" maxlength="10" /></li> -<li>Password: <input type="password" name="password" maxlength="10" /></li>""") - - def test_specifying_labels(self): - # You can specify the label for a field by using the 'label' argument to a Field - # class. If you don't specify 'label', Django will use the field name with - # underscores converted to spaces, and the initial letter capitalized. - class UserRegistration(Form): - username = CharField(max_length=10, label='Your username') - password1 = CharField(widget=PasswordInput) - password2 = CharField(widget=PasswordInput, label='Password (again)') - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Your username: <input type="text" name="username" maxlength="10" /></li> -<li>Password1: <input type="password" name="password1" /></li> -<li>Password (again): <input type="password" name="password2" /></li>""") - - # Labels for as_* methods will only end in a colon if they don't end in other - # punctuation already. - class Questions(Form): - q1 = CharField(label='The first question') - q2 = CharField(label='What is your name?') - q3 = CharField(label='The answer to life is:') - q4 = CharField(label='Answer this question!') - q5 = CharField(label='The last question. Period.') - - self.assertEqual(Questions(auto_id=False).as_p(), """<p>The first question: <input type="text" name="q1" /></p> -<p>What is your name? <input type="text" name="q2" /></p> -<p>The answer to life is: <input type="text" name="q3" /></p> -<p>Answer this question! <input type="text" name="q4" /></p> -<p>The last question. Period. <input type="text" name="q5" /></p>""") - self.assertEqual(Questions().as_p(), """<p><label for="id_q1">The first question:</label> <input type="text" name="q1" id="id_q1" /></p> -<p><label for="id_q2">What is your name?</label> <input type="text" name="q2" id="id_q2" /></p> -<p><label for="id_q3">The answer to life is:</label> <input type="text" name="q3" id="id_q3" /></p> -<p><label for="id_q4">Answer this question!</label> <input type="text" name="q4" id="id_q4" /></p> -<p><label for="id_q5">The last question. Period.</label> <input type="text" name="q5" id="id_q5" /></p>""") - - # A label can be a Unicode object or a bytestring with special characters. - class UserRegistration(Form): - username = CharField(max_length=10, label='ŠĐĆŽćžšđ') - password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), u'<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="text" name="username" maxlength="10" /></li>\n<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="password" name="password" /></li>') - - # If a label is set to the empty string for a field, that field won't get a label. - class UserRegistration(Form): - username = CharField(max_length=10, label='') - password = CharField(widget=PasswordInput) - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li> <input type="text" name="username" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - p = UserRegistration(auto_id='id_%s') - self.assertEqual(p.as_ul(), """<li> <input id="id_username" type="text" name="username" maxlength="10" /></li> -<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>""") - - # If label is None, Django will auto-create the label from the field name. This - # is default behavior. - class UserRegistration(Form): - username = CharField(max_length=10, label=None) - password = CharField(widget=PasswordInput) - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - p = UserRegistration(auto_id='id_%s') - self.assertEqual(p.as_ul(), """<li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></li> -<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>""") - - def test_label_suffix(self): - # You can specify the 'label_suffix' argument to a Form class to modify the - # punctuation symbol used at the end of a label. By default, the colon (:) is - # used, and is only appended to the label if the label doesn't already end with a - # punctuation symbol: ., !, ? or :. If you specify a different suffix, it will - # be appended regardless of the last character of the label. - class FavoriteForm(Form): - color = CharField(label='Favorite color?') - animal = CharField(label='Favorite animal') - - f = FavoriteForm(auto_id=False) - self.assertEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li> -<li>Favorite animal: <input type="text" name="animal" /></li>""") - f = FavoriteForm(auto_id=False, label_suffix='?') - self.assertEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li> -<li>Favorite animal? <input type="text" name="animal" /></li>""") - f = FavoriteForm(auto_id=False, label_suffix='') - self.assertEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" /></li> -<li>Favorite animal <input type="text" name="animal" /></li>""") - f = FavoriteForm(auto_id=False, label_suffix=u'\u2192') - self.assertEqual(f.as_ul(), u'<li>Favorite color? <input type="text" name="color" /></li>\n<li>Favorite animal\u2192 <input type="text" name="animal" /></li>') - - def test_initial_data(self): - # You can specify initial data for a field by using the 'initial' argument to a - # Field class. This initial data is displayed when a Form is rendered with *no* - # data. It is not displayed when a Form is rendered with any data (including an - # empty dictionary). Also, the initial value is *not* used if data for a - # particular required field isn't provided. - class UserRegistration(Form): - username = CharField(max_length=10, initial='django') - password = CharField(widget=PasswordInput) - - # Here, we're not submitting any data, so the initial value will be displayed.) - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - - # Here, we're submitting data, so the initial value will *not* be displayed. - p = UserRegistration({}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - p = UserRegistration({'username': u''}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - p = UserRegistration({'username': u'foo'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - - # An 'initial' value is *not* used as a fallback if data is not provided. In this - # example, we don't provide a value for 'username', and the form raises a - # validation error rather than using the initial value for 'username'. - p = UserRegistration({'password': 'secret'}) - self.assertEqual(p.errors['username'], [u'This field is required.']) - self.assertFalse(p.is_valid()) - - def test_dynamic_initial_data(self): - # The previous technique dealt with "hard-coded" initial data, but it's also - # possible to specify initial data after you've already created the Form class - # (i.e., at runtime). Use the 'initial' parameter to the Form constructor. This - # should be a dictionary containing initial values for one or more fields in the - # form, keyed by field name. - class UserRegistration(Form): - username = CharField(max_length=10) - password = CharField(widget=PasswordInput) - - # Here, we're not submitting any data, so the initial value will be displayed.) - p = UserRegistration(initial={'username': 'django'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - p = UserRegistration(initial={'username': 'stephane'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - - # The 'initial' parameter is meaningless if you pass data. - p = UserRegistration({}, initial={'username': 'django'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - p = UserRegistration({'username': u''}, initial={'username': 'django'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - p = UserRegistration({'username': u'foo'}, initial={'username': 'django'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>""") - - # A dynamic 'initial' value is *not* used as a fallback if data is not provided. - # In this example, we don't provide a value for 'username', and the form raises a - # validation error rather than using the initial value for 'username'. - p = UserRegistration({'password': 'secret'}, initial={'username': 'django'}) - self.assertEqual(p.errors['username'], [u'This field is required.']) - self.assertFalse(p.is_valid()) - - # If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(), - # then the latter will get precedence. - class UserRegistration(Form): - username = CharField(max_length=10, initial='django') - password = CharField(widget=PasswordInput) - - p = UserRegistration(initial={'username': 'babik'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="babik" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li>""") - - def test_callable_initial_data(self): - # The previous technique dealt with raw values as initial data, but it's also - # possible to specify callable data. - class UserRegistration(Form): - username = CharField(max_length=10) - password = CharField(widget=PasswordInput) - options = MultipleChoiceField(choices=[('f','foo'),('b','bar'),('w','whiz')]) - - # We need to define functions that get called later.) - def initial_django(): - return 'django' - - def initial_stephane(): - return 'stephane' - - def initial_options(): - return ['f','b'] - - def initial_other_options(): - return ['b','w'] - - # Here, we're not submitting any data, so the initial value will be displayed.) - p = UserRegistration(initial={'username': initial_django, 'options': initial_options}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li> -<li>Options: <select multiple="multiple" name="options"> -<option value="f" selected="selected">foo</option> -<option value="b" selected="selected">bar</option> -<option value="w">whiz</option> -</select></li>""") - - # The 'initial' parameter is meaningless if you pass data. - p = UserRegistration({}, initial={'username': initial_django, 'options': initial_options}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Options: <select multiple="multiple" name="options"> -<option value="f">foo</option> -<option value="b">bar</option> -<option value="w">whiz</option> -</select></li>""") - p = UserRegistration({'username': u''}, initial={'username': initial_django}, auto_id=False) - self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Options: <select multiple="multiple" name="options"> -<option value="f">foo</option> -<option value="b">bar</option> -<option value="w">whiz</option> -</select></li>""") - p = UserRegistration({'username': u'foo', 'options':['f','b']}, initial={'username': initial_django}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li> -<li>Options: <select multiple="multiple" name="options"> -<option value="f" selected="selected">foo</option> -<option value="b" selected="selected">bar</option> -<option value="w">whiz</option> -</select></li>""") - - # A callable 'initial' value is *not* used as a fallback if data is not provided. - # In this example, we don't provide a value for 'username', and the form raises a - # validation error rather than using the initial value for 'username'. - p = UserRegistration({'password': 'secret'}, initial={'username': initial_django, 'options': initial_options}) - self.assertEqual(p.errors['username'], [u'This field is required.']) - self.assertFalse(p.is_valid()) - - # If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(), - # then the latter will get precedence. - class UserRegistration(Form): - username = CharField(max_length=10, initial=initial_django) - password = CharField(widget=PasswordInput) - options = MultipleChoiceField(choices=[('f','foo'),('b','bar'),('w','whiz')], initial=initial_other_options) - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li> -<li>Options: <select multiple="multiple" name="options"> -<option value="f">foo</option> -<option value="b" selected="selected">bar</option> -<option value="w" selected="selected">whiz</option> -</select></li>""") - p = UserRegistration(initial={'username': initial_stephane, 'options': initial_options}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li> -<li>Password: <input type="password" name="password" /></li> -<li>Options: <select multiple="multiple" name="options"> -<option value="f" selected="selected">foo</option> -<option value="b" selected="selected">bar</option> -<option value="w">whiz</option> -</select></li>""") - - def test_help_text(self): - # You can specify descriptive text for a field by using the 'help_text' argument) - class UserRegistration(Form): - username = CharField(max_length=10, help_text='e.g., user@example.com') - password = CharField(widget=PasswordInput, help_text='Choose wisely.') - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li> -<li>Password: <input type="password" name="password" /> Choose wisely.</li>""") - self.assertEqual(p.as_p(), """<p>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p> -<p>Password: <input type="password" name="password" /> Choose wisely.</p>""") - self.assertEqual(p.as_table(), """<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr> -<tr><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr>""") - - # The help text is displayed whether or not data is provided for the form. - p = UserRegistration({'username': u'foo'}, auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li> -<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li>""") - - # help_text is not displayed for hidden fields. It can be used for documentation - # purposes, though. - class UserRegistration(Form): - username = CharField(max_length=10, help_text='e.g., user@example.com') - password = CharField(widget=PasswordInput) - next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination') - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), """<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li> -<li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>""") - - # Help text can include arbitrary Unicode characters. - class UserRegistration(Form): - username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ') - - p = UserRegistration(auto_id=False) - self.assertEqual(p.as_ul(), u'<li>Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>') - - def test_subclassing_forms(self): - # You can subclass a Form to add fields. The resulting form subclass will have - # all of the fields of the parent Form, plus whichever fields you define in the - # subclass. - class Person(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - class Musician(Person): - instrument = CharField() - - p = Person(auto_id=False) - self.assertEqual(p.as_ul(), """<li>First name: <input type="text" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /></li>""") - m = Musician(auto_id=False) - self.assertEqual(m.as_ul(), """<li>First name: <input type="text" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /></li> -<li>Instrument: <input type="text" name="instrument" /></li>""") - - # Yes, you can subclass multiple forms. The fields are added in the order in - # which the parent classes are listed. - class Person(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - class Instrument(Form): - instrument = CharField() - - class Beatle(Person, Instrument): - haircut_type = CharField() - - b = Beatle(auto_id=False) - self.assertEqual(b.as_ul(), """<li>First name: <input type="text" name="first_name" /></li> -<li>Last name: <input type="text" name="last_name" /></li> -<li>Birthday: <input type="text" name="birthday" /></li> -<li>Instrument: <input type="text" name="instrument" /></li> -<li>Haircut type: <input type="text" name="haircut_type" /></li>""") - - def test_forms_with_prefixes(self): - # Sometimes it's necessary to have multiple forms display on the same HTML page, - # or multiple copies of the same form. We can accomplish this with form prefixes. - # Pass the keyword argument 'prefix' to the Form constructor to use this feature. - # This value will be prepended to each HTML form field name. One way to think - # about this is "namespaces for HTML forms". Notice that in the data argument, - # each field's key has the prefix, in this case 'person1', prepended to the - # actual field name. - class Person(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - data = { - 'person1-first_name': u'John', - 'person1-last_name': u'Lennon', - 'person1-birthday': u'1940-10-9' - } - p = Person(data, prefix='person1') - self.assertEqual(p.as_ul(), """<li><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /></li> -<li><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /></li> -<li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li>""") - self.assertEqual(str(p['first_name']), '<input type="text" name="person1-first_name" value="John" id="id_person1-first_name" />') - self.assertEqual(str(p['last_name']), '<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" />') - self.assertEqual(str(p['birthday']), '<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" />') - self.assertEqual(p.errors, {}) - self.assertTrue(p.is_valid()) - self.assertEqual(p.cleaned_data['first_name'], u'John') - self.assertEqual(p.cleaned_data['last_name'], u'Lennon') - self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9)) - - # Let's try submitting some bad data to make sure form.errors and field.errors - # work as expected. - data = { - 'person1-first_name': u'', - 'person1-last_name': u'', - 'person1-birthday': u'' - } - p = Person(data, prefix='person1') - self.assertEqual(p.errors['first_name'], [u'This field is required.']) - self.assertEqual(p.errors['last_name'], [u'This field is required.']) - self.assertEqual(p.errors['birthday'], [u'This field is required.']) - self.assertEqual(p['first_name'].errors, [u'This field is required.']) - try: - p['person1-first_name'].errors - self.fail('Attempts to access non-existent fields should fail.') - except KeyError: - pass - - # In this example, the data doesn't have a prefix, but the form requires it, so - # the form doesn't "see" the fields. - data = { - 'first_name': u'John', - 'last_name': u'Lennon', - 'birthday': u'1940-10-9' - } - p = Person(data, prefix='person1') - self.assertEqual(p.errors['first_name'], [u'This field is required.']) - self.assertEqual(p.errors['last_name'], [u'This field is required.']) - self.assertEqual(p.errors['birthday'], [u'This field is required.']) - - # With prefixes, a single data dictionary can hold data for multiple instances - # of the same form. - data = { - 'person1-first_name': u'John', - 'person1-last_name': u'Lennon', - 'person1-birthday': u'1940-10-9', - 'person2-first_name': u'Jim', - 'person2-last_name': u'Morrison', - 'person2-birthday': u'1943-12-8' - } - p1 = Person(data, prefix='person1') - self.assertTrue(p1.is_valid()) - self.assertEqual(p1.cleaned_data['first_name'], u'John') - self.assertEqual(p1.cleaned_data['last_name'], u'Lennon') - self.assertEqual(p1.cleaned_data['birthday'], datetime.date(1940, 10, 9)) - p2 = Person(data, prefix='person2') - self.assertTrue(p2.is_valid()) - self.assertEqual(p2.cleaned_data['first_name'], u'Jim') - self.assertEqual(p2.cleaned_data['last_name'], u'Morrison') - self.assertEqual(p2.cleaned_data['birthday'], datetime.date(1943, 12, 8)) - - # By default, forms append a hyphen between the prefix and the field name, but a - # form can alter that behavior by implementing the add_prefix() method. This - # method takes a field name and returns the prefixed field, according to - # self.prefix. - class Person(Form): - first_name = CharField() - last_name = CharField() - birthday = DateField() - - def add_prefix(self, field_name): - return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name - - p = Person(prefix='foo') - self.assertEqual(p.as_ul(), """<li><label for="id_foo-prefix-first_name">First name:</label> <input type="text" name="foo-prefix-first_name" id="id_foo-prefix-first_name" /></li> -<li><label for="id_foo-prefix-last_name">Last name:</label> <input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" /></li> -<li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li>""") - data = { - 'foo-prefix-first_name': u'John', - 'foo-prefix-last_name': u'Lennon', - 'foo-prefix-birthday': u'1940-10-9' - } - p = Person(data, prefix='foo') - self.assertTrue(p.is_valid()) - self.assertEqual(p.cleaned_data['first_name'], u'John') - self.assertEqual(p.cleaned_data['last_name'], u'Lennon') - self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9)) - - def test_forms_with_null_boolean(self): - # NullBooleanField is a bit of a special case because its presentation (widget) - # is different than its data. This is handled transparently, though. - class Person(Form): - name = CharField() - is_cool = NullBooleanField() - - p = Person({'name': u'Joe'}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select>""") - p = Person({'name': u'Joe', 'is_cool': u'1'}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select>""") - p = Person({'name': u'Joe', 'is_cool': u'2'}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2" selected="selected">Yes</option> -<option value="3">No</option> -</select>""") - p = Person({'name': u'Joe', 'is_cool': u'3'}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2">Yes</option> -<option value="3" selected="selected">No</option> -</select>""") - p = Person({'name': u'Joe', 'is_cool': True}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2" selected="selected">Yes</option> -<option value="3">No</option> -</select>""") - p = Person({'name': u'Joe', 'is_cool': False}, auto_id=False) - self.assertEqual(str(p['is_cool']), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2">Yes</option> -<option value="3" selected="selected">No</option> -</select>""") - - def test_forms_with_file_fields(self): - # FileFields are a special case because they take their data from the request.FILES, - # not request.POST. - class FileForm(Form): - file1 = FileField() - - f = FileForm(auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>') - - f = FileForm(data={}, files={}, auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="file" name="file1" /></td></tr>') - - f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', '')}, auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>The submitted file is empty.</li></ul><input type="file" name="file1" /></td></tr>') - - f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul><input type="file" name="file1" /></td></tr>') - - f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', 'some content')}, auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>') - self.assertTrue(f.is_valid()) - - f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')}, auto_id=False) - self.assertEqual(f.as_table(), '<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>') - - def test_basic_processing_in_view(self): - class UserRegistration(Form): - username = CharField(max_length=10) - password1 = CharField(widget=PasswordInput) - password2 = CharField(widget=PasswordInput) - - def clean(self): - if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']: - raise ValidationError(u'Please make sure your passwords match.') - - return self.cleaned_data - - def my_function(method, post_data): - if method == 'POST': - form = UserRegistration(post_data, auto_id=False) - else: - form = UserRegistration(auto_id=False) - - if form.is_valid(): - return 'VALID: %r' % form.cleaned_data - - t = Template('<form action="" method="post">\n<table>\n{{ form }}\n</table>\n<input type="submit" />\n</form>') - return t.render(Context({'form': form})) - - # Case 1: GET (an empty form, with no errors).) - self.assertEqual(my_function('GET', {}), """<form action="" method="post"> -<table> -<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr> -<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr> -<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr> -</table> -<input type="submit" /> -</form>""") - # Case 2: POST with erroneous data (a redisplayed form, with errors).) - self.assertEqual(my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'}), """<form action="" method="post"> -<table> -<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> -<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr> -<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr> -<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr> -</table> -<input type="submit" /> -</form>""") - # Case 3: POST with valid data (the success message).) - self.assertEqual(my_function('POST', {'username': 'adrian', 'password1': 'secret', 'password2': 'secret'}), "VALID: {'username': u'adrian', 'password1': u'secret', 'password2': u'secret'}") - - def test_templates_with_forms(self): - class UserRegistration(Form): - username = CharField(max_length=10, help_text="Good luck picking a username that doesn't already exist.") - password1 = CharField(widget=PasswordInput) - password2 = CharField(widget=PasswordInput) - - def clean(self): - if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']: - raise ValidationError(u'Please make sure your passwords match.') - - return self.cleaned_data - - # You have full flexibility in displaying form fields in a template. Just pass a - # Form instance to the template, and use "dot" access to refer to individual - # fields. Note, however, that this flexibility comes with the responsibility of - # displaying all the errors, including any that might not be associated with a - # particular field. - t = Template('''<form action=""> -{{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p> -{{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p> -{{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action=""> -<p><label>Your username: <input type="text" name="username" maxlength="10" /></label></p> -<p><label>Password: <input type="password" name="password1" /></label></p> -<p><label>Password (again): <input type="password" name="password2" /></label></p> -<input type="submit" /> -</form>""") - self.assertEqual(t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)})), """<form action=""> -<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p> -<ul class="errorlist"><li>This field is required.</li></ul><p><label>Password: <input type="password" name="password1" /></label></p> -<ul class="errorlist"><li>This field is required.</li></ul><p><label>Password (again): <input type="password" name="password2" /></label></p> -<input type="submit" /> -</form>""") - - # Use form.[field].label to output a field's label. You can specify the label for - # a field by using the 'label' argument to a Field class. If you don't specify - # 'label', Django will use the field name with underscores converted to spaces, - # and the initial letter capitalized. - t = Template('''<form action=""> -<p><label>{{ form.username.label }}: {{ form.username }}</label></p> -<p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p> -<p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action=""> -<p><label>Username: <input type="text" name="username" maxlength="10" /></label></p> -<p><label>Password1: <input type="password" name="password1" /></label></p> -<p><label>Password2: <input type="password" name="password2" /></label></p> -<input type="submit" /> -</form>""") - - # User form.[field].label_tag to output a field's label with a <label> tag - # wrapped around it, but *only* if the given field has an "id" attribute. - # Recall from above that passing the "auto_id" argument to a Form gives each - # field an "id" attribute. - t = Template('''<form action=""> -<p>{{ form.username.label_tag }}: {{ form.username }}</p> -<p>{{ form.password1.label_tag }}: {{ form.password1 }}</p> -<p>{{ form.password2.label_tag }}: {{ form.password2 }}</p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action=""> -<p>Username: <input type="text" name="username" maxlength="10" /></p> -<p>Password1: <input type="password" name="password1" /></p> -<p>Password2: <input type="password" name="password2" /></p> -<input type="submit" /> -</form>""") - self.assertEqual(t.render(Context({'form': UserRegistration(auto_id='id_%s')})), """<form action=""> -<p><label for="id_username">Username</label>: <input id="id_username" type="text" name="username" maxlength="10" /></p> -<p><label for="id_password1">Password1</label>: <input type="password" name="password1" id="id_password1" /></p> -<p><label for="id_password2">Password2</label>: <input type="password" name="password2" id="id_password2" /></p> -<input type="submit" /> -</form>""") - - # User form.[field].help_text to output a field's help text. If the given field - # does not have help text, nothing will be output. - t = Template('''<form action=""> -<p>{{ form.username.label_tag }}: {{ form.username }}<br />{{ form.username.help_text }}</p> -<p>{{ form.password1.label_tag }}: {{ form.password1 }}</p> -<p>{{ form.password2.label_tag }}: {{ form.password2 }}</p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action=""> -<p>Username: <input type="text" name="username" maxlength="10" /><br />Good luck picking a username that doesn't already exist.</p> -<p>Password1: <input type="password" name="password1" /></p> -<p>Password2: <input type="password" name="password2" /></p> -<input type="submit" /> -</form>""") - self.assertEqual(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. - f = UserRegistration(auto_id='id_%s') - form_output = [] - - for bf in f: - form_output.append(bf.label_tag(attrs={'class': 'pretty'})) - - self.assertEqual(form_output, [ - '<label for="id_username" class="pretty">Username</label>', - '<label for="id_password1" class="pretty">Password1</label>', - '<label for="id_password2" class="pretty">Password2</label>', - ]) - - # To display the errors that aren't associated with a particular field -- e.g., - # the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the - # template. If used on its own, it is displayed as a <ul> (or an empty string, if - # the list of errors is empty). You can also use it in {% if %} statements. - t = Template('''<form action=""> -{{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p> -{{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p> -{{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)})), """<form action=""> -<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p> -<p><label>Password: <input type="password" name="password1" value="foo" /></label></p> -<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p> -<input type="submit" /> -</form>""") - t = Template('''<form action=""> -{{ form.non_field_errors }} -{{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p> -{{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p> -{{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p> -<input type="submit" /> -</form>''') - self.assertEqual(t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)})), """<form action=""> -<ul class="errorlist"><li>Please make sure your passwords match.</li></ul> -<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p> -<p><label>Password: <input type="password" name="password1" value="foo" /></label></p> -<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p> -<input type="submit" /> -</form>""") - - def test_empty_permitted(self): - # Sometimes (pretty much in formsets) we want to allow a form to pass validation - # if it is completely empty. We can accomplish this by using the empty_permitted - # agrument to a form constructor. - class SongForm(Form): - artist = CharField() - name = CharField() - - # First let's show what happens id empty_permitted=False (the default): - data = {'artist': '', 'song': ''} - form = SongForm(data, empty_permitted=False) - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors, {'name': [u'This field is required.'], 'artist': [u'This field is required.']}) - try: - form.cleaned_data - self.fail('Attempts to access cleaned_data when validation fails should fail.') - except AttributeError: - pass - - # Now let's show what happens when empty_permitted=True and the form is empty. - form = SongForm(data, empty_permitted=True) - self.assertTrue(form.is_valid()) - self.assertEqual(form.errors, {}) - self.assertEqual(form.cleaned_data, {}) - - # But if we fill in data for one of the fields, the form is no longer empty and - # the whole thing must pass validation. - data = {'artist': 'The Doors', 'song': ''} - form = SongForm(data, empty_permitted=False) - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors, {'name': [u'This field is required.']}) - try: - form.cleaned_data - self.fail('Attempts to access cleaned_data when validation fails should fail.') - except AttributeError: - pass - - # If a field is not given in the data then None is returned for its data. Lets - # make sure that when checking for empty_permitted that None is treated - # accordingly. - data = {'artist': None, 'song': ''} - form = SongForm(data, empty_permitted=True) - self.assertTrue(form.is_valid()) - - # However, we *really* need to be sure we are checking for None as any data in - # initial that returns False on a boolean call needs to be treated literally. - class PriceForm(Form): - amount = FloatField() - qty = IntegerField() - - data = {'amount': '0.0', 'qty': ''} - form = PriceForm(data, initial={'amount': 0.0}, empty_permitted=True) - self.assertTrue(form.is_valid()) - - def test_extracting_hidden_and_visible(self): - class SongForm(Form): - token = CharField(widget=HiddenInput) - artist = CharField() - name = CharField() - - form = SongForm() - self.assertEqual([f.name for f in form.hidden_fields()], ['token']) - self.assertEqual([f.name for f in form.visible_fields()], ['artist', 'name']) - - def test_hidden_initial_gets_id(self): - class MyForm(Form): - field1 = CharField(max_length=50, show_hidden_initial=True) - - self.assertEqual(MyForm().as_table(), '<tr><th><label for="id_field1">Field1:</label></th><td><input id="id_field1" type="text" name="field1" maxlength="50" /><input type="hidden" name="initial-field1" id="initial-id_field1" /></td></tr>') - - def test_error_html_required_html_classes(self): - class Person(Form): - name = CharField() - is_cool = NullBooleanField() - email = EmailField(required=False) - age = IntegerField() - - p = Person({}) - p.error_css_class = 'error' - p.required_css_class = 'required' - - self.assertEqual(p.as_ul(), """<li class="required error"><ul class="errorlist"><li>This field is required.</li></ul><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li> -<li class="required"><label for="id_is_cool">Is cool:</label> <select name="is_cool" id="id_is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select></li> -<li><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></li> -<li class="required error"><ul class="errorlist"><li>This field is required.</li></ul><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></li>""") - - self.assertEqual(p.as_p(), """<ul class="errorlist"><li>This field is required.</li></ul> -<p class="required error"><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> -<p class="required"><label for="id_is_cool">Is cool:</label> <select name="is_cool" id="id_is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select></p> -<p><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></p> -<ul class="errorlist"><li>This field is required.</li></ul> -<p class="required error"><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></p>""") - - self.assertEqual(p.as_table(), """<tr class="required error"><th><label for="id_name">Name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="name" id="id_name" /></td></tr> -<tr class="required"><th><label for="id_is_cool">Is cool:</label></th><td><select name="is_cool" id="id_is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select></td></tr> -<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email" /></td></tr> -<tr class="required error"><th><label for="id_age">Age:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="age" id="id_age" /></td></tr>""") - - def test_label_split_datetime_not_displayed(self): - class EventForm(Form): - happened_at = SplitDateTimeField(widget=widgets.SplitHiddenDateTimeWidget) - - form = EventForm() - self.assertEqual(form.as_ul(), u'<input type="hidden" name="happened_at_0" id="id_happened_at_0" /><input type="hidden" name="happened_at_1" id="id_happened_at_1" />') diff --git a/parts/django/tests/regressiontests/forms/tests/formsets.py b/parts/django/tests/regressiontests/forms/tests/formsets.py deleted file mode 100644 index db94797..0000000 --- a/parts/django/tests/regressiontests/forms/tests/formsets.py +++ /dev/null @@ -1,763 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from django.forms import Form, CharField, IntegerField, ValidationError -from django.forms.formsets import formset_factory, BaseFormSet - - -class Choice(Form): - choice = CharField() - votes = IntegerField() - - -# FormSet allows us to use multiple instance of the same form on 1 page. For now, -# the best way to create a FormSet is by using the formset_factory function. -ChoiceFormSet = formset_factory(Choice) - - -class FavoriteDrinkForm(Form): - name = CharField() - - -class BaseFavoriteDrinksFormSet(BaseFormSet): - def clean(self): - seen_drinks = [] - - for drink in self.cleaned_data: - if drink['name'] in seen_drinks: - raise ValidationError('You may only specify a drink once.') - - seen_drinks.append(drink['name']) - - -# Let's define a FormSet that takes a list of favorite drinks, but raises an -# error if there are any duplicates. Used in ``test_clean_hook``, -# ``test_regression_6926`` & ``test_regression_12878``. -FavoriteDrinksFormSet = formset_factory(FavoriteDrinkForm, - formset=BaseFavoriteDrinksFormSet, extra=3) - - -class FormsFormsetTestCase(TestCase): - def test_basic_formset(self): - # A FormSet constructor takes the same arguments as Form. Let's create a FormSet - # for adding data. By default, it displays 1 blank form. It can display more, - # but we'll look at how to do so later. - formset = ChoiceFormSet(auto_id=False, prefix='choices') - self.assertEqual(str(formset), """<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" /> -<tr><th>Choice:</th><td><input type="text" name="choices-0-choice" /></td></tr> -<tr><th>Votes:</th><td><input type="text" name="choices-0-votes" /></td></tr>""") - - # On thing to note is that there needs to be a special value in the data. This - # value tells the FormSet how many forms were displayed so it can tell how - # many forms it needs to clean and validate. You could use javascript to create - # new forms on the client side, but they won't get validated unless you increment - # the TOTAL_FORMS field appropriately. - - data = { - 'choices-TOTAL_FORMS': '1', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - } - # We treat FormSet pretty much like we would treat a normal Form. FormSet has an - # is_valid method, and a cleaned_data or errors attribute depending on whether all - # the forms passed validation. However, unlike a Form instance, cleaned_data and - # errors will be a list of dicts rather than just a single dict. - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': u'Calexico'}]) - - # If a FormSet was not passed any data, its is_valid method should return False. - formset = ChoiceFormSet() - self.assertFalse(formset.is_valid()) - - def test_formset_validation(self): - # FormSet instances can also have an error attribute if validation failed for - # any of the forms. - - data = { - 'choices-TOTAL_FORMS': '1', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{'votes': [u'This field is required.']}]) - - def test_formset_initial_data(self): - # We can also prefill a FormSet with existing data by providing an ``initial`` - # argument to the constructor. ``initial`` should be a list of dicts. By default, - # an extra blank form is included. - - initial = [{'choice': u'Calexico', 'votes': 100}] - formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li> -<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li> -<li>Choice: <input type="text" name="choices-1-choice" /></li> -<li>Votes: <input type="text" name="choices-1-votes" /></li>""") - - # Let's simulate what would happen if we submitted this form. - - data = { - 'choices-TOTAL_FORMS': '2', # the number of forms rendered - 'choices-INITIAL_FORMS': '1', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-1-choice': '', - 'choices-1-votes': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': u'Calexico'}, {}]) - - def test_second_form_partially_filled(self): - # But the second form was blank! Shouldn't we get some errors? No. If we display - # a form as blank, it's ok for it to be submitted as blank. If we fill out even - # one of the fields of a blank form though, it will be validated. We may want to - # required that at least x number of forms are completed, but we'll show how to - # handle that later. - - data = { - 'choices-TOTAL_FORMS': '2', # the number of forms rendered - 'choices-INITIAL_FORMS': '1', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-1-choice': 'The Decemberists', - 'choices-1-votes': '', # missing value - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{}, {'votes': [u'This field is required.']}]) - - def test_delete_prefilled_data(self): - # If we delete data that was pre-filled, we should get an error. Simply removing - # data from form fields isn't the proper way to delete it. We'll see how to - # handle that case later. - - data = { - 'choices-TOTAL_FORMS': '2', # the number of forms rendered - 'choices-INITIAL_FORMS': '1', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': '', # deleted value - 'choices-0-votes': '', # deleted value - 'choices-1-choice': '', - 'choices-1-votes': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{'votes': [u'This field is required.'], 'choice': [u'This field is required.']}, {}]) - - def test_displaying_more_than_one_blank_form(self): - # Displaying more than 1 blank form ########################################### - # We can also display more than 1 empty form at a time. To do so, pass a - # extra argument to formset_factory. - ChoiceFormSet = formset_factory(Choice, extra=3) - - formset = ChoiceFormSet(auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" /></li> -<li>Votes: <input type="text" name="choices-0-votes" /></li> -<li>Choice: <input type="text" name="choices-1-choice" /></li> -<li>Votes: <input type="text" name="choices-1-votes" /></li> -<li>Choice: <input type="text" name="choices-2-choice" /></li> -<li>Votes: <input type="text" name="choices-2-votes" /></li>""") - - # Since we displayed every form as blank, we will also accept them back as blank. - # This may seem a little strange, but later we will show how to require a minimum - # number of forms to be completed. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': '', - 'choices-0-votes': '', - 'choices-1-choice': '', - 'choices-1-votes': '', - 'choices-2-choice': '', - 'choices-2-votes': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - self.assertEqual([form.cleaned_data for form in formset.forms], [{}, {}, {}]) - - def test_single_form_completed(self): - # We can just fill out one of the forms. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-1-choice': '', - 'choices-1-votes': '', - 'choices-2-choice': '', - 'choices-2-votes': '', - } - - ChoiceFormSet = formset_factory(Choice, extra=3) - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': u'Calexico'}, {}, {}]) - - def test_second_form_partially_filled_2(self): - # And once again, if we try to partially complete a form, validation will fail. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-1-choice': 'The Decemberists', - 'choices-1-votes': '', # missing value - 'choices-2-choice': '', - 'choices-2-votes': '', - } - - ChoiceFormSet = formset_factory(Choice, extra=3) - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.errors, [{}, {'votes': [u'This field is required.']}, {}]) - - def test_more_initial_data(self): - # The extra argument also works when the formset is pre-filled with initial - # data. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-1-choice': '', - 'choices-1-votes': '', # missing value - 'choices-2-choice': '', - 'choices-2-votes': '', - } - - initial = [{'choice': u'Calexico', 'votes': 100}] - ChoiceFormSet = formset_factory(Choice, extra=3) - formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li> -<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li> -<li>Choice: <input type="text" name="choices-1-choice" /></li> -<li>Votes: <input type="text" name="choices-1-votes" /></li> -<li>Choice: <input type="text" name="choices-2-choice" /></li> -<li>Votes: <input type="text" name="choices-2-votes" /></li> -<li>Choice: <input type="text" name="choices-3-choice" /></li> -<li>Votes: <input type="text" name="choices-3-votes" /></li>""") - - # Make sure retrieving an empty form works, and it shows up in the form list - - self.assertTrue(formset.empty_form.empty_permitted) - self.assertEqual(formset.empty_form.as_ul(), """<li>Choice: <input type="text" name="choices-__prefix__-choice" /></li> -<li>Votes: <input type="text" name="choices-__prefix__-votes" /></li>""") - - def test_formset_with_deletion(self): - # FormSets with deletion ###################################################### - # We can easily add deletion ability to a FormSet with an argument to - # formset_factory. This will add a boolean field to each form instance. When - # that boolean field is True, the form will be in formset.deleted_forms - - ChoiceFormSet = formset_factory(Choice, can_delete=True) - - initial = [{'choice': u'Calexico', 'votes': 100}, {'choice': u'Fergie', 'votes': 900}] - formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li> -<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li> -<li>Delete: <input type="checkbox" name="choices-0-DELETE" /></li> -<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li> -<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li> -<li>Delete: <input type="checkbox" name="choices-1-DELETE" /></li> -<li>Choice: <input type="text" name="choices-2-choice" /></li> -<li>Votes: <input type="text" name="choices-2-votes" /></li> -<li>Delete: <input type="checkbox" name="choices-2-DELETE" /></li>""") - - # To delete something, we just need to set that form's special delete field to - # 'on'. Let's go ahead and delete Fergie. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '2', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-0-DELETE': '', - 'choices-1-choice': 'Fergie', - 'choices-1-votes': '900', - 'choices-1-DELETE': 'on', - 'choices-2-choice': '', - 'choices-2-votes': '', - 'choices-2-DELETE': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'DELETE': False, 'choice': u'Calexico'}, {'votes': 900, 'DELETE': True, 'choice': u'Fergie'}, {}]) - self.assertEqual([form.cleaned_data for form in formset.deleted_forms], [{'votes': 900, 'DELETE': True, 'choice': u'Fergie'}]) - - # If we fill a form with something and then we check the can_delete checkbox for - # that form, that form's errors should not make the entire formset invalid since - # it's going to be deleted. - - class CheckForm(Form): - field = IntegerField(min_value=100) - - data = { - 'check-TOTAL_FORMS': '3', # the number of forms rendered - 'check-INITIAL_FORMS': '2', # the number of forms with initial data - 'check-MAX_NUM_FORMS': '0', # max number of forms - 'check-0-field': '200', - 'check-0-DELETE': '', - 'check-1-field': '50', - 'check-1-DELETE': 'on', - 'check-2-field': '', - 'check-2-DELETE': '', - } - CheckFormSet = formset_factory(CheckForm, can_delete=True) - formset = CheckFormSet(data, prefix='check') - self.assertTrue(formset.is_valid()) - - # If we remove the deletion flag now we will have our validation back. - data['check-1-DELETE'] = '' - formset = CheckFormSet(data, prefix='check') - self.assertFalse(formset.is_valid()) - - # Should be able to get deleted_forms from a valid formset even if a - # deleted form would have been invalid. - - class Person(Form): - name = CharField() - - PeopleForm = formset_factory( - form=Person, - can_delete=True) - - p = PeopleForm( - {'form-0-name': u'', 'form-0-DELETE': u'on', # no name! - 'form-TOTAL_FORMS': 1, 'form-INITIAL_FORMS': 1, - 'form-MAX_NUM_FORMS': 1}) - - self.assertTrue(p.is_valid()) - self.assertEqual(len(p.deleted_forms), 1) - - def test_formsets_with_ordering(self): - # FormSets with ordering ###################################################### - # We can also add ordering ability to a FormSet with an argument to - # formset_factory. This will add a integer field to each form instance. When - # form validation succeeds, [form.cleaned_data for form in formset.forms] will have the data in the correct - # order specified by the ordering fields. If a number is duplicated in the set - # of ordering fields, for instance form 0 and form 3 are both marked as 1, then - # the form index used as a secondary ordering criteria. In order to put - # something at the front of the list, you'd need to set it's order to 0. - - ChoiceFormSet = formset_factory(Choice, can_order=True) - - initial = [{'choice': u'Calexico', 'votes': 100}, {'choice': u'Fergie', 'votes': 900}] - formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li> -<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li> -<li>Order: <input type="text" name="choices-0-ORDER" value="1" /></li> -<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li> -<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li> -<li>Order: <input type="text" name="choices-1-ORDER" value="2" /></li> -<li>Choice: <input type="text" name="choices-2-choice" /></li> -<li>Votes: <input type="text" name="choices-2-votes" /></li> -<li>Order: <input type="text" name="choices-2-ORDER" /></li>""") - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '2', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-0-ORDER': '1', - 'choices-1-choice': 'Fergie', - 'choices-1-votes': '900', - 'choices-1-ORDER': '2', - 'choices-2-choice': 'The Decemberists', - 'choices-2-votes': '500', - 'choices-2-ORDER': '0', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - form_output = [] - - for form in formset.ordered_forms: - form_output.append(form.cleaned_data) - - self.assertEqual(form_output, [ - {'votes': 500, 'ORDER': 0, 'choice': u'The Decemberists'}, - {'votes': 100, 'ORDER': 1, 'choice': u'Calexico'}, - {'votes': 900, 'ORDER': 2, 'choice': u'Fergie'}, - ]) - - def test_empty_ordered_fields(self): - # Ordering fields are allowed to be left blank, and if they *are* left blank, - # they will be sorted below everything else. - - data = { - 'choices-TOTAL_FORMS': '4', # the number of forms rendered - 'choices-INITIAL_FORMS': '3', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-0-ORDER': '1', - 'choices-1-choice': 'Fergie', - 'choices-1-votes': '900', - 'choices-1-ORDER': '2', - 'choices-2-choice': 'The Decemberists', - 'choices-2-votes': '500', - 'choices-2-ORDER': '', - 'choices-3-choice': 'Basia Bulat', - 'choices-3-votes': '50', - 'choices-3-ORDER': '', - } - - ChoiceFormSet = formset_factory(Choice, can_order=True) - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - form_output = [] - - for form in formset.ordered_forms: - form_output.append(form.cleaned_data) - - self.assertEqual(form_output, [ - {'votes': 100, 'ORDER': 1, 'choice': u'Calexico'}, - {'votes': 900, 'ORDER': 2, 'choice': u'Fergie'}, - {'votes': 500, 'ORDER': None, 'choice': u'The Decemberists'}, - {'votes': 50, 'ORDER': None, 'choice': u'Basia Bulat'}, - ]) - - def test_ordering_blank_fieldsets(self): - # Ordering should work with blank fieldsets. - - data = { - 'choices-TOTAL_FORMS': '3', # the number of forms rendered - 'choices-INITIAL_FORMS': '0', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - } - - ChoiceFormSet = formset_factory(Choice, can_order=True) - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - form_output = [] - - for form in formset.ordered_forms: - form_output.append(form.cleaned_data) - - self.assertEqual(form_output, []) - - def test_formset_with_ordering_and_deletion(self): - # FormSets with ordering + deletion ########################################### - # Let's try throwing ordering and deletion into the same form. - - ChoiceFormSet = formset_factory(Choice, can_order=True, can_delete=True) - - initial = [ - {'choice': u'Calexico', 'votes': 100}, - {'choice': u'Fergie', 'votes': 900}, - {'choice': u'The Decemberists', 'votes': 500}, - ] - formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices') - form_output = [] - - for form in formset.forms: - form_output.append(form.as_ul()) - - self.assertEqual('\n'.join(form_output), """<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li> -<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li> -<li>Order: <input type="text" name="choices-0-ORDER" value="1" /></li> -<li>Delete: <input type="checkbox" name="choices-0-DELETE" /></li> -<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li> -<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li> -<li>Order: <input type="text" name="choices-1-ORDER" value="2" /></li> -<li>Delete: <input type="checkbox" name="choices-1-DELETE" /></li> -<li>Choice: <input type="text" name="choices-2-choice" value="The Decemberists" /></li> -<li>Votes: <input type="text" name="choices-2-votes" value="500" /></li> -<li>Order: <input type="text" name="choices-2-ORDER" value="3" /></li> -<li>Delete: <input type="checkbox" name="choices-2-DELETE" /></li> -<li>Choice: <input type="text" name="choices-3-choice" /></li> -<li>Votes: <input type="text" name="choices-3-votes" /></li> -<li>Order: <input type="text" name="choices-3-ORDER" /></li> -<li>Delete: <input type="checkbox" name="choices-3-DELETE" /></li>""") - - # Let's delete Fergie, and put The Decemberists ahead of Calexico. - - data = { - 'choices-TOTAL_FORMS': '4', # the number of forms rendered - 'choices-INITIAL_FORMS': '3', # the number of forms with initial data - 'choices-MAX_NUM_FORMS': '0', # max number of forms - 'choices-0-choice': 'Calexico', - 'choices-0-votes': '100', - 'choices-0-ORDER': '1', - 'choices-0-DELETE': '', - 'choices-1-choice': 'Fergie', - 'choices-1-votes': '900', - 'choices-1-ORDER': '2', - 'choices-1-DELETE': 'on', - 'choices-2-choice': 'The Decemberists', - 'choices-2-votes': '500', - 'choices-2-ORDER': '0', - 'choices-2-DELETE': '', - 'choices-3-choice': '', - 'choices-3-votes': '', - 'choices-3-ORDER': '', - 'choices-3-DELETE': '', - } - - formset = ChoiceFormSet(data, auto_id=False, prefix='choices') - self.assertTrue(formset.is_valid()) - form_output = [] - - for form in formset.ordered_forms: - form_output.append(form.cleaned_data) - - self.assertEqual(form_output, [ - {'votes': 500, 'DELETE': False, 'ORDER': 0, 'choice': u'The Decemberists'}, - {'votes': 100, 'DELETE': False, 'ORDER': 1, 'choice': u'Calexico'}, - ]) - self.assertEqual([form.cleaned_data for form in formset.deleted_forms], [{'votes': 900, 'DELETE': True, 'ORDER': 2, 'choice': u'Fergie'}]) - - def test_invalid_deleted_form_with_ordering(self): - # Should be able to get ordered forms from a valid formset even if a - # deleted form would have been invalid. - - class Person(Form): - name = CharField() - - PeopleForm = formset_factory(form=Person, can_delete=True, can_order=True) - - p = PeopleForm({ - 'form-0-name': u'', - 'form-0-DELETE': u'on', # no name! - 'form-TOTAL_FORMS': 1, - 'form-INITIAL_FORMS': 1, - 'form-MAX_NUM_FORMS': 1 - }) - - self.assertTrue(p.is_valid()) - self.assertEqual(p.ordered_forms, []) - - def test_clean_hook(self): - # FormSet clean hook ########################################################## - # FormSets have a hook for doing extra validation that shouldn't be tied to any - # particular form. It follows the same pattern as the clean hook on Forms. - - # We start out with a some duplicate data. - - data = { - 'drinks-TOTAL_FORMS': '2', # the number of forms rendered - 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data - 'drinks-MAX_NUM_FORMS': '0', # max number of forms - 'drinks-0-name': 'Gin and Tonic', - 'drinks-1-name': 'Gin and Tonic', - } - - formset = FavoriteDrinksFormSet(data, prefix='drinks') - self.assertFalse(formset.is_valid()) - - # Any errors raised by formset.clean() are available via the - # formset.non_form_errors() method. - - for error in formset.non_form_errors(): - self.assertEqual(str(error), 'You may only specify a drink once.') - - # Make sure we didn't break the valid case. - - data = { - 'drinks-TOTAL_FORMS': '2', # the number of forms rendered - 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data - 'drinks-MAX_NUM_FORMS': '0', # max number of forms - 'drinks-0-name': 'Gin and Tonic', - 'drinks-1-name': 'Bloody Mary', - } - - formset = FavoriteDrinksFormSet(data, prefix='drinks') - self.assertTrue(formset.is_valid()) - self.assertEqual(formset.non_form_errors(), []) - - def test_limiting_max_forms(self): - # Limiting the maximum number of forms ######################################## - # Base case for max_num. - - # When not passed, max_num will take its default value of None, i.e. unlimited - # number of forms, only controlled by the value of the extra parameter. - - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3) - formset = LimitedFavoriteDrinkFormSet() - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr> -<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr> -<tr><th><label for="id_form-2-name">Name:</label></th><td><input type="text" name="form-2-name" id="id_form-2-name" /></td></tr>""") - - # If max_num is 0 then no form is rendered at all. - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=0) - formset = LimitedFavoriteDrinkFormSet() - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), "") - - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=5, max_num=2) - formset = LimitedFavoriteDrinkFormSet() - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr> -<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>""") - - # Ensure that max_num has no effect when extra is less than max_num. - - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2) - formset = LimitedFavoriteDrinkFormSet() - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>""") - - def test_max_num_with_initial_data(self): - # max_num with initial data - - # When not passed, max_num will take its default value of None, i.e. unlimited - # number of forms, only controlled by the values of the initial and extra - # parameters. - - initial = [ - {'name': 'Fernet and Coke'}, - ] - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1) - formset = LimitedFavoriteDrinkFormSet(initial=initial) - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Fernet and Coke" id="id_form-0-name" /></td></tr> -<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>""") - - def test_max_num_zero(self): - # If max_num is 0 then no form is rendered at all, even if extra and initial - # are specified. - - initial = [ - {'name': 'Fernet and Coke'}, - {'name': 'Bloody Mary'}, - ] - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=0) - formset = LimitedFavoriteDrinkFormSet(initial=initial) - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), "") - - def test_more_initial_than_max_num(self): - # More initial forms than max_num will result in only the first max_num of - # them to be displayed with no extra forms. - - initial = [ - {'name': 'Gin Tonic'}, - {'name': 'Bloody Mary'}, - {'name': 'Jack and Coke'}, - ] - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2) - formset = LimitedFavoriteDrinkFormSet(initial=initial) - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Gin Tonic" id="id_form-0-name" /></td></tr> -<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" value="Bloody Mary" id="id_form-1-name" /></td></tr>""") - - # One form from initial and extra=3 with max_num=2 should result in the one - # initial form and one extra. - initial = [ - {'name': 'Gin Tonic'}, - ] - LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=2) - formset = LimitedFavoriteDrinkFormSet(initial=initial) - form_output = [] - - for form in formset.forms: - form_output.append(str(form)) - - self.assertEqual('\n'.join(form_output), """<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Gin Tonic" id="id_form-0-name" /></td></tr> -<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>""") - - def test_regression_6926(self): - # Regression test for #6926 ################################################## - # Make sure the management form has the correct prefix. - - formset = FavoriteDrinksFormSet() - self.assertEqual(formset.management_form.prefix, 'form') - - formset = FavoriteDrinksFormSet(data={}) - self.assertEqual(formset.management_form.prefix, 'form') - - formset = FavoriteDrinksFormSet(initial={}) - self.assertEqual(formset.management_form.prefix, 'form') - - def test_regression_12878(self): - # Regression test for #12878 ################################################# - - data = { - 'drinks-TOTAL_FORMS': '2', # the number of forms rendered - 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data - 'drinks-MAX_NUM_FORMS': '0', # max number of forms - 'drinks-0-name': 'Gin and Tonic', - 'drinks-1-name': 'Gin and Tonic', - } - - formset = FavoriteDrinksFormSet(data, prefix='drinks') - self.assertFalse(formset.is_valid()) - self.assertEqual(formset.non_form_errors(), [u'You may only specify a drink once.']) diff --git a/parts/django/tests/regressiontests/forms/tests/input_formats.py b/parts/django/tests/regressiontests/forms/tests/input_formats.py deleted file mode 100644 index 498c6de..0000000 --- a/parts/django/tests/regressiontests/forms/tests/input_formats.py +++ /dev/null @@ -1,894 +0,0 @@ -from datetime import time, date, datetime -from unittest import TestCase - -from django import forms -from django.conf import settings -from django.utils.translation import activate, deactivate - - -class LocalizedTimeTests(TestCase): - def setUp(self): - self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS - self.old_USE_L10N = settings.USE_L10N - - settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"] - settings.USE_L10N = True - - activate('de') - - def tearDown(self): - settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS - settings.USE_L10N = self.old_USE_L10N - - deactivate() - - def test_timeField(self): - "TimeFields can parse dates in the default format" - f = forms.TimeField() - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30:05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '13:30:05') - - # Parse a time in a valid, but non-default format, get a parsed result - result = f.clean('13:30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_localized_timeField(self): - "Localized TimeFields act as unlocalized widgets" - f = forms.TimeField(localize=True) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30:05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_timeField_with_inputformat(self): - "TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"]) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30.05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_localized_timeField_with_inputformat(self): - "Localized TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30.05') - self.assertEqual(result, time(13,30,5)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - -class CustomTimeInputFormatsTests(TestCase): - def setUp(self): - self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS - settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"] - - def tearDown(self): - settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS - - def test_timeField(self): - "TimeFields can parse dates in the default format" - f = forms.TimeField() - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30:05 PM') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '01:30:05 PM') - - # Parse a time in a valid, but non-default format, get a parsed result - result = f.clean('1:30 PM') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM") - - def test_localized_timeField(self): - "Localized TimeFields act as unlocalized widgets" - f = forms.TimeField(localize=True) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30:05 PM') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '01:30:05 PM') - - # Parse a time in a valid format, get a parsed result - result = f.clean('01:30 PM') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM") - - def test_timeField_with_inputformat(self): - "TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"]) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30.05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:05 PM") - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM") - - def test_localized_timeField_with_inputformat(self): - "Localized TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30.05') - self.assertEqual(result, time(13,30,5)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:05 PM") - - # Parse a time in a valid format, get a parsed result - result = f.clean('13.30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM") - - -class SimpleTimeFormatTests(TestCase): - def test_timeField(self): - "TimeFields can parse dates in the default format" - f = forms.TimeField() - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30:05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid, but non-default format, get a parsed result - result = f.clean('13:30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_localized_timeField(self): - "Localized TimeFields in a non-localized environment act as unlocalized widgets" - f = forms.TimeField() - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM') - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30:05') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid format, get a parsed result - result = f.clean('13:30') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_timeField_with_inputformat(self): - "TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"]) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30:05 PM') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30 PM') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - def test_localized_timeField_with_inputformat(self): - "Localized TimeFields with manually specified input formats can accept those formats" - f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"], localize=True) - # Parse a time in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05') - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30:05 PM') - self.assertEqual(result, time(13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:05") - - # Parse a time in a valid format, get a parsed result - result = f.clean('1:30 PM') - self.assertEqual(result, time(13,30,0)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "13:30:00") - - -class LocalizedDateTests(TestCase): - def setUp(self): - self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS - self.old_USE_L10N = settings.USE_L10N - - settings.DATE_INPUT_FORMATS = ["%d/%m/%Y", "%d-%m-%Y"] - settings.USE_L10N = True - - activate('de') - - def tearDown(self): - settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS - settings.USE_L10N = self.old_USE_L10N - - deactivate() - - def test_dateField(self): - "DateFields can parse dates in the default format" - f = forms.DateField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21/12/2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010') - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('21.12.10') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_localized_dateField(self): - "Localized DateFields act as unlocalized widgets" - f = forms.DateField(localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21/12/2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.10') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_dateField_with_inputformat(self): - "DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - self.assertRaises(forms.ValidationError, f.clean, '21/12/2010') - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_localized_dateField_with_inputformat(self): - "Localized DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - self.assertRaises(forms.ValidationError, f.clean, '21/12/2010') - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010') - self.assertEqual(result, date(2010,12,21)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - -class CustomDateInputFormatsTests(TestCase): - def setUp(self): - self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS - settings.DATE_INPUT_FORMATS = ["%d.%m.%Y", "%d-%m-%Y"] - - def tearDown(self): - settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS - - def test_dateField(self): - "DateFields can parse dates in the default format" - f = forms.DateField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010') - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('21-12-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_localized_dateField(self): - "Localized DateFields act as unlocalized widgets" - f = forms.DateField(localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21-12-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_dateField_with_inputformat(self): - "DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - def test_localized_dateField_with_inputformat(self): - "Localized DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010') - self.assertEqual(result, date(2010,12,21)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010") - -class SimpleDateFormatTests(TestCase): - def test_dateField(self): - "DateFields can parse dates in the default format" - f = forms.DateField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('2010-12-21') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('12/21/2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - def test_localized_dateField(self): - "Localized DateFields in a non-localized environment act as unlocalized widgets" - f = forms.DateField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('2010-12-21') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12/21/2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - def test_dateField_with_inputformat(self): - "DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - # Parse a date in a valid format, get a parsed result - result = f.clean('21-12-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - def test_localized_dateField_with_inputformat(self): - "Localized DateFields with manually specified input formats can accept those formats" - f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - - # Parse a date in a valid format, get a parsed result - result = f.clean('21-12-2010') - self.assertEqual(result, date(2010,12,21)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21") - -class LocalizedDateTimeTests(TestCase): - def setUp(self): - self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS - self.old_USE_L10N = settings.USE_L10N - - settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"] - settings.USE_L10N = True - - activate('de') - - def tearDown(self): - settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS - settings.USE_L10N = self.old_USE_L10N - - deactivate() - - def test_dateTimeField(self): - "DateTimeFields can parse dates in the default format" - f = forms.DateTimeField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010 13:30:05') - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('21.12.2010 13:30') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:00") - - def test_localized_dateTimeField(self): - "Localized DateTimeFields act as unlocalized widgets" - f = forms.DateTimeField(localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '21.12.2010 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('21.12.2010 13:30') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:00") - - def test_dateTimeField_with_inputformat(self): - "DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05 13:30:05') - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('13.30.05 12.21.2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:05") - - # Parse a date in a valid format, get a parsed result - result = f.clean('13.30 12-21-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:00") - - def test_localized_dateTimeField_with_inputformat(self): - "Localized DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010') - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('13.30.05 12.21.2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:05") - - # Parse a date in a valid format, get a parsed result - result = f.clean('13.30 12-21-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "21.12.2010 13:30:00") - - -class CustomDateTimeInputFormatsTests(TestCase): - def setUp(self): - self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS - settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"] - - def tearDown(self): - settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS - - def test_dateTimeField(self): - "DateTimeFields can parse dates in the default format" - f = forms.DateTimeField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30:05 PM 21/12/2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip - text = f.widget._format_value(result) - self.assertEqual(text, '01:30:05 PM 21/12/2010') - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('1:30 PM 21-12-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM 21/12/2010") - - def test_localized_dateTimeField(self): - "Localized DateTimeFields act as unlocalized widgets" - f = forms.DateTimeField(localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30:05 PM 21/12/2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, '01:30:05 PM 21/12/2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30 PM 21-12-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM 21/12/2010") - - def test_dateTimeField_with_inputformat(self): - "DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:05 PM 21/12/2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010 13:30') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM 21/12/2010") - - def test_localized_dateTimeField_with_inputformat(self): - "Localized DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('12.21.2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:05 PM 21/12/2010") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12-21-2010 13:30') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "01:30:00 PM 21/12/2010") - -class SimpleDateTimeFormatTests(TestCase): - def test_dateTimeField(self): - "DateTimeFields can parse dates in the default format" - f = forms.DateTimeField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('2010-12-21 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - # Parse a date in a valid, but non-default format, get a parsed result - result = f.clean('12/21/2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - def test_localized_dateTimeField(self): - "Localized DateTimeFields in a non-localized environment act as unlocalized widgets" - f = forms.DateTimeField() - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010') - - # Parse a date in a valid format, get a parsed result - result = f.clean('2010-12-21 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - # Parse a date in a valid format, get a parsed result - result = f.clean('12/21/2010 13:30:05') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - def test_dateTimeField_with_inputformat(self): - "DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"]) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30:05 PM 21.12.2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30 PM 21-12-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:00") - - def test_localized_dateTimeField_with_inputformat(self): - "Localized DateTimeFields with manually specified input formats can accept those formats" - f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"], localize=True) - # Parse a date in an unaccepted format; get an error - self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05') - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30:05 PM 21.12.2010') - self.assertEqual(result, datetime(2010,12,21,13,30,5)) - - # Check that the parsed result does a round trip to the same format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:05") - - # Parse a date in a valid format, get a parsed result - result = f.clean('1:30 PM 21-12-2010') - self.assertEqual(result, datetime(2010,12,21,13,30)) - - # Check that the parsed result does a round trip to default format - text = f.widget._format_value(result) - self.assertEqual(text, "2010-12-21 13:30:00") diff --git a/parts/django/tests/regressiontests/forms/tests/media.py b/parts/django/tests/regressiontests/forms/tests/media.py deleted file mode 100644 index eb59d13..0000000 --- a/parts/django/tests/regressiontests/forms/tests/media.py +++ /dev/null @@ -1,460 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from django.conf import settings -from django.forms import TextInput, Media, TextInput, CharField, Form, MultiWidget - - -class FormsMediaTestCase(TestCase): - # Tests for the media handling on widgets and forms - def setUp(self): - super(FormsMediaTestCase, self).setUp() - self.original_media_url = settings.MEDIA_URL - settings.MEDIA_URL = 'http://media.example.com/media/' - - def tearDown(self): - settings.MEDIA_URL = self.original_media_url - super(FormsMediaTestCase, self).tearDown() - - def test_construction(self): - # Check construction of media objects - m = Media(css={'all': ('path/to/css1','/path/to/css2')}, js=('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')) - self.assertEqual(str(m), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - class Foo: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - m3 = Media(Foo) - self.assertEqual(str(m3), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - # A widget can exist without a media definition - class MyWidget(TextInput): - pass - - w = MyWidget() - self.assertEqual(str(w.media), '') - - def test_media_dsl(self): - ############################################################### - # DSL Class-based media definitions - ############################################################### - - # A widget can define media if it needs to. - # Any absolute path will be preserved; relative paths are combined - # with the value of settings.MEDIA_URL - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - w1 = MyWidget1() - self.assertEqual(str(w1.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - # Media objects can be interrogated by media type - self.assertEqual(str(w1.media['css']), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />""") - - self.assertEqual(str(w1.media['js']), """<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - def test_combine_media(self): - # Media objects can be combined. Any given media resource will appear only - # once. Duplicated media definitions are ignored. - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2','/path/to/css3') - } - js = ('/path/to/js1','/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - w1 = MyWidget1() - w2 = MyWidget2() - w3 = MyWidget3() - self.assertEqual(str(w1.media + w2.media + w3.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - # Check that media addition hasn't affected the original objects - self.assertEqual(str(w1.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - # Regression check for #12879: specifying the same CSS or JS file - # multiple times in a single Media instance should result in that file - # only being included once. - class MyWidget4(TextInput): - class Media: - css = {'all': ('/path/to/css1', '/path/to/css1')} - js = ('/path/to/js1', '/path/to/js1') - - w4 = MyWidget4() - self.assertEqual(str(w4.media), """<link href="/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script>""") - - def test_media_property(self): - ############################################################### - # Property-based media definitions - ############################################################### - - # Widget media can be defined as a property - class MyWidget4(TextInput): - def _media(self): - return Media(css={'all': ('/some/path',)}, js = ('/some/js',)) - media = property(_media) - - w4 = MyWidget4() - self.assertEqual(str(w4.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/some/js"></script>""") - - # Media properties can reference the media of their parents - class MyWidget5(MyWidget4): - def _media(self): - return super(MyWidget5, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',)) - media = property(_media) - - w5 = MyWidget5() - self.assertEqual(str(w5.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" /> -<link href="/other/path" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/some/js"></script> -<script type="text/javascript" src="/other/js"></script>""") - - def test_media_property_parent_references(self): - # Media properties can reference the media of their parents, - # even if the parent media was defined using a class - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget6(MyWidget1): - def _media(self): - return super(MyWidget6, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',)) - media = property(_media) - - w6 = MyWidget6() - self.assertEqual(str(w6.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/other/path" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/other/js"></script>""") - - def test_media_inheritance(self): - ############################################################### - # Inheritance of media - ############################################################### - - # If a widget extends another but provides no media definition, it inherits the parent widget's media - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget7(MyWidget1): - pass - - w7 = MyWidget7() - self.assertEqual(str(w7.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""") - - # If a widget extends another but defines media, it extends the parent widget's media by default - class MyWidget8(MyWidget1): - class Media: - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - w8 = MyWidget8() - self.assertEqual(str(w8.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_media_inheritance_from_property(self): - # If a widget extends another but defines media, it extends the parents widget's media, - # even if the parent defined media using a property. - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget4(TextInput): - def _media(self): - return Media(css={'all': ('/some/path',)}, js = ('/some/js',)) - media = property(_media) - - class MyWidget9(MyWidget4): - class Media: - css = { - 'all': ('/other/path',) - } - js = ('/other/js',) - - w9 = MyWidget9() - self.assertEqual(str(w9.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" /> -<link href="/other/path" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/some/js"></script> -<script type="text/javascript" src="/other/js"></script>""") - - # A widget can disable media inheritance by specifying 'extend=False' - class MyWidget10(MyWidget1): - class Media: - extend = False - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - w10 = MyWidget10() - self.assertEqual(str(w10.media), """<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_media_inheritance_extends(self): - # A widget can explicitly enable full media inheritance by specifying 'extend=True' - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget11(MyWidget1): - class Media: - extend = True - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - w11 = MyWidget11() - self.assertEqual(str(w11.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_media_inheritance_single_type(self): - # A widget can enable inheritance of one media type by specifying extend as a tuple - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget12(MyWidget1): - class Media: - extend = ('css',) - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - w12 = MyWidget12() - self.assertEqual(str(w12.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_multi_media(self): - ############################################################### - # Multi-media handling for CSS - ############################################################### - - # A widget can define CSS media for multiple output media types - class MultimediaWidget(TextInput): - class Media: - css = { - 'screen, print': ('/file1','/file2'), - 'screen': ('/file3',), - 'print': ('/file4',) - } - js = ('/path/to/js1','/path/to/js4') - - multimedia = MultimediaWidget() - self.assertEqual(str(multimedia.media), """<link href="/file4" type="text/css" media="print" rel="stylesheet" /> -<link href="/file3" type="text/css" media="screen" rel="stylesheet" /> -<link href="/file1" type="text/css" media="screen, print" rel="stylesheet" /> -<link href="/file2" type="text/css" media="screen, print" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_multi_widget(self): - ############################################################### - # Multiwidget media handling - ############################################################### - - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2','/path/to/css3') - } - js = ('/path/to/js1','/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - # MultiWidgets have a default media definition that gets all the - # media from the component widgets - class MyMultiWidget(MultiWidget): - def __init__(self, attrs=None): - widgets = [MyWidget1, MyWidget2, MyWidget3] - super(MyMultiWidget, self).__init__(widgets, attrs) - - mymulti = MyMultiWidget() - self.assertEqual(str(mymulti.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - def test_form_media(self): - ############################################################### - # Media processing for forms - ############################################################### - - class MyWidget1(TextInput): - class Media: - css = { - 'all': ('path/to/css1','/path/to/css2') - } - js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2','/path/to/css3') - } - js = ('/path/to/js1','/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3','path/to/css1') - } - js = ('/path/to/js1','/path/to/js4') - - # You can ask a form for the media required by its widgets. - class MyForm(Form): - field1 = CharField(max_length=20, widget=MyWidget1()) - field2 = CharField(max_length=20, widget=MyWidget2()) - f1 = MyForm() - self.assertEqual(str(f1.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - # Form media can be combined to produce a single media definition. - class AnotherForm(Form): - field3 = CharField(max_length=20, widget=MyWidget3()) - f2 = AnotherForm() - self.assertEqual(str(f1.media + f2.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script>""") - - # Forms can also define media, following the same rules as widgets. - class FormWithMedia(Form): - field1 = CharField(max_length=20, widget=MyWidget1()) - field2 = CharField(max_length=20, widget=MyWidget2()) - class Media: - js = ('/some/form/javascript',) - css = { - 'all': ('/some/form/css',) - } - f3 = FormWithMedia() - self.assertEqual(str(f3.media), """<link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" /> -<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script> -<script type="text/javascript" src="/some/form/javascript"></script>""") - - # Media works in templates - from django.template import Template, Context - self.assertEqual(Template("{{ form.media.js }}{{ form.media.css }}").render(Context({'form': f3})), """<script type="text/javascript" src="/path/to/js1"></script> -<script type="text/javascript" src="http://media.other.com/path/to/js2"></script> -<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script> -<script type="text/javascript" src="/path/to/js4"></script> -<script type="text/javascript" src="/some/form/javascript"></script><link href="http://media.example.com/media/path/to/css1" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" /> -<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" /> -<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />""") diff --git a/parts/django/tests/regressiontests/forms/tests/models.py b/parts/django/tests/regressiontests/forms/tests/models.py deleted file mode 100644 index af7473e..0000000 --- a/parts/django/tests/regressiontests/forms/tests/models.py +++ /dev/null @@ -1,169 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from django.core.files.uploadedfile import SimpleUploadedFile -from django.conf import settings -from django.db import connection -from django.forms import Form, ModelForm, FileField, ModelChoiceField -from django.test import TestCase -from regressiontests.forms.models import ChoiceModel, ChoiceOptionModel, ChoiceFieldModel, FileModel, Group, BoundaryModel, Defaults - - -class ChoiceFieldForm(ModelForm): - class Meta: - model = ChoiceFieldModel - - -class FileForm(Form): - file1 = FileField() - - -class TestTicket12510(TestCase): - ''' It is not necessary to generate choices for ModelChoiceField (regression test for #12510). ''' - def setUp(self): - self.groups = [Group.objects.create(name=name) for name in 'abc'] - self.old_debug = settings.DEBUG - # turn debug on to get access to connection.queries - settings.DEBUG = True - - def tearDown(self): - settings.DEBUG = self.old_debug - - def test_choices_not_fetched_when_not_rendering(self): - initial_queries = len(connection.queries) - field = ModelChoiceField(Group.objects.order_by('-name')) - self.assertEqual('a', field.clean(self.groups[0].pk).name) - # only one query is required to pull the model from DB - self.assertEqual(initial_queries+1, len(connection.queries)) - -class ModelFormCallableModelDefault(TestCase): - def test_no_empty_option(self): - "If a model's ForeignKey has blank=False and a default, no empty option is created (Refs #10792)." - option = ChoiceOptionModel.objects.create(name='default') - - choices = list(ChoiceFieldForm().fields['choice'].choices) - self.assertEquals(len(choices), 1) - self.assertEquals(choices[0], (option.pk, unicode(option))) - - def test_callable_initial_value(self): - "The initial value for a callable default returning a queryset is the pk (refs #13769)" - obj1 = ChoiceOptionModel.objects.create(id=1, name='default') - obj2 = ChoiceOptionModel.objects.create(id=2, name='option 2') - obj3 = ChoiceOptionModel.objects.create(id=3, name='option 3') - self.assertEquals(ChoiceFieldForm().as_p(), """<p><label for="id_choice">Choice:</label> <select name="choice" id="id_choice"> -<option value="1" selected="selected">ChoiceOption 1</option> -<option value="2">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-choice" value="1" id="initial-id_choice" /></p> -<p><label for="id_choice_int">Choice int:</label> <select name="choice_int" id="id_choice_int"> -<option value="1" selected="selected">ChoiceOption 1</option> -<option value="2">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-choice_int" value="1" id="initial-id_choice_int" /></p> -<p><label for="id_multi_choice">Multi choice:</label> <select multiple="multiple" name="multi_choice" id="id_multi_choice"> -<option value="1" selected="selected">ChoiceOption 1</option> -<option value="2">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-multi_choice" value="1" id="initial-id_multi_choice_0" /> Hold down "Control", or "Command" on a Mac, to select more than one.</p> -<p><label for="id_multi_choice_int">Multi choice int:</label> <select multiple="multiple" name="multi_choice_int" id="id_multi_choice_int"> -<option value="1" selected="selected">ChoiceOption 1</option> -<option value="2">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-multi_choice_int" value="1" id="initial-id_multi_choice_int_0" /> Hold down "Control", or "Command" on a Mac, to select more than one.</p>""") - - def test_initial_instance_value(self): - "Initial instances for model fields may also be instances (refs #7287)" - obj1 = ChoiceOptionModel.objects.create(id=1, name='default') - obj2 = ChoiceOptionModel.objects.create(id=2, name='option 2') - obj3 = ChoiceOptionModel.objects.create(id=3, name='option 3') - self.assertEquals(ChoiceFieldForm(initial={ - 'choice': obj2, - 'choice_int': obj2, - 'multi_choice': [obj2,obj3], - 'multi_choice_int': ChoiceOptionModel.objects.exclude(name="default"), - }).as_p(), """<p><label for="id_choice">Choice:</label> <select name="choice" id="id_choice"> -<option value="1">ChoiceOption 1</option> -<option value="2" selected="selected">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-choice" value="2" id="initial-id_choice" /></p> -<p><label for="id_choice_int">Choice int:</label> <select name="choice_int" id="id_choice_int"> -<option value="1">ChoiceOption 1</option> -<option value="2" selected="selected">ChoiceOption 2</option> -<option value="3">ChoiceOption 3</option> -</select><input type="hidden" name="initial-choice_int" value="2" id="initial-id_choice_int" /></p> -<p><label for="id_multi_choice">Multi choice:</label> <select multiple="multiple" name="multi_choice" id="id_multi_choice"> -<option value="1">ChoiceOption 1</option> -<option value="2" selected="selected">ChoiceOption 2</option> -<option value="3" selected="selected">ChoiceOption 3</option> -</select><input type="hidden" name="initial-multi_choice" value="2" id="initial-id_multi_choice_0" /> -<input type="hidden" name="initial-multi_choice" value="3" id="initial-id_multi_choice_1" /> Hold down "Control", or "Command" on a Mac, to select more than one.</p> -<p><label for="id_multi_choice_int">Multi choice int:</label> <select multiple="multiple" name="multi_choice_int" id="id_multi_choice_int"> -<option value="1">ChoiceOption 1</option> -<option value="2" selected="selected">ChoiceOption 2</option> -<option value="3" selected="selected">ChoiceOption 3</option> -</select><input type="hidden" name="initial-multi_choice_int" value="2" id="initial-id_multi_choice_int_0" /> -<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1" /> Hold down "Control", or "Command" on a Mac, to select more than one.</p>""") - - - -class FormsModelTestCase(TestCase): - def test_unicode_filename(self): - # FileModel with unicode filename and data ######################### - f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')}, auto_id=False) - self.assertTrue(f.is_valid()) - self.assertTrue('file1' in f.cleaned_data) - m = FileModel.objects.create(file=f.cleaned_data['file1']) - self.assertEqual(m.file.name, u'tests/\u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54.txt') - m.delete() - - def test_boundary_conditions(self): - # Boundary conditions on a PostitiveIntegerField ######################### - class BoundaryForm(ModelForm): - class Meta: - model = BoundaryModel - - f = BoundaryForm({'positive_integer': 100}) - self.assertTrue(f.is_valid()) - f = BoundaryForm({'positive_integer': 0}) - self.assertTrue(f.is_valid()) - f = BoundaryForm({'positive_integer': -100}) - self.assertFalse(f.is_valid()) - - def test_formfield_initial(self): - # Formfield initial values ######## - # If the model has default values for some fields, they are used as the formfield - # initial values. - class DefaultsForm(ModelForm): - class Meta: - model = Defaults - - self.assertEqual(DefaultsForm().fields['name'].initial, u'class default value') - self.assertEqual(DefaultsForm().fields['def_date'].initial, datetime.date(1980, 1, 1)) - self.assertEqual(DefaultsForm().fields['value'].initial, 42) - r1 = DefaultsForm()['callable_default'].as_widget() - r2 = DefaultsForm()['callable_default'].as_widget() - self.assertNotEqual(r1, r2) - - # In a ModelForm that is passed an instance, the initial values come from the - # instance's values, not the model's defaults. - foo_instance = Defaults(name=u'instance value', def_date=datetime.date(1969, 4, 4), value=12) - instance_form = DefaultsForm(instance=foo_instance) - self.assertEqual(instance_form.initial['name'], u'instance value') - self.assertEqual(instance_form.initial['def_date'], datetime.date(1969, 4, 4)) - self.assertEqual(instance_form.initial['value'], 12) - - from django.forms import CharField - - class ExcludingForm(ModelForm): - name = CharField(max_length=255) - - class Meta: - model = Defaults - exclude = ['name', 'callable_default'] - - f = ExcludingForm({'name': u'Hello', 'value': 99, 'def_date': datetime.date(1999, 3, 2)}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data['name'], u'Hello') - obj = f.save() - self.assertEqual(obj.name, u'class default value') - self.assertEqual(obj.value, 99) - self.assertEqual(obj.def_date, datetime.date(1999, 3, 2)) diff --git a/parts/django/tests/regressiontests/forms/tests/regressions.py b/parts/django/tests/regressiontests/forms/tests/regressions.py deleted file mode 100644 index ddec740..0000000 --- a/parts/django/tests/regressiontests/forms/tests/regressions.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from django.forms import * -from django.utils.translation import ugettext_lazy, activate, deactivate - -from regressiontests.forms.models import Cheese - - -class FormsRegressionsTestCase(TestCase): - def test_class(self): - # Tests to prevent against recurrences of earlier bugs. - extra_attrs = {'class': 'special'} - - class TestForm(Form): - f1 = CharField(max_length=10, widget=TextInput(attrs=extra_attrs)) - f2 = CharField(widget=TextInput(attrs=extra_attrs)) - - self.assertEqual(TestForm(auto_id=False).as_p(), u'<p>F1: <input type="text" class="special" name="f1" maxlength="10" /></p>\n<p>F2: <input type="text" class="special" name="f2" /></p>') - - def test_regression_3600(self): - # Tests for form i18n # - # There were some problems with form translations in #3600 - - class SomeForm(Form): - username = CharField(max_length=10, label=ugettext_lazy('Username')) - - f = SomeForm() - self.assertEqual(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) - activate('de') - self.assertEqual(f.as_p(), '<p><label for="id_username">Benutzername:</label> <input id="id_username" type="text" name="username" maxlength="10" /></p>') - activate('pl') - self.assertEqual(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() - - def test_regression_5216(self): - # There was some problems with form translations in #5216 - class SomeForm(Form): - field_1 = CharField(max_length=10, label=ugettext_lazy('field_1')) - field_2 = CharField(max_length=10, label=ugettext_lazy('field_2'), widget=TextInput(attrs={'id': 'field_2_id'})) - - f = SomeForm() - self.assertEqual(f['field_1'].label_tag(), '<label for="id_field_1">field_1</label>') - self.assertEqual(f['field_2'].label_tag(), '<label for="field_2_id">field_2</label>') - - # Unicode decoding problems... - GENDERS = ((u'\xc5', u'En tied\xe4'), (u'\xf8', u'Mies'), (u'\xdf', u'Nainen')) - - class SomeForm(Form): - somechoice = ChoiceField(choices=GENDERS, widget=RadioSelect(), label=u'\xc5\xf8\xdf') - - f = SomeForm() - self.assertEqual(f.as_p(), u'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label for="id_somechoice_0"><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label for="id_somechoice_1"><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label for="id_somechoice_2"><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) - self.assertEqual(f.clean(u'\u0448\u0442.'), u'\u0448\u0442.') - self.assertEqual(f.clean('\xd1\x88\xd1\x82.'), u'\u0448\u0442.') - - # Translated error messages used to be buggy. - activate('ru') - f = SomeForm({}) - self.assertEqual(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 for="id_somechoice_0"><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label for="id_somechoice_1"><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label for="id_somechoice_2"><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>') - deactivate() - - # Deep copying translated text shouldn't raise an error) - from django.utils.translation import gettext_lazy - - class CopyForm(Form): - degree = IntegerField(widget=Select(choices=((1, gettext_lazy('test')),))) - - f = CopyForm() - - def test_misc(self): - # 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'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data, {'data': u'xyzzy'}) - - # A form with *only* hidden fields that has errors is going to be very unusual. - class HiddenForm(Form): - data = IntegerField(widget=HiddenInput) - - f = HiddenForm({}) - self.assertEqual(f.as_p(), u'<ul class="errorlist"><li>(Hidden field data) This field is required.</li></ul>\n<p> <input type="hidden" name="data" id="id_data" /></p>') - self.assertEqual(f.as_table(), u'<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field data) This field is required.</li></ul><input type="hidden" name="data" id="id_data" /></td></tr>') - - def test_xss_error_messages(self): - ################################################### - # Tests for XSS vulnerabilities in error messages # - ################################################### - - # The forms layer doesn't escape input values directly because error messages - # might be presented in non-HTML contexts. Instead, the message is just marked - # for escaping by the template engine. So we'll need to construct a little - # silly template to trigger the escaping. - from django.template import Template, Context - t = Template('{{ form.errors }}') - - class SomeForm(Form): - field = ChoiceField(choices=[('one', 'One')]) - - f = SomeForm({'field': '<script>'}) - self.assertEqual(t.render(Context({'form': f})), u'<ul class="errorlist"><li>field<ul class="errorlist"><li>Select a valid choice. <script> is not one of the available choices.</li></ul></li></ul>') - - class SomeForm(Form): - field = MultipleChoiceField(choices=[('one', 'One')]) - - f = SomeForm({'field': ['<script>']}) - self.assertEqual(t.render(Context({'form': f})), u'<ul class="errorlist"><li>field<ul class="errorlist"><li>Select a valid choice. <script> is not one of the available choices.</li></ul></li></ul>') - - from regressiontests.forms.models import ChoiceModel - - class SomeForm(Form): - field = ModelMultipleChoiceField(ChoiceModel.objects.all()) - - f = SomeForm({'field': ['<script>']}) - self.assertEqual(t.render(Context({'form': f})), u'<ul class="errorlist"><li>field<ul class="errorlist"><li>"<script>" is not a valid value for a primary key.</li></ul></li></ul>') - - def test_regression_14234(self): - """ - Re-cleaning an instance that was added via a ModelForm should not raise - a pk uniqueness error. - - """ - class CheeseForm(ModelForm): - class Meta: - model = Cheese - - form = CheeseForm({ - 'name': 'Brie', - }) - - self.assertTrue(form.is_valid()) - - obj = form.save() - obj.name = 'Camembert' - obj.full_clean() diff --git a/parts/django/tests/regressiontests/forms/tests/util.py b/parts/django/tests/regressiontests/forms/tests/util.py deleted file mode 100644 index 8ea3bdd..0000000 --- a/parts/django/tests/regressiontests/forms/tests/util.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from django.core.exceptions import ValidationError -from django.forms.util import * -from django.utils.translation import ugettext_lazy - - -class FormsUtilTestCase(TestCase): - # Tests for forms/util.py module. - - def test_flatatt(self): - ########### - # flatatt # - ########### - - self.assertEqual(flatatt({'id': "header"}), u' id="header"') - self.assertEqual(flatatt({'class': "news", 'title': "Read this"}), u' class="news" title="Read this"') - self.assertEqual(flatatt({}), u'') - - def test_validation_error(self): - ################### - # ValidationError # - ################### - - # Can take a string. - self.assertEqual(str(ErrorList(ValidationError("There was an error.").messages)), - '<ul class="errorlist"><li>There was an error.</li></ul>') - - # Can take a unicode string. - self.assertEqual(str(ErrorList(ValidationError(u"Not \u03C0.").messages)), - '<ul class="errorlist"><li>Not π.</li></ul>') - - # Can take a lazy string. - self.assertEqual(str(ErrorList(ValidationError(ugettext_lazy("Error.")).messages)), - '<ul class="errorlist"><li>Error.</li></ul>') - - # Can take a list. - self.assertEqual(str(ErrorList(ValidationError(["Error one.", "Error two."]).messages)), - '<ul class="errorlist"><li>Error one.</li><li>Error two.</li></ul>') - - # Can take a mixture in a list. - self.assertEqual(str(ErrorList(ValidationError(["First error.", u"Not \u03C0.", ugettext_lazy("Error.")]).messages)), - '<ul class="errorlist"><li>First error.</li><li>Not π.</li><li>Error.</li></ul>') - - class VeryBadError: - def __unicode__(self): return u"A very bad error." - - # Can take a non-string. - self.assertEqual(str(ErrorList(ValidationError(VeryBadError()).messages)), - '<ul class="errorlist"><li>A very bad error.</li></ul>') - - # Escapes non-safe input but not input marked safe. - example = 'Example of link: <a href="http://www.example.com/">example</a>' - self.assertEqual(str(ErrorList([example])), - '<ul class="errorlist"><li>Example of link: <a href="http://www.example.com/">example</a></li></ul>') - self.assertEqual(str(ErrorList([mark_safe(example)])), - '<ul class="errorlist"><li>Example of link: <a href="http://www.example.com/">example</a></li></ul>') diff --git a/parts/django/tests/regressiontests/forms/tests/validators.py b/parts/django/tests/regressiontests/forms/tests/validators.py deleted file mode 100644 index ed8e8fb..0000000 --- a/parts/django/tests/regressiontests/forms/tests/validators.py +++ /dev/null @@ -1,17 +0,0 @@ -from unittest import TestCase - -from django import forms -from django.core import validators -from django.core.exceptions import ValidationError - - -class TestFieldWithValidators(TestCase): - def test_all_errors_get_reported(self): - field = forms.CharField( - validators=[validators.validate_integer, validators.validate_email] - ) - self.assertRaises(ValidationError, field.clean, 'not int nor mail') - try: - field.clean('not int nor mail') - except ValidationError, e: - self.assertEqual(2, len(e.messages)) diff --git a/parts/django/tests/regressiontests/forms/tests/widgets.py b/parts/django/tests/regressiontests/forms/tests/widgets.py deleted file mode 100644 index 9e7c6f6..0000000 --- a/parts/django/tests/regressiontests/forms/tests/widgets.py +++ /dev/null @@ -1,1070 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from decimal import Decimal -import re -import time -from unittest import TestCase -from django.conf import settings -from django.core.files.uploadedfile import SimpleUploadedFile -from django.forms import * -from django.forms.widgets import RadioFieldRenderer -from django.utils import copycompat as copy -from django.utils import formats -from django.utils.safestring import mark_safe -from django.utils.translation import activate, deactivate - - - -class FormsWidgetTestCase(TestCase): - # Each Widget class corresponds to an HTML form widget. A Widget knows how to - # render itself, given a field name and some data. Widgets don't perform - # validation. - def test_textinput(self): - w = TextInput() - self.assertEqual(w.render('email', ''), u'<input type="text" name="email" />') - self.assertEqual(w.render('email', None), u'<input type="text" name="email" />') - self.assertEqual(w.render('email', 'test@example.com'), u'<input type="text" name="email" value="test@example.com" />') - self.assertEqual(w.render('email', 'some "quoted" & ampersanded value'), u'<input type="text" name="email" value="some "quoted" & ampersanded value" />') - self.assertEqual(w.render('email', 'test@example.com', attrs={'class': 'fun'}), u'<input type="text" name="email" value="test@example.com" class="fun" />') - - # Note that doctest in Python 2.4 (and maybe 2.5?) doesn't support non-ascii - # characters in output, so we're displaying the repr() here. - self.assertEqual(w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), u'<input type="text" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" class="fun" />') - - # You can also pass 'attrs' to the constructor: - w = TextInput(attrs={'class': 'fun'}) - self.assertEqual(w.render('email', ''), u'<input type="text" class="fun" name="email" />') - self.assertEqual(w.render('email', 'foo@example.com'), u'<input type="text" class="fun" value="foo@example.com" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = TextInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', '', attrs={'class': 'special'}), u'<input type="text" class="special" name="email" />') - - # 'attrs' can be safe-strings if needed) - w = TextInput(attrs={'onBlur': mark_safe("function('foo')")}) - self.assertEqual(w.render('email', ''), u'<input onBlur="function(\'foo\')" type="text" name="email" />') - - def test_passwordinput(self): - w = PasswordInput() - self.assertEqual(w.render('email', ''), u'<input type="password" name="email" />') - self.assertEqual(w.render('email', None), u'<input type="password" name="email" />') - self.assertEqual(w.render('email', 'test@example.com'), u'<input type="password" name="email" value="test@example.com" />') - self.assertEqual(w.render('email', 'some "quoted" & ampersanded value'), u'<input type="password" name="email" value="some "quoted" & ampersanded value" />') - self.assertEqual(w.render('email', 'test@example.com', attrs={'class': 'fun'}), u'<input type="password" name="email" value="test@example.com" class="fun" />') - - # You can also pass 'attrs' to the constructor: - w = PasswordInput(attrs={'class': 'fun'}) - self.assertEqual(w.render('email', ''), u'<input type="password" class="fun" name="email" />') - self.assertEqual(w.render('email', 'foo@example.com'), u'<input type="password" class="fun" value="foo@example.com" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = PasswordInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', '', attrs={'class': 'special'}), u'<input type="password" class="special" name="email" />') - - self.assertEqual(w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), u'<input type="password" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />') - - # The render_value argument lets you specify whether the widget should render - # its value. You may want to do this for security reasons. - w = PasswordInput(render_value=True) - self.assertEqual(w.render('email', 'secret'), u'<input type="password" name="email" value="secret" />') - - w = PasswordInput(render_value=False) - self.assertEqual(w.render('email', ''), u'<input type="password" name="email" />') - self.assertEqual(w.render('email', None), u'<input type="password" name="email" />') - self.assertEqual(w.render('email', 'secret'), u'<input type="password" name="email" />') - - w = PasswordInput(attrs={'class': 'fun'}, render_value=False) - self.assertEqual(w.render('email', 'secret'), u'<input type="password" class="fun" name="email" />') - - def test_hiddeninput(self): - w = HiddenInput() - self.assertEqual(w.render('email', ''), u'<input type="hidden" name="email" />') - self.assertEqual(w.render('email', None), u'<input type="hidden" name="email" />') - self.assertEqual(w.render('email', 'test@example.com'), u'<input type="hidden" name="email" value="test@example.com" />') - self.assertEqual(w.render('email', 'some "quoted" & ampersanded value'), u'<input type="hidden" name="email" value="some "quoted" & ampersanded value" />') - self.assertEqual(w.render('email', 'test@example.com', attrs={'class': 'fun'}), u'<input type="hidden" name="email" value="test@example.com" class="fun" />') - - # You can also pass 'attrs' to the constructor: - w = HiddenInput(attrs={'class': 'fun'}) - self.assertEqual(w.render('email', ''), u'<input type="hidden" class="fun" name="email" />') - self.assertEqual(w.render('email', 'foo@example.com'), u'<input type="hidden" class="fun" value="foo@example.com" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = HiddenInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', '', attrs={'class': 'special'}), u'<input type="hidden" class="special" name="email" />') - - self.assertEqual(w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), u'<input type="hidden" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = HiddenInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', '', attrs={'class': 'special'}), u'<input type="hidden" class="special" name="email" />') - - # Boolean values are rendered to their string forms ("True" and "False"). - w = HiddenInput() - self.assertEqual(w.render('get_spam', False), u'<input type="hidden" name="get_spam" value="False" />') - self.assertEqual(w.render('get_spam', True), u'<input type="hidden" name="get_spam" value="True" />') - - def test_multiplehiddeninput(self): - w = MultipleHiddenInput() - self.assertEqual(w.render('email', []), u'') - self.assertEqual(w.render('email', None), u'') - self.assertEqual(w.render('email', ['test@example.com']), u'<input type="hidden" name="email" value="test@example.com" />') - self.assertEqual(w.render('email', ['some "quoted" & ampersanded value']), u'<input type="hidden" name="email" value="some "quoted" & ampersanded value" />') - self.assertEqual(w.render('email', ['test@example.com', 'foo@example.com']), u'<input type="hidden" name="email" value="test@example.com" />\n<input type="hidden" name="email" value="foo@example.com" />') - self.assertEqual(w.render('email', ['test@example.com'], attrs={'class': 'fun'}), u'<input type="hidden" name="email" value="test@example.com" class="fun" />') - self.assertEqual(w.render('email', ['test@example.com', 'foo@example.com'], attrs={'class': 'fun'}), u'<input type="hidden" name="email" value="test@example.com" class="fun" />\n<input type="hidden" name="email" value="foo@example.com" class="fun" />') - - # You can also pass 'attrs' to the constructor: - w = MultipleHiddenInput(attrs={'class': 'fun'}) - self.assertEqual(w.render('email', []), u'') - self.assertEqual(w.render('email', ['foo@example.com']), u'<input type="hidden" class="fun" value="foo@example.com" name="email" />') - self.assertEqual(w.render('email', ['foo@example.com', 'test@example.com']), u'<input type="hidden" class="fun" value="foo@example.com" name="email" />\n<input type="hidden" class="fun" value="test@example.com" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = MultipleHiddenInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', ['foo@example.com'], attrs={'class': 'special'}), u'<input type="hidden" class="special" value="foo@example.com" name="email" />') - - self.assertEqual(w.render('email', ['ŠĐĆŽćžšđ'], attrs={'class': 'fun'}), u'<input type="hidden" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = MultipleHiddenInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('email', ['foo@example.com'], attrs={'class': 'special'}), u'<input type="hidden" class="special" value="foo@example.com" name="email" />') - - # Each input gets a separate ID. - w = MultipleHiddenInput() - self.assertEqual(w.render('letters', list('abc'), attrs={'id': 'hideme'}), u'<input type="hidden" name="letters" value="a" id="hideme_0" />\n<input type="hidden" name="letters" value="b" id="hideme_1" />\n<input type="hidden" name="letters" value="c" id="hideme_2" />') - - def test_fileinput(self): - # FileInput widgets don't ever show the value, because the old value is of no use - # if you are updating the form or if the provided file generated an error. - w = FileInput() - self.assertEqual(w.render('email', ''), u'<input type="file" name="email" />') - self.assertEqual(w.render('email', None), u'<input type="file" name="email" />') - self.assertEqual(w.render('email', 'test@example.com'), u'<input type="file" name="email" />') - self.assertEqual(w.render('email', 'some "quoted" & ampersanded value'), u'<input type="file" name="email" />') - self.assertEqual(w.render('email', 'test@example.com', attrs={'class': 'fun'}), u'<input type="file" name="email" class="fun" />') - - # You can also pass 'attrs' to the constructor: - w = FileInput(attrs={'class': 'fun'}) - self.assertEqual(w.render('email', ''), u'<input type="file" class="fun" name="email" />') - self.assertEqual(w.render('email', 'foo@example.com'), u'<input type="file" class="fun" name="email" />') - - self.assertEqual(w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), u'<input type="file" class="fun" name="email" />') - - # Test for the behavior of _has_changed for FileInput. The value of data will - # more than likely come from request.FILES. The value of initial data will - # likely be a filename stored in the database. Since its value is of no use to - # a FileInput it is ignored. - w = FileInput() - - # No file was uploaded and no initial data. - self.assertFalse(w._has_changed(u'', None)) - - # A file was uploaded and no initial data. - self.assertTrue(w._has_changed(u'', {'filename': 'resume.txt', 'content': 'My resume'})) - - # A file was not uploaded, but there is initial data - self.assertFalse(w._has_changed(u'resume.txt', None)) - - # A file was uploaded and there is initial data (file identity is not dealt - # with here) - self.assertTrue(w._has_changed('resume.txt', {'filename': 'resume.txt', 'content': 'My resume'})) - - def test_textarea(self): - w = Textarea() - self.assertEqual(w.render('msg', ''), u'<textarea rows="10" cols="40" name="msg"></textarea>') - self.assertEqual(w.render('msg', None), u'<textarea rows="10" cols="40" name="msg"></textarea>') - self.assertEqual(w.render('msg', 'value'), u'<textarea rows="10" cols="40" name="msg">value</textarea>') - self.assertEqual(w.render('msg', 'some "quoted" & ampersanded value'), u'<textarea rows="10" cols="40" name="msg">some "quoted" & ampersanded value</textarea>') - self.assertEqual(w.render('msg', mark_safe('pre "quoted" value')), u'<textarea rows="10" cols="40" name="msg">pre "quoted" value</textarea>') - self.assertEqual(w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20}), u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>') - - # You can also pass 'attrs' to the constructor: - w = Textarea(attrs={'class': 'pretty'}) - self.assertEqual(w.render('msg', ''), u'<textarea rows="10" cols="40" name="msg" class="pretty"></textarea>') - self.assertEqual(w.render('msg', 'example'), u'<textarea rows="10" cols="40" name="msg" class="pretty">example</textarea>') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = Textarea(attrs={'class': 'pretty'}) - self.assertEqual(w.render('msg', '', attrs={'class': 'special'}), u'<textarea rows="10" cols="40" name="msg" class="special"></textarea>') - - self.assertEqual(w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), u'<textarea rows="10" cols="40" name="msg" class="fun">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>') - - def test_checkboxinput(self): - w = CheckboxInput() - self.assertEqual(w.render('is_cool', ''), u'<input type="checkbox" name="is_cool" />') - self.assertEqual(w.render('is_cool', None), u'<input type="checkbox" name="is_cool" />') - self.assertEqual(w.render('is_cool', False), u'<input type="checkbox" name="is_cool" />') - self.assertEqual(w.render('is_cool', True), u'<input checked="checked" type="checkbox" name="is_cool" />') - - # Using any value that's not in ('', None, False, True) will check the checkbox - # and set the 'value' attribute. - self.assertEqual(w.render('is_cool', 'foo'), u'<input checked="checked" type="checkbox" name="is_cool" value="foo" />') - - self.assertEqual(w.render('is_cool', False, attrs={'class': 'pretty'}), u'<input type="checkbox" name="is_cool" class="pretty" />') - - # You can also pass 'attrs' to the constructor: - w = CheckboxInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('is_cool', ''), u'<input type="checkbox" class="pretty" name="is_cool" />') - - # 'attrs' passed to render() get precedence over those passed to the constructor: - w = CheckboxInput(attrs={'class': 'pretty'}) - self.assertEqual(w.render('is_cool', '', attrs={'class': 'special'}), u'<input type="checkbox" class="special" name="is_cool" />') - - # You can pass 'check_test' to the constructor. This is a callable that takes the - # value and returns True if the box should be checked. - w = CheckboxInput(check_test=lambda value: value.startswith('hello')) - self.assertEqual(w.render('greeting', ''), u'<input type="checkbox" name="greeting" />') - self.assertEqual(w.render('greeting', 'hello'), u'<input checked="checked" type="checkbox" name="greeting" value="hello" />') - self.assertEqual(w.render('greeting', 'hello there'), u'<input checked="checked" type="checkbox" name="greeting" value="hello there" />') - self.assertEqual(w.render('greeting', 'hello & goodbye'), u'<input checked="checked" type="checkbox" name="greeting" value="hello & goodbye" />') - - # A subtlety: If the 'check_test' argument cannot handle a value and raises any - # exception during its __call__, then the exception will be swallowed and the box - # will not be checked. In this example, the 'check_test' assumes the value has a - # startswith() method, which fails for the values True, False and None. - self.assertEqual(w.render('greeting', True), u'<input type="checkbox" name="greeting" />') - self.assertEqual(w.render('greeting', False), u'<input type="checkbox" name="greeting" />') - self.assertEqual(w.render('greeting', None), u'<input type="checkbox" name="greeting" />') - - # The CheckboxInput widget will return False if the key is not found in the data - # dictionary (because HTML form submission doesn't send any result for unchecked - # checkboxes). - self.assertFalse(w.value_from_datadict({}, {}, 'testing')) - - self.assertFalse(w._has_changed(None, None)) - self.assertFalse(w._has_changed(None, u'')) - self.assertFalse(w._has_changed(u'', None)) - self.assertFalse(w._has_changed(u'', u'')) - self.assertTrue(w._has_changed(False, u'on')) - self.assertFalse(w._has_changed(True, u'on')) - self.assertTrue(w._has_changed(True, u'')) - - def test_select(self): - w = Select() - self.assertEqual(w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select name="beatle"> -<option value="J" selected="selected">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - - # If the value is None, none of the options are selected: - self.assertEqual(w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select name="beatle"> -<option value="J">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - - # If the value corresponds to a label (but not to an option value), none of the options are selected: - self.assertEqual(w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select name="beatle"> -<option value="J">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - - # The value is compared to its str(): - self.assertEqual(w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')]), """<select name="num"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - self.assertEqual(w.render('num', '2', choices=[(1, 1), (2, 2), (3, 3)]), """<select name="num"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - self.assertEqual(w.render('num', 2, choices=[(1, 1), (2, 2), (3, 3)]), """<select name="num"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - - # The 'choices' argument can be any iterable: - from itertools import chain - def get_choices(): - for i in range(5): - yield (i, i) - self.assertEqual(w.render('num', 2, choices=get_choices()), """<select name="num"> -<option value="0">0</option> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -<option value="4">4</option> -</select>""") - things = ({'id': 1, 'name': 'And Boom'}, {'id': 2, 'name': 'One More Thing!'}) - class SomeForm(Form): - somechoice = ChoiceField(choices=chain((('', '-'*9),), [(thing['id'], thing['name']) for thing in things])) - f = SomeForm() - self.assertEqual(f.as_table(), u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>') - self.assertEqual(f.as_table(), u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>') - f = SomeForm({'somechoice': 2}) - self.assertEqual(f.as_table(), u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="">---------</option>\n<option value="1">And Boom</option>\n<option value="2" selected="selected">One More Thing!</option>\n</select></td></tr>') - - # You can also pass 'choices' to the constructor: - w = Select(choices=[(1, 1), (2, 2), (3, 3)]) - self.assertEqual(w.render('num', 2), """<select name="num"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - - # If 'choices' is passed to both the constructor and render(), then they'll both be in the output: - self.assertEqual(w.render('num', 2, choices=[(4, 4), (5, 5)]), """<select name="num"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -</select>""") - - # Choices are escaped correctly - self.assertEqual(w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me')))), """<select name="escape"> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="bad">you & me</option> -<option value="good">you > me</option> -</select>""") - - # Unicode choices are correctly rendered as HTML - self.assertEqual(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]), u'<select name="email">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>') - - # If choices is passed to the constructor and is a generator, it can be iterated - # over multiple times without getting consumed: - w = Select(choices=get_choices()) - self.assertEqual(w.render('num', 2), """<select name="num"> -<option value="0">0</option> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -<option value="4">4</option> -</select>""") - self.assertEqual(w.render('num', 3), """<select name="num"> -<option value="0">0</option> -<option value="1">1</option> -<option value="2">2</option> -<option value="3" selected="selected">3</option> -<option value="4">4</option> -</select>""") - - # Choices can be nested one level in order to create HTML optgroups: - w.choices=(('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) - self.assertEqual(w.render('nestchoice', None), """<select name="nestchoice"> -<option value="outer1">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - self.assertEqual(w.render('nestchoice', 'outer1'), """<select name="nestchoice"> -<option value="outer1" selected="selected">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - self.assertEqual(w.render('nestchoice', 'inner1'), """<select name="nestchoice"> -<option value="outer1">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1" selected="selected">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - def test_nullbooleanselect(self): - w = NullBooleanSelect() - self.assertTrue(w.render('is_cool', True), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2" selected="selected">Yes</option> -<option value="3">No</option> -</select>""") - self.assertEqual(w.render('is_cool', False), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2">Yes</option> -<option value="3" selected="selected">No</option> -</select>""") - self.assertEqual(w.render('is_cool', None), """<select name="is_cool"> -<option value="1" selected="selected">Unknown</option> -<option value="2">Yes</option> -<option value="3">No</option> -</select>""") - self.assertEqual(w.render('is_cool', '2'), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2" selected="selected">Yes</option> -<option value="3">No</option> -</select>""") - self.assertEqual(w.render('is_cool', '3'), """<select name="is_cool"> -<option value="1">Unknown</option> -<option value="2">Yes</option> -<option value="3" selected="selected">No</option> -</select>""") - self.assertTrue(w._has_changed(False, None)) - self.assertTrue(w._has_changed(None, False)) - self.assertFalse(w._has_changed(None, None)) - self.assertFalse(w._has_changed(False, False)) - self.assertTrue(w._has_changed(True, False)) - self.assertTrue(w._has_changed(True, None)) - self.assertTrue(w._has_changed(True, False)) - - def test_selectmultiple(self): - w = SelectMultiple() - self.assertEqual(w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J" selected="selected">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - self.assertEqual(w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J" selected="selected">John</option> -<option value="P" selected="selected">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - self.assertEqual(w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J" selected="selected">John</option> -<option value="P" selected="selected">Paul</option> -<option value="G">George</option> -<option value="R" selected="selected">Ringo</option> -</select>""") - - # If the value is None, none of the options are selected: - self.assertEqual(w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - - # If the value corresponds to a label (but not to an option value), none of the options are selected: - self.assertEqual(w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J">John</option> -<option value="P">Paul</option> -<option value="G">George</option> -<option value="R">Ringo</option> -</select>""") - - # If multiple values are given, but some of them are not valid, the valid ones are selected: - self.assertEqual(w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select multiple="multiple" name="beatles"> -<option value="J" selected="selected">John</option> -<option value="P">Paul</option> -<option value="G" selected="selected">George</option> -<option value="R">Ringo</option> -</select>""") - - # The value is compared to its str(): - self.assertEqual(w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')]), """<select multiple="multiple" name="nums"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - self.assertEqual(w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)]), """<select multiple="multiple" name="nums"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - self.assertEqual(w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)]), """<select multiple="multiple" name="nums"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - - # The 'choices' argument can be any iterable: - def get_choices(): - for i in range(5): - yield (i, i) - self.assertEqual(w.render('nums', [2], choices=get_choices()), """<select multiple="multiple" name="nums"> -<option value="0">0</option> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -<option value="4">4</option> -</select>""") - - # You can also pass 'choices' to the constructor: - w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)]) - self.assertEqual(w.render('nums', [2]), """<select multiple="multiple" name="nums"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -</select>""") - - # If 'choices' is passed to both the constructor and render(), then they'll both be in the output: - self.assertEqual(w.render('nums', [2], choices=[(4, 4), (5, 5)]), """<select multiple="multiple" name="nums"> -<option value="1">1</option> -<option value="2" selected="selected">2</option> -<option value="3">3</option> -<option value="4">4</option> -<option value="5">5</option> -</select>""") - - # Choices are escaped correctly - self.assertEqual(w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me')))), """<select multiple="multiple" name="escape"> -<option value="1">1</option> -<option value="2">2</option> -<option value="3">3</option> -<option value="bad">you & me</option> -<option value="good">you > me</option> -</select>""") - - # Unicode choices are correctly rendered as HTML - self.assertEqual(w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]), u'<select multiple="multiple" name="nums">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>') - - # Test the usage of _has_changed - self.assertFalse(w._has_changed(None, None)) - self.assertFalse(w._has_changed([], None)) - self.assertTrue(w._has_changed(None, [u'1'])) - self.assertFalse(w._has_changed([1, 2], [u'1', u'2'])) - self.assertTrue(w._has_changed([1, 2], [u'1'])) - self.assertTrue(w._has_changed([1, 2], [u'1', u'3'])) - - # Choices can be nested one level in order to create HTML optgroups: - w.choices = (('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) - self.assertEqual(w.render('nestchoice', None), """<select multiple="multiple" name="nestchoice"> -<option value="outer1">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - self.assertEqual(w.render('nestchoice', ['outer1']), """<select multiple="multiple" name="nestchoice"> -<option value="outer1" selected="selected">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - self.assertEqual(w.render('nestchoice', ['inner1']), """<select multiple="multiple" name="nestchoice"> -<option value="outer1">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1" selected="selected">Inner 1</option> -<option value="inner2">Inner 2</option> -</optgroup> -</select>""") - - self.assertEqual(w.render('nestchoice', ['outer1', 'inner2']), """<select multiple="multiple" name="nestchoice"> -<option value="outer1" selected="selected">Outer 1</option> -<optgroup label="Group "1""> -<option value="inner1">Inner 1</option> -<option value="inner2" selected="selected">Inner 2</option> -</optgroup> -</select>""") - - def test_radioselect(self): - w = RadioSelect() - self.assertEqual(w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input checked="checked" type="radio" name="beatle" value="J" /> John</label></li> -<li><label><input type="radio" name="beatle" value="P" /> Paul</label></li> -<li><label><input type="radio" name="beatle" value="G" /> George</label></li> -<li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li> -</ul>""") - - # If the value is None, none of the options are checked: - self.assertEqual(w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input type="radio" name="beatle" value="J" /> John</label></li> -<li><label><input type="radio" name="beatle" value="P" /> Paul</label></li> -<li><label><input type="radio" name="beatle" value="G" /> George</label></li> -<li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li> -</ul>""") - - # If the value corresponds to a label (but not to an option value), none of the options are checked: - self.assertEqual(w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input type="radio" name="beatle" value="J" /> John</label></li> -<li><label><input type="radio" name="beatle" value="P" /> Paul</label></li> -<li><label><input type="radio" name="beatle" value="G" /> George</label></li> -<li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li> -</ul>""") - - # The value is compared to its str(): - self.assertEqual(w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')]), """<ul> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -</ul>""") - self.assertEqual(w.render('num', '2', choices=[(1, 1), (2, 2), (3, 3)]), """<ul> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -</ul>""") - self.assertEqual(w.render('num', 2, choices=[(1, 1), (2, 2), (3, 3)]), """<ul> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -</ul>""") - - # The 'choices' argument can be any iterable: - def get_choices(): - for i in range(5): - yield (i, i) - self.assertEqual(w.render('num', 2, choices=get_choices()), """<ul> -<li><label><input type="radio" name="num" value="0" /> 0</label></li> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -<li><label><input type="radio" name="num" value="4" /> 4</label></li> -</ul>""") - - # You can also pass 'choices' to the constructor: - w = RadioSelect(choices=[(1, 1), (2, 2), (3, 3)]) - self.assertEqual(w.render('num', 2), """<ul> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -</ul>""") - - # If 'choices' is passed to both the constructor and render(), then they'll both be in the output: - self.assertEqual(w.render('num', 2, choices=[(4, 4), (5, 5)]), """<ul> -<li><label><input type="radio" name="num" value="1" /> 1</label></li> -<li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li> -<li><label><input type="radio" name="num" value="3" /> 3</label></li> -<li><label><input type="radio" name="num" value="4" /> 4</label></li> -<li><label><input type="radio" name="num" value="5" /> 5</label></li> -</ul>""") - - # RadioSelect uses a RadioFieldRenderer to render the individual radio inputs. - # You can manipulate that object directly to customize the way the RadioSelect - # is rendered. - w = RadioSelect() - r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) - inp_set1 = [] - inp_set2 = [] - inp_set3 = [] - inp_set4 = [] - - for inp in r: - inp_set1.append(str(inp)) - inp_set2.append('%s<br />' % inp) - inp_set3.append('<p>%s %s</p>' % (inp.tag(), inp.choice_label)) - inp_set4.append('%s %s %s %s %s' % (inp.name, inp.value, inp.choice_value, inp.choice_label, inp.is_checked())) - - self.assertEqual('\n'.join(inp_set1), """<label><input checked="checked" type="radio" name="beatle" value="J" /> John</label> -<label><input type="radio" name="beatle" value="P" /> Paul</label> -<label><input type="radio" name="beatle" value="G" /> George</label> -<label><input type="radio" name="beatle" value="R" /> Ringo</label>""") - self.assertEqual('\n'.join(inp_set2), """<label><input checked="checked" type="radio" name="beatle" value="J" /> John</label><br /> -<label><input type="radio" name="beatle" value="P" /> Paul</label><br /> -<label><input type="radio" name="beatle" value="G" /> George</label><br /> -<label><input type="radio" name="beatle" value="R" /> Ringo</label><br />""") - self.assertEqual('\n'.join(inp_set3), """<p><input checked="checked" type="radio" name="beatle" value="J" /> John</p> -<p><input type="radio" name="beatle" value="P" /> Paul</p> -<p><input type="radio" name="beatle" value="G" /> George</p> -<p><input type="radio" name="beatle" value="R" /> Ringo</p>""") - self.assertEqual('\n'.join(inp_set4), """beatle J J John True -beatle J P Paul False -beatle J G George False -beatle J R Ringo False""") - - # You can create your own custom renderers for RadioSelect to use. - class MyRenderer(RadioFieldRenderer): - def render(self): - return u'<br />\n'.join([unicode(choice) for choice in self]) - w = RadioSelect(renderer=MyRenderer) - self.assertEqual(w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> -<label><input type="radio" name="beatle" value="P" /> Paul</label><br /> -<label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> -<label><input type="radio" name="beatle" value="R" /> Ringo</label>""") - - # Or you can use custom RadioSelect fields that use your custom renderer. - class CustomRadioSelect(RadioSelect): - renderer = MyRenderer - w = CustomRadioSelect() - self.assertEqual(w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> -<label><input type="radio" name="beatle" value="P" /> Paul</label><br /> -<label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> -<label><input type="radio" name="beatle" value="R" /> Ringo</label>""") - - # A RadioFieldRenderer object also allows index access to individual RadioInput - w = RadioSelect() - r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) - self.assertEqual(str(r[1]), '<label><input type="radio" name="beatle" value="P" /> Paul</label>') - self.assertEqual(str(r[0]), '<label><input checked="checked" type="radio" name="beatle" value="J" /> John</label>') - self.assertTrue(r[0].is_checked()) - self.assertFalse(r[1].is_checked()) - self.assertEqual((r[1].name, r[1].value, r[1].choice_value, r[1].choice_label), ('beatle', u'J', u'P', u'Paul')) - - try: - r[10] - self.fail("This offset should not exist.") - except IndexError: - pass - - # Choices are escaped correctly - w = RadioSelect() - self.assertEqual(w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me')))), """<ul> -<li><label><input type="radio" name="escape" value="bad" /> you & me</label></li> -<li><label><input type="radio" name="escape" value="good" /> you > me</label></li> -</ul>""") - - # Unicode choices are correctly rendered as HTML - w = RadioSelect() - self.assertEqual(unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])), u'<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>') - - # Attributes provided at instantiation are passed to the constituent inputs - w = RadioSelect(attrs={'id':'foo'}) - self.assertEqual(w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label for="foo_0"><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li> -<li><label for="foo_1"><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li> -<li><label for="foo_2"><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li> -<li><label for="foo_3"><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li> -</ul>""") - - # Attributes provided at render-time are passed to the constituent inputs - w = RadioSelect() - self.assertEqual(w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'}), """<ul> -<li><label for="bar_0"><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li> -<li><label for="bar_1"><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li> -<li><label for="bar_2"><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li> -<li><label for="bar_3"><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li> -</ul>""") - - def test_checkboxselectmultiple(self): - w = CheckboxSelectMultiple() - self.assertEqual(w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - self.assertEqual(w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - self.assertEqual(w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input checked="checked" type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - - # If the value is None, none of the options are selected: - self.assertEqual(w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - - # If the value corresponds to a label (but not to an option value), none of the options are selected: - self.assertEqual(w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - - # If multiple values are given, but some of them are not valid, the valid ones are selected: - self.assertEqual(w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<ul> -<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> -<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> -<li><label><input checked="checked" type="checkbox" name="beatles" value="G" /> George</label></li> -<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> -</ul>""") - - # The value is compared to its str(): - self.assertEqual(w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')]), """<ul> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -</ul>""") - self.assertEqual(w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)]), """<ul> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -</ul>""") - self.assertEqual(w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)]), """<ul> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -</ul>""") - - # The 'choices' argument can be any iterable: - def get_choices(): - for i in range(5): - yield (i, i) - self.assertEqual(w.render('nums', [2], choices=get_choices()), """<ul> -<li><label><input type="checkbox" name="nums" value="0" /> 0</label></li> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -<li><label><input type="checkbox" name="nums" value="4" /> 4</label></li> -</ul>""") - - # You can also pass 'choices' to the constructor: - w = CheckboxSelectMultiple(choices=[(1, 1), (2, 2), (3, 3)]) - self.assertEqual(w.render('nums', [2]), """<ul> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -</ul>""") - - # If 'choices' is passed to both the constructor and render(), then they'll both be in the output: - self.assertEqual(w.render('nums', [2], choices=[(4, 4), (5, 5)]), """<ul> -<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> -<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> -<li><label><input type="checkbox" name="nums" value="4" /> 4</label></li> -<li><label><input type="checkbox" name="nums" value="5" /> 5</label></li> -</ul>""") - - # Choices are escaped correctly - self.assertEqual(w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me')))), """<ul> -<li><label><input type="checkbox" name="escape" value="1" /> 1</label></li> -<li><label><input type="checkbox" name="escape" value="2" /> 2</label></li> -<li><label><input type="checkbox" name="escape" value="3" /> 3</label></li> -<li><label><input type="checkbox" name="escape" value="bad" /> you & me</label></li> -<li><label><input type="checkbox" name="escape" value="good" /> you > me</label></li> -</ul>""") - - # Test the usage of _has_changed - self.assertFalse(w._has_changed(None, None)) - self.assertFalse(w._has_changed([], None)) - self.assertTrue(w._has_changed(None, [u'1'])) - self.assertFalse(w._has_changed([1, 2], [u'1', u'2'])) - self.assertTrue(w._has_changed([1, 2], [u'1'])) - self.assertTrue(w._has_changed([1, 2], [u'1', u'3'])) - self.assertFalse(w._has_changed([2, 1], [u'1', u'2'])) - - # Unicode choices are correctly rendered as HTML - self.assertEqual(w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]), u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>') - - # Each input gets a separate ID - self.assertEqual(CheckboxSelectMultiple().render('letters', list('ac'), choices=zip(list('abc'), list('ABC')), attrs={'id': 'abc'}), """<ul> -<li><label for="abc_0"><input checked="checked" type="checkbox" name="letters" value="a" id="abc_0" /> A</label></li> -<li><label for="abc_1"><input type="checkbox" name="letters" value="b" id="abc_1" /> B</label></li> -<li><label for="abc_2"><input checked="checked" type="checkbox" name="letters" value="c" id="abc_2" /> C</label></li> -</ul>""") - - def test_multi(self): - class MyMultiWidget(MultiWidget): - def decompress(self, value): - if value: - return value.split('__') - return ['', ''] - def format_output(self, rendered_widgets): - return u'<br />'.join(rendered_widgets) - - w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'}))) - self.assertEqual(w.render('name', ['john', 'lennon']), u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />') - self.assertEqual(w.render('name', 'john__lennon'), u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />') - self.assertEqual(w.render('name', 'john__lennon', attrs={'id':'foo'}), u'<input id="foo_0" type="text" class="big" value="john" name="name_0" /><br /><input id="foo_1" type="text" class="small" value="lennon" name="name_1" />') - w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'}) - self.assertEqual(w.render('name', ['john', 'lennon']), u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />') - - w = MyMultiWidget(widgets=(TextInput(), TextInput())) - - # test with no initial data - self.assertTrue(w._has_changed(None, [u'john', u'lennon'])) - - # test when the data is the same as initial - self.assertFalse(w._has_changed(u'john__lennon', [u'john', u'lennon'])) - - # test when the first widget's data has changed - self.assertTrue(w._has_changed(u'john__lennon', [u'alfred', u'lennon'])) - - # test when the last widget's data has changed. this ensures that it is not - # short circuiting while testing the widgets. - self.assertTrue(w._has_changed(u'john__lennon', [u'john', u'denver'])) - - def test_splitdatetime(self): - w = SplitDateTimeWidget() - self.assertEqual(w.render('date', ''), u'<input type="text" name="date_0" /><input type="text" name="date_1" />') - self.assertEqual(w.render('date', None), u'<input type="text" name="date_0" /><input type="text" name="date_1" />') - self.assertEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" name="date_0" value="2006-01-10" /><input type="text" name="date_1" value="07:30:00" />') - self.assertEqual(w.render('date', [datetime.date(2006, 1, 10), datetime.time(7, 30)]), u'<input type="text" name="date_0" value="2006-01-10" /><input type="text" name="date_1" value="07:30:00" />') - - # You can also pass 'attrs' to the constructor. In this case, the attrs will be - w = SplitDateTimeWidget(attrs={'class': 'pretty'}) - self.assertEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" class="pretty" value="2006-01-10" name="date_0" /><input type="text" class="pretty" value="07:30:00" name="date_1" />') - - # Use 'date_format' and 'time_format' to change the way a value is displayed. - w = SplitDateTimeWidget(date_format='%d/%m/%Y', time_format='%H:%M') - self.assertEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" name="date_0" value="10/01/2006" /><input type="text" name="date_1" value="07:30" />') - - self.assertTrue(w._has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), [u'2008-05-06', u'12:40:00'])) - self.assertFalse(w._has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), [u'06/05/2008', u'12:40'])) - self.assertTrue(w._has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), [u'06/05/2008', u'12:41'])) - - def test_datetimeinput(self): - w = DateTimeInput() - self.assertEqual(w.render('date', None), u'<input type="text" name="date" />') - d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548) - self.assertEqual(str(d), '2007-09-17 12:51:34.482548') - - # The microseconds are trimmed on display, by default. - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="2007-09-17 12:51:34" />') - self.assertEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51, 34)), u'<input type="text" name="date" value="2007-09-17 12:51:34" />') - self.assertEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), u'<input type="text" name="date" value="2007-09-17 12:51:00" />') - - # Use 'format' to change the way a value is displayed. - w = DateTimeInput(format='%d/%m/%Y %H:%M') - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="17/09/2007 12:51" />') - self.assertFalse(w._has_changed(d, '17/09/2007 12:51')) - - # Make sure a custom format works with _has_changed. The hidden input will use - data = datetime.datetime(2010, 3, 6, 12, 0, 0) - custom_format = '%d.%m.%Y %H:%M' - w = DateTimeInput(format=custom_format) - self.assertFalse(w._has_changed(formats.localize_input(data), data.strftime(custom_format))) - - def test_dateinput(self): - w = DateInput() - self.assertEqual(w.render('date', None), u'<input type="text" name="date" />') - d = datetime.date(2007, 9, 17) - self.assertEqual(str(d), '2007-09-17') - - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="2007-09-17" />') - self.assertEqual(w.render('date', datetime.date(2007, 9, 17)), u'<input type="text" name="date" value="2007-09-17" />') - - # We should be able to initialize from a unicode value. - self.assertEqual(w.render('date', u'2007-09-17'), u'<input type="text" name="date" value="2007-09-17" />') - - # Use 'format' to change the way a value is displayed. - w = DateInput(format='%d/%m/%Y') - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="17/09/2007" />') - self.assertFalse(w._has_changed(d, '17/09/2007')) - - # Make sure a custom format works with _has_changed. The hidden input will use - data = datetime.date(2010, 3, 6) - custom_format = '%d.%m.%Y' - w = DateInput(format=custom_format) - self.assertFalse(w._has_changed(formats.localize_input(data), data.strftime(custom_format))) - - def test_timeinput(self): - w = TimeInput() - self.assertEqual(w.render('time', None), u'<input type="text" name="time" />') - t = datetime.time(12, 51, 34, 482548) - self.assertEqual(str(t), '12:51:34.482548') - - # The microseconds are trimmed on display, by default. - self.assertEqual(w.render('time', t), u'<input type="text" name="time" value="12:51:34" />') - self.assertEqual(w.render('time', datetime.time(12, 51, 34)), u'<input type="text" name="time" value="12:51:34" />') - self.assertEqual(w.render('time', datetime.time(12, 51)), u'<input type="text" name="time" value="12:51:00" />') - - # We should be able to initialize from a unicode value. - self.assertEqual(w.render('time', u'13:12:11'), u'<input type="text" name="time" value="13:12:11" />') - - # Use 'format' to change the way a value is displayed. - w = TimeInput(format='%H:%M') - self.assertEqual(w.render('time', t), u'<input type="text" name="time" value="12:51" />') - self.assertFalse(w._has_changed(t, '12:51')) - - # Make sure a custom format works with _has_changed. The hidden input will use - data = datetime.time(13, 0) - custom_format = '%I:%M %p' - w = TimeInput(format=custom_format) - self.assertFalse(w._has_changed(formats.localize_input(data), data.strftime(custom_format))) - - def test_splithiddendatetime(self): - from django.forms.widgets import SplitHiddenDateTimeWidget - - w = SplitHiddenDateTimeWidget() - self.assertEqual(w.render('date', ''), u'<input type="hidden" name="date_0" /><input type="hidden" name="date_1" />') - d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548) - self.assertEqual(str(d), '2007-09-17 12:51:34.482548') - self.assertEqual(w.render('date', d), u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:34" />') - self.assertEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51, 34)), u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:34" />') - self.assertEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:00" />') - - -class FormsI18NWidgetsTestCase(TestCase): - def setUp(self): - super(FormsI18NWidgetsTestCase, self).setUp() - self.old_use_l10n = getattr(settings, 'USE_L10N', False) - settings.USE_L10N = True - activate('de-at') - - def tearDown(self): - deactivate() - settings.USE_L10N = self.old_use_l10n - super(FormsI18NWidgetsTestCase, self).tearDown() - - def test_splitdatetime(self): - w = SplitDateTimeWidget(date_format='%d/%m/%Y', time_format='%H:%M') - self.assertTrue(w._has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), [u'06.05.2008', u'12:41'])) - - def test_datetimeinput(self): - w = DateTimeInput() - d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548) - w.is_localized = True - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="17.09.2007 12:51:34" />') - - def test_dateinput(self): - w = DateInput() - d = datetime.date(2007, 9, 17) - w.is_localized = True - self.assertEqual(w.render('date', d), u'<input type="text" name="date" value="17.09.2007" />') - - def test_timeinput(self): - w = TimeInput() - t = datetime.time(12, 51, 34, 482548) - w.is_localized = True - self.assertEqual(w.render('time', t), u'<input type="text" name="time" value="12:51:34" />') - - def test_splithiddendatetime(self): - from django.forms.widgets import SplitHiddenDateTimeWidget - - w = SplitHiddenDateTimeWidget() - w.is_localized = True - self.assertEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), u'<input type="hidden" name="date_0" value="17.09.2007" /><input type="hidden" name="date_1" value="12:51:00" />') - - -class SelectAndTextWidget(MultiWidget): - """ - MultiWidget subclass - """ - def __init__(self, choices=[]): - widgets = [ - RadioSelect(choices=choices), - TextInput - ] - super(SelectAndTextWidget, self).__init__(widgets) - - def _set_choices(self, choices): - """ - When choices are set for this widget, we want to pass those along to the Select widget - """ - self.widgets[0].choices = choices - def _get_choices(self): - """ - The choices for this widget are the Select widget's choices - """ - return self.widgets[0].choices - choices = property(_get_choices, _set_choices) - - -class WidgetTests(TestCase): - def test_12048(self): - # See ticket #12048. - w1 = SelectAndTextWidget(choices=[1,2,3]) - w2 = copy.deepcopy(w1) - w2.choices = [4,5,6] - # w2 ought to be independent of w1, since MultiWidget ought - # to make a copy of its sub-widgets when it is copied. - self.assertEqual(w1.choices, [1,2,3]) - - def test_13390(self): - # See ticket #13390 - class SplitDateForm(Form): - field = DateTimeField(widget=SplitDateTimeWidget, required=False) - - form = SplitDateForm({'field': ''}) - self.assertTrue(form.is_valid()) - form = SplitDateForm({'field': ['', '']}) - self.assertTrue(form.is_valid()) - - class SplitDateRequiredForm(Form): - field = DateTimeField(widget=SplitDateTimeWidget, required=True) - - form = SplitDateRequiredForm({'field': ''}) - self.assertFalse(form.is_valid()) - form = SplitDateRequiredForm({'field': ['', '']}) - self.assertFalse(form.is_valid()) - diff --git a/parts/django/tests/regressiontests/formwizard/__init__.py b/parts/django/tests/regressiontests/formwizard/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/formwizard/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/formwizard/forms.py b/parts/django/tests/regressiontests/formwizard/forms.py deleted file mode 100644 index f458eda..0000000 --- a/parts/django/tests/regressiontests/formwizard/forms.py +++ /dev/null @@ -1,18 +0,0 @@ -from django import forms -from django.contrib.formtools.wizard import FormWizard -from django.http import HttpResponse - -class Page1(forms.Form): - name = forms.CharField(max_length=100) - thirsty = forms.NullBooleanField() - -class Page2(forms.Form): - address1 = forms.CharField(max_length=100) - address2 = forms.CharField(max_length=100) - -class Page3(forms.Form): - random_crap = forms.CharField(max_length=100) - -class ContactWizard(FormWizard): - def done(self, request, form_list): - return HttpResponse("") diff --git a/parts/django/tests/regressiontests/formwizard/models.py b/parts/django/tests/regressiontests/formwizard/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/formwizard/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/formwizard/templates/forms/wizard.html b/parts/django/tests/regressiontests/formwizard/templates/forms/wizard.html deleted file mode 100644 index a31378f..0000000 --- a/parts/django/tests/regressiontests/formwizard/templates/forms/wizard.html +++ /dev/null @@ -1,13 +0,0 @@ -<html>
- <body>
- <p>Step {{ step }} of {{ step_count }}</p>
- <form action="." method="post">
- <table>
- {{ form }}
- </table>
- <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
- {{ previous_fields|safe }}
- <input type="submit">
- </form>
- </body>
-</html>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/formwizard/tests.py b/parts/django/tests/regressiontests/formwizard/tests.py deleted file mode 100644 index 0c94d2e..0000000 --- a/parts/django/tests/regressiontests/formwizard/tests.py +++ /dev/null @@ -1,59 +0,0 @@ -import re -from django import forms -from django.test import TestCase - -class FormWizardWithNullBooleanField(TestCase): - urls = 'regressiontests.formwizard.urls' - - input_re = re.compile('name="([^"]+)" value="([^"]+)"') - - wizard_url = '/wiz/' - wizard_step_data = ( - { - '0-name': 'Pony', - '0-thirsty': '2', - }, - { - '1-address1': '123 Main St', - '1-address2': 'Djangoland', - }, - { - '2-random_crap': 'blah blah', - } - ) - - def grabFieldData(self, response): - """ - Pull the appropriate field data from the context to pass to the next wizard step - """ - previous_fields = response.context['previous_fields'] - fields = {'wizard_step': response.context['step0']} - - def grab(m): - fields[m.group(1)] = m.group(2) - return '' - - self.input_re.sub(grab, previous_fields) - return fields - - def checkWizardStep(self, response, step_no): - """ - Helper function to test each step of the wizard - - Make sure the call succeeded - - Make sure response is the proper step number - - return the result from the post for the next step - """ - step_count = len(self.wizard_step_data) - - self.assertEqual(response.status_code, 200) - self.assertContains(response, 'Step %d of %d' % (step_no, step_count)) - - data = self.grabFieldData(response) - data.update(self.wizard_step_data[step_no - 1]) - - return self.client.post(self.wizard_url, data) - - def testWizard(self): - response = self.client.get(self.wizard_url) - for step_no in range(1, len(self.wizard_step_data) + 1): - response = self.checkWizardStep(response, step_no) diff --git a/parts/django/tests/regressiontests/formwizard/urls.py b/parts/django/tests/regressiontests/formwizard/urls.py deleted file mode 100644 index d964bc6..0000000 --- a/parts/django/tests/regressiontests/formwizard/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.conf.urls.defaults import * -from forms import ContactWizard, Page1, Page2, Page3 - -urlpatterns = patterns('', - url(r'^wiz/$', ContactWizard([Page1, Page2, Page3])), - ) diff --git a/parts/django/tests/regressiontests/generic_inline_admin/__init__.py b/parts/django/tests/regressiontests/generic_inline_admin/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/generic_inline_admin/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/generic_inline_admin/fixtures/users.xml b/parts/django/tests/regressiontests/generic_inline_admin/fixtures/users.xml deleted file mode 100644 index 6cf441f..0000000 --- a/parts/django/tests/regressiontests/generic_inline_admin/fixtures/users.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> -</django-objects>
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/generic_inline_admin/models.py b/parts/django/tests/regressiontests/generic_inline_admin/models.py deleted file mode 100644 index 329c487..0000000 --- a/parts/django/tests/regressiontests/generic_inline_admin/models.py +++ /dev/null @@ -1,108 +0,0 @@ -from django.db import models -from django.contrib import admin -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType - -class Episode(models.Model): - name = models.CharField(max_length=100) - -class Media(models.Model): - """ - Media that can associated to any object. - """ - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey() - url = models.URLField(verify_exists=False) - - def __unicode__(self): - return self.url - -class MediaInline(generic.GenericTabularInline): - model = Media - -class EpisodeAdmin(admin.ModelAdmin): - inlines = [ - MediaInline, - ] -admin.site.register(Episode, EpisodeAdmin) - -# -# These models let us test the different GenericInline settings at -# different urls in the admin site. -# - -# -# Generic inline with extra = 0 -# - -class EpisodeExtra(Episode): - pass - -class MediaExtraInline(generic.GenericTabularInline): - model = Media - extra = 0 - -admin.site.register(EpisodeExtra, inlines=[MediaExtraInline]) - -# -# Generic inline with extra and max_num -# - -class EpisodeMaxNum(Episode): - pass - -class MediaMaxNumInline(generic.GenericTabularInline): - model = Media - extra = 5 - max_num = 2 - -admin.site.register(EpisodeMaxNum, inlines=[MediaMaxNumInline]) - -# -# Generic inline with exclude -# - -class EpisodeExclude(Episode): - pass - -class MediaExcludeInline(generic.GenericTabularInline): - model = Media - exclude = ['url'] - -admin.site.register(EpisodeExclude, inlines=[MediaExcludeInline]) - -# -# Generic inline with unique_together -# - -class PhoneNumber(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') - phone_number = models.CharField(max_length=30) - - class Meta: - unique_together = (('content_type', 'object_id', 'phone_number',),) - -class Contact(models.Model): - name = models.CharField(max_length=50) - phone_numbers = generic.GenericRelation(PhoneNumber) - -class PhoneNumberInline(generic.GenericTabularInline): - model = PhoneNumber - -admin.site.register(Contact, inlines=[PhoneNumberInline]) - -# -# Generic inline with can_delete=False -# - -class EpisodePermanent(Episode): - pass - -class MediaPermanentInline(generic.GenericTabularInline): - model = Media - can_delete = False - -admin.site.register(EpisodePermanent, inlines=[MediaPermanentInline]) diff --git a/parts/django/tests/regressiontests/generic_inline_admin/tests.py b/parts/django/tests/regressiontests/generic_inline_admin/tests.py deleted file mode 100644 index d5531f0..0000000 --- a/parts/django/tests/regressiontests/generic_inline_admin/tests.py +++ /dev/null @@ -1,214 +0,0 @@ -# coding: utf-8 - -from django.conf import settings -from django.contrib.contenttypes.generic import generic_inlineformset_factory -from django.test import TestCase - -# local test models -from models import Episode, EpisodeExtra, EpisodeMaxNum, EpisodeExclude, \ - Media, EpisodePermanent, MediaPermanentInline - - -class GenericAdminViewTest(TestCase): - fixtures = ['users.xml'] - - def setUp(self): - # set TEMPLATE_DEBUG to True to ensure {% include %} will raise - # exceptions since that is how inlines are rendered and #9498 will - # bubble up if it is an issue. - self.original_template_debug = settings.TEMPLATE_DEBUG - settings.TEMPLATE_DEBUG = True - self.client.login(username='super', password='secret') - - # Can't load content via a fixture (since the GenericForeignKey - # relies on content type IDs, which will vary depending on what - # other tests have been run), thus we do it here. - e = Episode.objects.create(name='This Week in Django') - self.episode_pk = e.pk - m = Media(content_object=e, url='http://example.com/podcast.mp3') - m.save() - self.mp3_media_pk = m.pk - - m = Media(content_object=e, url='http://example.com/logo.png') - m.save() - self.png_media_pk = m.pk - - def tearDown(self): - self.client.logout() - settings.TEMPLATE_DEBUG = self.original_template_debug - - def testBasicAddGet(self): - """ - A smoke test to ensure GET on the add_view works. - """ - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/add/') - self.assertEqual(response.status_code, 200) - - def testBasicEditGet(self): - """ - A smoke test to ensure GET on the change_view works. - """ - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk) - self.assertEqual(response.status_code, 200) - - def testBasicAddPost(self): - """ - A smoke test to ensure POST on add_view works. - """ - post_data = { - "name": u"This Week in Django", - # inline data - "generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"1", - "generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"0", - "generic_inline_admin-media-content_type-object_id-MAX_NUM_FORMS": u"0", - } - response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/episode/add/', post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - def testBasicEditPost(self): - """ - A smoke test to ensure POST on edit_view works. - """ - post_data = { - "name": u"This Week in Django", - # inline data - "generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"3", - "generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"2", - "generic_inline_admin-media-content_type-object_id-MAX_NUM_FORMS": u"0", - "generic_inline_admin-media-content_type-object_id-0-id": u"%d" % self.mp3_media_pk, - "generic_inline_admin-media-content_type-object_id-0-url": u"http://example.com/podcast.mp3", - "generic_inline_admin-media-content_type-object_id-1-id": u"%d" % self.png_media_pk, - "generic_inline_admin-media-content_type-object_id-1-url": u"http://example.com/logo.png", - "generic_inline_admin-media-content_type-object_id-2-id": u"", - "generic_inline_admin-media-content_type-object_id-2-url": u"", - } - url = '/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk - response = self.client.post(url, post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - - def testGenericInlineFormset(self): - EpisodeMediaFormSet = generic_inlineformset_factory(Media, can_delete=False, extra=3) - e = Episode.objects.get(name='This Week in Django') - - # Works with no queryset - formset = EpisodeMediaFormSet(instance=e) - self.assertEquals(len(formset.forms), 5) - self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/podcast.mp3" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>' % self.mp3_media_pk) - self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" value="%s" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>' % self.png_media_pk) - self.assertEquals(formset.forms[2].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-2-url" type="text" name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>') - - # A queryset can be used to alter display ordering - formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.order_by('url')) - self.assertEquals(len(formset.forms), 5) - self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>' % self.png_media_pk) - self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" value="http://example.com/podcast.mp3" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" value="%s" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>' % self.mp3_media_pk) - self.assertEquals(formset.forms[2].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-2-url" type="text" name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>') - - - # Works with a queryset that omits items - formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.filter(url__endswith=".png")) - self.assertEquals(len(formset.forms), 4) - self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>' % self.png_media_pk) - self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>') - - def testGenericInlineFormsetFactory(self): - # Regression test for #10522. - inline_formset = generic_inlineformset_factory(Media, - exclude=('url',)) - - # Regression test for #12340. - e = Episode.objects.get(name='This Week in Django') - formset = inline_formset(instance=e) - self.assertTrue(formset.get_queryset().ordered) - -class GenericInlineAdminParametersTest(TestCase): - fixtures = ['users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def _create_object(self, model): - """ - Create a model with an attached Media object via GFK. We can't - load content via a fixture (since the GenericForeignKey relies on - content type IDs, which will vary depending on what other tests - have been run), thus we do it here. - """ - e = model.objects.create(name='This Week in Django') - Media.objects.create(content_object=e, url='http://example.com/podcast.mp3') - return e - - def testNoParam(self): - """ - With one initial form, extra (default) at 3, there should be 4 forms. - """ - e = self._create_object(Episode) - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/%s/' % e.pk) - formset = response.context['inline_admin_formsets'][0].formset - self.assertEqual(formset.total_form_count(), 4) - self.assertEqual(formset.initial_form_count(), 1) - - def testExtraParam(self): - """ - With extra=0, there should be one form. - """ - e = self._create_object(EpisodeExtra) - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeextra/%s/' % e.pk) - formset = response.context['inline_admin_formsets'][0].formset - self.assertEqual(formset.total_form_count(), 1) - self.assertEqual(formset.initial_form_count(), 1) - - def testMaxNumParam(self): - """ - With extra=5 and max_num=2, there should be only 2 forms. - """ - e = self._create_object(EpisodeMaxNum) - inline_form_data = '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-TOTAL_FORMS" value="2" id="id_generic_inline_admin-media-content_type-object_id-TOTAL_FORMS" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-INITIAL_FORMS" value="1" id="id_generic_inline_admin-media-content_type-object_id-INITIAL_FORMS" />' - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodemaxnum/%s/' % e.pk) - formset = response.context['inline_admin_formsets'][0].formset - self.assertEqual(formset.total_form_count(), 2) - self.assertEqual(formset.initial_form_count(), 1) - - def testExcludeParam(self): - """ - Generic inline formsets should respect include. - """ - e = self._create_object(EpisodeExclude) - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeexclude/%s/' % e.pk) - formset = response.context['inline_admin_formsets'][0].formset - self.assertFalse('url' in formset.forms[0], 'The formset has excluded "url" field.') - -class GenericInlineAdminWithUniqueTogetherTest(TestCase): - fixtures = ['users.xml'] - - def setUp(self): - self.client.login(username='super', password='secret') - - def tearDown(self): - self.client.logout() - - def testAdd(self): - post_data = { - "name": u"John Doe", - # inline data - "generic_inline_admin-phonenumber-content_type-object_id-TOTAL_FORMS": u"1", - "generic_inline_admin-phonenumber-content_type-object_id-INITIAL_FORMS": u"0", - "generic_inline_admin-phonenumber-content_type-object_id-MAX_NUM_FORMS": u"0", - "generic_inline_admin-phonenumber-content_type-object_id-0-id": "", - "generic_inline_admin-phonenumber-content_type-object_id-0-phone_number": "555-555-5555", - } - response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/contact/add/') - self.assertEqual(response.status_code, 200) - response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/contact/add/', post_data) - self.assertEqual(response.status_code, 302) # redirect somewhere - -class NoInlineDeletionTest(TestCase): - def test_no_deletion(self): - fake_site = object() - inline = MediaPermanentInline(EpisodePermanent, fake_site) - fake_request = object() - formset = inline.get_formset(fake_request) - self.assertFalse(formset.can_delete) diff --git a/parts/django/tests/regressiontests/generic_inline_admin/urls.py b/parts/django/tests/regressiontests/generic_inline_admin/urls.py deleted file mode 100644 index c3e8af8..0000000 --- a/parts/django/tests/regressiontests/generic_inline_admin/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.conf.urls.defaults import * -from django.contrib import admin - -urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), -) diff --git a/parts/django/tests/regressiontests/generic_relations_regress/__init__.py b/parts/django/tests/regressiontests/generic_relations_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/generic_relations_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/generic_relations_regress/models.py b/parts/django/tests/regressiontests/generic_relations_regress/models.py deleted file mode 100644 index d28385d..0000000 --- a/parts/django/tests/regressiontests/generic_relations_regress/models.py +++ /dev/null @@ -1,79 +0,0 @@ -from django.db import models -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType - -__all__ = ('Link', 'Place', 'Restaurant', 'Person', 'Address', - 'CharLink', 'TextLink', 'OddRelation1', 'OddRelation2', - 'Contact', 'Organization', 'Note') - -class Link(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey() - - def __unicode__(self): - return "Link to %s id=%s" % (self.content_type, self.object_id) - -class Place(models.Model): - name = models.CharField(max_length=100) - links = generic.GenericRelation(Link) - - def __unicode__(self): - return "Place: %s" % self.name - -class Restaurant(Place): - def __unicode__(self): - return "Restaurant: %s" % self.name - -class Address(models.Model): - street = models.CharField(max_length=80) - city = models.CharField(max_length=50) - state = models.CharField(max_length=2) - zipcode = models.CharField(max_length=5) - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey() - - def __unicode__(self): - return '%s %s, %s %s' % (self.street, self.city, self.state, self.zipcode) - -class Person(models.Model): - account = models.IntegerField(primary_key=True) - name = models.CharField(max_length=128) - addresses = generic.GenericRelation(Address) - - def __unicode__(self): - return self.name - -class CharLink(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.CharField(max_length=100) - content_object = generic.GenericForeignKey() - -class TextLink(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.TextField() - content_object = generic.GenericForeignKey() - -class OddRelation1(models.Model): - name = models.CharField(max_length=100) - clinks = generic.GenericRelation(CharLink) - -class OddRelation2(models.Model): - name = models.CharField(max_length=100) - tlinks = generic.GenericRelation(TextLink) - -# models for test_q_object_or: -class Note(models.Model): - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey() - note = models.TextField() - -class Contact(models.Model): - notes = generic.GenericRelation(Note) - -class Organization(models.Model): - name = models.CharField(max_length=255) - contacts = models.ManyToManyField(Contact, related_name='organizations') - diff --git a/parts/django/tests/regressiontests/generic_relations_regress/tests.py b/parts/django/tests/regressiontests/generic_relations_regress/tests.py deleted file mode 100644 index 45e8674..0000000 --- a/parts/django/tests/regressiontests/generic_relations_regress/tests.py +++ /dev/null @@ -1,74 +0,0 @@ -from django.test import TestCase -from django.contrib.contenttypes.models import ContentType -from django.db.models import Q -from models import * - -class GenericRelationTests(TestCase): - - def test_inherited_models_content_type(self): - """ - Test that GenericRelations on inherited classes use the correct content - type. - """ - - p = Place.objects.create(name="South Park") - r = Restaurant.objects.create(name="Chubby's") - l1 = Link.objects.create(content_object=p) - l2 = Link.objects.create(content_object=r) - self.assertEqual(list(p.links.all()), [l1]) - self.assertEqual(list(r.links.all()), [l2]) - - def test_reverse_relation_pk(self): - """ - Test that the correct column name is used for the primary key on the - originating model of a query. See #12664. - """ - p = Person.objects.create(account=23, name='Chef') - a = Address.objects.create(street='123 Anywhere Place', - city='Conifer', state='CO', - zipcode='80433', content_object=p) - - qs = Person.objects.filter(addresses__zipcode='80433') - self.assertEqual(1, qs.count()) - self.assertEqual('Chef', qs[0].name) - - def test_charlink_delete(self): - oddrel = OddRelation1.objects.create(name='clink') - cl = CharLink.objects.create(content_object=oddrel) - oddrel.delete() - - def test_textlink_delete(self): - oddrel = OddRelation2.objects.create(name='tlink') - tl = TextLink.objects.create(content_object=oddrel) - oddrel.delete() - - def test_q_object_or(self): - """ - Tests that SQL query parameters for generic relations are properly - grouped when OR is used. - - Test for bug http://code.djangoproject.com/ticket/11535 - - In this bug the first query (below) works while the second, with the - query parameters the same but in reverse order, does not. - - The issue is that the generic relation conditions do not get properly - grouped in parentheses. - """ - note_contact = Contact.objects.create() - org_contact = Contact.objects.create() - note = Note.objects.create(note='note', content_object=note_contact) - org = Organization.objects.create(name='org name') - org.contacts.add(org_contact) - # search with a non-matching note and a matching org name - qs = Contact.objects.filter(Q(notes__note__icontains=r'other note') | - Q(organizations__name__icontains=r'org name')) - self.assertTrue(org_contact in qs) - # search again, with the same query parameters, in reverse order - qs = Contact.objects.filter( - Q(organizations__name__icontains=r'org name') | - Q(notes__note__icontains=r'other note')) - self.assertTrue(org_contact in qs) - - - diff --git a/parts/django/tests/regressiontests/get_or_create_regress/__init__.py b/parts/django/tests/regressiontests/get_or_create_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/get_or_create_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/get_or_create_regress/models.py b/parts/django/tests/regressiontests/get_or_create_regress/models.py deleted file mode 100644 index 292d96c..0000000 --- a/parts/django/tests/regressiontests/get_or_create_regress/models.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.db import models - - -class Publisher(models.Model): - name = models.CharField(max_length=100) - -class Author(models.Model): - name = models.CharField(max_length=100) - -class Book(models.Model): - name = models.CharField(max_length=100) - authors = models.ManyToManyField(Author, related_name='books') - publisher = models.ForeignKey(Publisher, related_name='books') diff --git a/parts/django/tests/regressiontests/get_or_create_regress/tests.py b/parts/django/tests/regressiontests/get_or_create_regress/tests.py deleted file mode 100644 index 87057da..0000000 --- a/parts/django/tests/regressiontests/get_or_create_regress/tests.py +++ /dev/null @@ -1,53 +0,0 @@ -from django.test import TestCase - -from models import Author, Publisher - - -class GetOrCreateTests(TestCase): - def test_related(self): - p = Publisher.objects.create(name="Acme Publishing") - # Create a book through the publisher. - book, created = p.books.get_or_create(name="The Book of Ed & Fred") - self.assertTrue(created) - # The publisher should have one book. - self.assertEqual(p.books.count(), 1) - - # Try get_or_create again, this time nothing should be created. - book, created = p.books.get_or_create(name="The Book of Ed & Fred") - self.assertFalse(created) - # And the publisher should still have one book. - self.assertEqual(p.books.count(), 1) - - # Add an author to the book. - ed, created = book.authors.get_or_create(name="Ed") - self.assertTrue(created) - # Book should have one author. - self.assertEqual(book.authors.count(), 1) - - # Try get_or_create again, this time nothing should be created. - ed, created = book.authors.get_or_create(name="Ed") - self.assertFalse(created) - # And the book should still have one author. - self.assertEqual(book.authors.count(), 1) - - # Add a second author to the book. - fred, created = book.authors.get_or_create(name="Fred") - self.assertTrue(created) - - # The book should have two authors now. - self.assertEqual(book.authors.count(), 2) - - # Create an Author not tied to any books. - Author.objects.create(name="Ted") - - # There should be three Authors in total. The book object should have two. - self.assertEqual(Author.objects.count(), 3) - self.assertEqual(book.authors.count(), 2) - - # Try creating a book through an author. - _, created = ed.books.get_or_create(name="Ed's Recipes", publisher=p) - self.assertTrue(created) - - # Now Ed has two Books, Fred just one. - self.assertEqual(ed.books.count(), 2) - self.assertEqual(fred.books.count(), 1) diff --git a/parts/django/tests/regressiontests/httpwrappers/__init__.py b/parts/django/tests/regressiontests/httpwrappers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/httpwrappers/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/httpwrappers/models.py b/parts/django/tests/regressiontests/httpwrappers/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/httpwrappers/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/httpwrappers/tests.py b/parts/django/tests/regressiontests/httpwrappers/tests.py deleted file mode 100644 index 4e946a2..0000000 --- a/parts/django/tests/regressiontests/httpwrappers/tests.py +++ /dev/null @@ -1,266 +0,0 @@ -import copy -import pickle -import unittest - -from django.http import QueryDict, HttpResponse, CompatCookie, BadHeaderError - - -class QueryDictTests(unittest.TestCase): - def test_missing_key(self): - q = QueryDict('') - self.assertRaises(KeyError, q.__getitem__, 'foo') - - def test_immutability(self): - q = QueryDict('') - self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') - self.assertRaises(AttributeError, q.setlist, 'foo', ['bar']) - self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) - self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) - self.assertRaises(AttributeError, q.pop, 'foo') - self.assertRaises(AttributeError, q.popitem) - self.assertRaises(AttributeError, q.clear) - - def test_immutable_get_with_default(self): - q = QueryDict('') - self.assertEqual(q.get('foo', 'default'), 'default') - - def test_immutable_basic_operations(self): - q = QueryDict('') - self.assertEqual(q.getlist('foo'), []) - self.assertEqual(q.has_key('foo'), False) - self.assertEqual('foo' in q, False) - self.assertEqual(q.items(), []) - self.assertEqual(q.lists(), []) - self.assertEqual(q.items(), []) - self.assertEqual(q.keys(), []) - self.assertEqual(q.values(), []) - self.assertEqual(len(q), 0) - self.assertEqual(q.urlencode(), '') - - def test_single_key_value(self): - """Test QueryDict with one key/value pair""" - - q = QueryDict('foo=bar') - self.assertEqual(q['foo'], 'bar') - self.assertRaises(KeyError, q.__getitem__, 'bar') - self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') - - self.assertEqual(q.get('foo', 'default'), 'bar') - self.assertEqual(q.get('bar', 'default'), 'default') - self.assertEqual(q.getlist('foo'), ['bar']) - self.assertEqual(q.getlist('bar'), []) - - self.assertRaises(AttributeError, q.setlist, 'foo', ['bar']) - self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) - - self.assertTrue(q.has_key('foo')) - self.assertTrue('foo' in q) - self.assertFalse(q.has_key('bar')) - self.assertFalse('bar' in q) - - self.assertEqual(q.items(), [(u'foo', u'bar')]) - self.assertEqual(q.lists(), [(u'foo', [u'bar'])]) - self.assertEqual(q.keys(), ['foo']) - self.assertEqual(q.values(), ['bar']) - self.assertEqual(len(q), 1) - - self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) - self.assertRaises(AttributeError, q.pop, 'foo') - self.assertRaises(AttributeError, q.popitem) - self.assertRaises(AttributeError, q.clear) - self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar') - - self.assertEqual(q.urlencode(), 'foo=bar') - - def test_mutable_copy(self): - """A copy of a QueryDict is mutable.""" - q = QueryDict('').copy() - self.assertRaises(KeyError, q.__getitem__, "foo") - q['name'] = 'john' - self.assertEqual(q['name'], 'john') - - def test_mutable_delete(self): - q = QueryDict('').copy() - q['name'] = 'john' - del q['name'] - self.assertFalse('name' in q) - - def test_basic_mutable_operations(self): - q = QueryDict('').copy() - q['name'] = 'john' - self.assertEqual(q.get('foo', 'default'), 'default') - self.assertEqual(q.get('name', 'default'), 'john') - self.assertEqual(q.getlist('name'), ['john']) - self.assertEqual(q.getlist('foo'), []) - - q.setlist('foo', ['bar', 'baz']) - self.assertEqual(q.get('foo', 'default'), 'baz') - self.assertEqual(q.getlist('foo'), ['bar', 'baz']) - - q.appendlist('foo', 'another') - self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another']) - self.assertEqual(q['foo'], 'another') - self.assertTrue(q.has_key('foo')) - self.assertTrue('foo' in q) - - self.assertEqual(q.items(), [(u'foo', u'another'), (u'name', u'john')]) - self.assertEqual(q.lists(), [(u'foo', [u'bar', u'baz', u'another']), (u'name', [u'john'])]) - self.assertEqual(q.keys(), [u'foo', u'name']) - self.assertEqual(q.values(), [u'another', u'john']) - self.assertEqual(len(q), 2) - - q.update({'foo': 'hello'}) - self.assertEqual(q['foo'], 'hello') - self.assertEqual(q.get('foo', 'not available'), 'hello') - self.assertEqual(q.getlist('foo'), [u'bar', u'baz', u'another', u'hello']) - self.assertEqual(q.pop('foo'), [u'bar', u'baz', u'another', u'hello']) - self.assertEqual(q.pop('foo', 'not there'), 'not there') - self.assertEqual(q.get('foo', 'not there'), 'not there') - self.assertEqual(q.setdefault('foo', 'bar'), 'bar') - self.assertEqual(q['foo'], 'bar') - self.assertEqual(q.getlist('foo'), ['bar']) - self.assertEqual(q.urlencode(), 'foo=bar&name=john') - - q.clear() - self.assertEqual(len(q), 0) - - def test_multiple_keys(self): - """Test QueryDict with two key/value pairs with same keys.""" - - q = QueryDict('vote=yes&vote=no') - - self.assertEqual(q['vote'], u'no') - self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') - - self.assertEqual(q.get('vote', 'default'), u'no') - self.assertEqual(q.get('foo', 'default'), 'default') - self.assertEqual(q.getlist('vote'), [u'yes', u'no']) - self.assertEqual(q.getlist('foo'), []) - - self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz']) - self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz']) - self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) - - self.assertEqual(q.has_key('vote'), True) - self.assertEqual('vote' in q, True) - self.assertEqual(q.has_key('foo'), False) - self.assertEqual('foo' in q, False) - self.assertEqual(q.items(), [(u'vote', u'no')]) - self.assertEqual(q.lists(), [(u'vote', [u'yes', u'no'])]) - self.assertEqual(q.keys(), [u'vote']) - self.assertEqual(q.values(), [u'no']) - self.assertEqual(len(q), 1) - - self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) - self.assertRaises(AttributeError, q.pop, 'foo') - self.assertRaises(AttributeError, q.popitem) - self.assertRaises(AttributeError, q.clear) - self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar') - self.assertRaises(AttributeError, q.__delitem__, 'vote') - - def test_invalid_input_encoding(self): - """ - QueryDicts must be able to handle invalid input encoding (in this - case, bad UTF-8 encoding). - """ - q = QueryDict('foo=bar&foo=\xff') - self.assertEqual(q['foo'], u'\ufffd') - self.assertEqual(q.getlist('foo'), [u'bar', u'\ufffd']) - - def test_pickle(self): - q = QueryDict('') - q1 = pickle.loads(pickle.dumps(q, 2)) - self.assertEqual(q == q1, True) - q = QueryDict('a=b&c=d') - q1 = pickle.loads(pickle.dumps(q, 2)) - self.assertEqual(q == q1, True) - q = QueryDict('a=b&c=d&a=1') - q1 = pickle.loads(pickle.dumps(q, 2)) - self.assertEqual(q == q1 , True) - - def test_update_from_querydict(self): - """Regression test for #8278: QueryDict.update(QueryDict)""" - x = QueryDict("a=1&a=2", mutable=True) - y = QueryDict("a=3&a=4") - x.update(y) - self.assertEqual(x.getlist('a'), [u'1', u'2', u'3', u'4']) - - def test_non_default_encoding(self): - """#13572 - QueryDict with a non-default encoding""" - q = QueryDict('sbb=one', encoding='rot_13') - self.assertEqual(q.encoding , 'rot_13' ) - self.assertEqual(q.items() , [(u'foo', u'bar')] ) - self.assertEqual(q.urlencode() , 'sbb=one' ) - q = q.copy() - self.assertEqual(q.encoding , 'rot_13' ) - self.assertEqual(q.items() , [(u'foo', u'bar')] ) - self.assertEqual(q.urlencode() , 'sbb=one' ) - self.assertEqual(copy.copy(q).encoding , 'rot_13' ) - self.assertEqual(copy.deepcopy(q).encoding , 'rot_13') - -class HttpResponseTests(unittest.TestCase): - def test_unicode_headers(self): - r = HttpResponse() - - # If we insert a unicode value it will be converted to an ascii - r['value'] = u'test value' - self.assertTrue(isinstance(r['value'], str)) - # An error is raised ~hen a unicode object with non-ascii is assigned. - self.assertRaises(UnicodeEncodeError, r.__setitem__, 'value', u't\xebst value') - - # An error is raised when a unicode object with non-ASCII format is - # passed as initial mimetype or content_type. - self.assertRaises(UnicodeEncodeError, HttpResponse, - mimetype=u't\xebst value') - - # HttpResponse headers must be convertible to ASCII. - self.assertRaises(UnicodeEncodeError, HttpResponse, - content_type=u't\xebst value') - - # The response also converts unicode keys to strings.) - r[u'test'] = 'testing key' - l = list(r.items()) - l.sort() - self.assertEqual(l[1], ('test', 'testing key')) - - # It will also raise errors for keys with non-ascii data. - self.assertRaises(UnicodeEncodeError, r.__setitem__, u't\xebst key', 'value') - - def test_newlines_in_headers(self): - # Bug #10188: Do not allow newlines in headers (CR or LF) - r = HttpResponse() - self.assertRaises(BadHeaderError, r.__setitem__, 'test\rstr', 'test') - self.assertRaises(BadHeaderError, r.__setitem__, 'test\nstr', 'test') - -class CookieTests(unittest.TestCase): - def test_encode(self): - """ - Test that we don't output tricky characters in encoded value - """ - # Python 2.4 compatibility note: Python 2.4's cookie implementation - # always returns Set-Cookie headers terminating in semi-colons. - # That's not the bug this test is looking for, so ignore it. - c = CompatCookie() - c['test'] = "An,awkward;value" - self.assert_(";" not in c.output().rstrip(';')) # IE compat - self.assert_("," not in c.output().rstrip(';')) # Safari compat - - def test_decode(self): - """ - Test that we can still preserve semi-colons and commas - """ - c = CompatCookie() - c['test'] = "An,awkward;value" - c2 = CompatCookie() - c2.load(c.output()) - self.assertEqual(c['test'].value, c2['test'].value) - - def test_decode_2(self): - """ - Test that we haven't broken normal encoding - """ - c = CompatCookie() - c['test'] = "\xf0" - c2 = CompatCookie() - c2.load(c.output()) - self.assertEqual(c['test'].value, c2['test'].value) diff --git a/parts/django/tests/regressiontests/humanize/__init__.py b/parts/django/tests/regressiontests/humanize/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/humanize/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/humanize/models.py b/parts/django/tests/regressiontests/humanize/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/humanize/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/humanize/tests.py b/parts/django/tests/regressiontests/humanize/tests.py deleted file mode 100644 index 3536c6b..0000000 --- a/parts/django/tests/regressiontests/humanize/tests.py +++ /dev/null @@ -1,76 +0,0 @@ -import unittest -from datetime import timedelta, date -from django.template import Template, Context, add_to_builtins -from django.utils.dateformat import DateFormat -from django.utils.translation import ugettext as _ -from django.utils.html import escape - -add_to_builtins('django.contrib.humanize.templatetags.humanize') - -class HumanizeTests(unittest.TestCase): - - def humanize_tester(self, test_list, result_list, method): - # Using max below ensures we go through both lists - # However, if the lists are not equal length, this raises an exception - for index in xrange(max(len(test_list), len(result_list))): - test_content = test_list[index] - t = Template('{{ test_content|%s }}' % method) - rendered = t.render(Context(locals())).strip() - self.assertEqual(rendered, escape(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', - 'something else', None) - result_list = ('1st', '2nd', '3rd', '4th', '11th', - '12th', '13th', '101st', '102nd', '103rd', - '111th', 'something else', None) - - self.humanize_tester(test_list, result_list, 'ordinal') - - def test_intcomma(self): - test_list = (100, 1000, 10123, 10311, 1000000, 1234567.25, - '100', '1000', '10123', '10311', '1000000', '1234567.1234567', - None) - result_list = ('100', '1,000', '10,123', '10,311', '1,000,000', '1,234,567.25', - '100', '1,000', '10,123', '10,311', '1,000,000', '1,234,567.1234567', - None) - - self.humanize_tester(test_list, result_list, 'intcomma') - - def test_intword(self): - test_list = ('100', '1000000', '1200000', '1290000', - '1000000000','2000000000','6000000000000', - None) - result_list = ('100', '1.0 million', '1.2 million', '1.3 million', - '1.0 billion', '2.0 billion', '6.0 trillion', - None) - - self.humanize_tester(test_list, result_list, 'intword') - - def test_apnumber(self): - test_list = [str(x) for x in range(1, 11)] - test_list.append(None) - result_list = (u'one', u'two', u'three', u'four', u'five', u'six', - u'seven', u'eight', u'nine', u'10', None) - - self.humanize_tester(test_list, result_list, 'apnumber') - - def test_naturalday(self): - from django.template import defaultfilters - today = date.today() - yesterday = today - timedelta(days=1) - tomorrow = today + timedelta(days=1) - someday = today - timedelta(days=10) - notdate = u"I'm not a date value" - - test_list = (today, yesterday, tomorrow, someday, notdate, None) - someday_result = defaultfilters.date(someday) - result_list = (_(u'today'), _(u'yesterday'), _(u'tomorrow'), - someday_result, u"I'm not a date value", None) - self.humanize_tester(test_list, result_list, 'naturalday') - -if __name__ == '__main__': - unittest.main() - diff --git a/parts/django/tests/regressiontests/i18n/__init__.py b/parts/django/tests/regressiontests/i18n/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/forms.py b/parts/django/tests/regressiontests/i18n/forms.py deleted file mode 100644 index 156441c..0000000 --- a/parts/django/tests/regressiontests/i18n/forms.py +++ /dev/null @@ -1,22 +0,0 @@ -from django import template, forms -from django.forms.extras import SelectDateWidget -from models import Company - -class I18nForm(forms.Form): - decimal_field = forms.DecimalField(localize=True) - float_field = forms.FloatField(localize=True) - date_field = forms.DateField(localize=True) - datetime_field = forms.DateTimeField(localize=True) - time_field = forms.TimeField(localize=True) - integer_field = forms.IntegerField(localize=True) - -class SelectDateForm(forms.Form): - date_field = forms.DateField(widget=SelectDateWidget) - -class CompanyForm(forms.ModelForm): - cents_payed = forms.DecimalField(max_digits=4, decimal_places=2, localize=True) - products_delivered = forms.IntegerField(localize=True) - date_added = forms.DateTimeField(localize=True) - - class Meta: - model = Company diff --git a/parts/django/tests/regressiontests/i18n/models.py b/parts/django/tests/regressiontests/i18n/models.py deleted file mode 100644 index 75cd996..0000000 --- a/parts/django/tests/regressiontests/i18n/models.py +++ /dev/null @@ -1,12 +0,0 @@ -from datetime import datetime -from django.db import models -from django.utils.translation import ugettext_lazy as _ - -class TestModel(models.Model): - text = models.CharField(max_length=10, default=_('Anything')) - -class Company(models.Model): - name = models.CharField(max_length=50) - date_added = models.DateTimeField(default=datetime(1799,1,31,23,59,59,0)) - cents_payed = models.DecimalField(max_digits=4, decimal_places=2) - products_delivered = models.IntegerField() diff --git a/parts/django/tests/regressiontests/i18n/other/__init__.py b/parts/django/tests/regressiontests/i18n/other/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/other/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/other/locale/__init__.py b/parts/django/tests/regressiontests/i18n/other/locale/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/other/locale/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.mo b/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 2bc9343..0000000 --- a/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po b/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 2fdcee5..0000000 --- a/parts/django/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,22 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-14 17:33+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: models.py:3 -msgid "Date/time" -msgstr "Datum/Zeit (LOCALE_PATHS)" diff --git a/parts/django/tests/regressiontests/i18n/other/locale/de/__init__.py b/parts/django/tests/regressiontests/i18n/other/locale/de/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/other/locale/de/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/other/locale/de/formats.py b/parts/django/tests/regressiontests/i18n/other/locale/de/formats.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/other/locale/de/formats.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/resolution/__init__.py b/parts/django/tests/regressiontests/i18n/resolution/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/i18n/resolution/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.mo b/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 1c37ac5..0000000 --- a/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.po b/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 11d2d5d..0000000 --- a/parts/django/tests/regressiontests/i18n/resolution/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,22 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-14 17:33+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: models.py:3 -msgid "Date/time" -msgstr "Datum/Zeit (APP)" diff --git a/parts/django/tests/regressiontests/i18n/resolution/models.py b/parts/django/tests/regressiontests/i18n/resolution/models.py deleted file mode 100644 index 4287ca8..0000000 --- a/parts/django/tests/regressiontests/i18n/resolution/models.py +++ /dev/null @@ -1 +0,0 @@ -#
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/i18n/tests.py b/parts/django/tests/regressiontests/i18n/tests.py deleted file mode 100644 index 99f9fe1..0000000 --- a/parts/django/tests/regressiontests/i18n/tests.py +++ /dev/null @@ -1,667 +0,0 @@ -# -*- encoding: utf-8 -*- -import datetime -import decimal -import os -import sys -import pickle - -from django.conf import settings -from django.template import Template, Context -from django.test import TestCase -from django.utils.formats import get_format, date_format, time_format, localize, localize_input, iter_format_modules -from django.utils.numberformat import format as nformat -from django.utils.safestring import mark_safe, SafeString, SafeUnicode -from django.utils.translation import ugettext, ugettext_lazy, activate, deactivate, gettext_lazy, to_locale -from django.utils.importlib import import_module - - -from forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm -from models import Company, TestModel - - -class TranslationTests(TestCase): - - def test_lazy_objects(self): - """ - Format string interpolation should work with *_lazy objects. - """ - s = ugettext_lazy('Add %(name)s') - d = {'name': 'Ringo'} - self.assertEqual(u'Add Ringo', s % d) - activate('de') - try: - self.assertEqual(u'Ringo hinzuf\xfcgen', s % d) - activate('pl') - self.assertEqual(u'Dodaj Ringo', s % d) - finally: - deactivate() - - # It should be possible to compare *_lazy objects. - s1 = ugettext_lazy('Add %(name)s') - self.assertEqual(True, s == s1) - s2 = gettext_lazy('Add %(name)s') - s3 = gettext_lazy('Add %(name)s') - self.assertEqual(True, s2 == s3) - self.assertEqual(True, s == s2) - s4 = ugettext_lazy('Some other string') - self.assertEqual(False, s == s4) - - def test_lazy_pickle(self): - s1 = ugettext_lazy("test") - self.assertEqual(unicode(s1), "test") - s2 = pickle.loads(pickle.dumps(s1)) - self.assertEqual(unicode(s2), "test") - - def test_string_concat(self): - """ - unicode(string_concat(...)) should not raise a TypeError - #4796 - """ - import django.utils.translation - self.assertEqual(u'django', unicode(django.utils.translation.string_concat("dja", "ngo"))) - - def test_safe_status(self): - """ - Translating a string requiring no auto-escaping shouldn't change the "safe" status. - """ - s = mark_safe('Password') - self.assertEqual(SafeString, type(s)) - activate('de') - try: - self.assertEqual(SafeUnicode, type(ugettext(s))) - finally: - deactivate() - self.assertEqual('aPassword', SafeString('a') + s) - self.assertEqual('Passworda', s + SafeString('a')) - self.assertEqual('Passworda', s + mark_safe('a')) - self.assertEqual('aPassword', mark_safe('a') + s) - self.assertEqual('as', mark_safe('a') + mark_safe('s')) - - def test_maclines(self): - """ - Translations on files with mac or dos end of lines will be converted - to unix eof in .po catalogs, and they have to match when retrieved - """ - from django.utils.translation.trans_real import translation - ca_translation = translation('ca') - ca_translation._catalog[u'Mac\nEOF\n'] = u'Catalan Mac\nEOF\n' - ca_translation._catalog[u'Win\nEOF\n'] = u'Catalan Win\nEOF\n' - activate('ca') - try: - self.assertEqual(u'Catalan Mac\nEOF\n', ugettext(u'Mac\rEOF\r')) - self.assertEqual(u'Catalan Win\nEOF\n', ugettext(u'Win\r\nEOF\r\n')) - finally: - deactivate() - - def test_to_locale(self): - """ - Tests the to_locale function and the special case of Serbian Latin - (refs #12230 and r11299) - """ - self.assertEqual(to_locale('en-us'), 'en_US') - self.assertEqual(to_locale('sr-lat'), 'sr_Lat') - - def test_to_language(self): - """ - Test the to_language function - """ - from django.utils.translation.trans_real import to_language - self.assertEqual(to_language('en_US'), 'en-us') - self.assertEqual(to_language('sr_Lat'), 'sr-lat') - - -class FormattingTests(TestCase): - - def setUp(self): - self.use_i18n = settings.USE_I18N - self.use_l10n = settings.USE_L10N - self.use_thousand_separator = settings.USE_THOUSAND_SEPARATOR - self.thousand_separator = settings.THOUSAND_SEPARATOR - self.number_grouping = settings.NUMBER_GROUPING - self.n = decimal.Decimal('66666.666') - self.f = 99999.999 - self.d = datetime.date(2009, 12, 31) - self.dt = datetime.datetime(2009, 12, 31, 20, 50) - self.t = datetime.time(10, 15, 48) - self.l = 10000L - self.ctxt = Context({ - 'n': self.n, - 't': self.t, - 'd': self.d, - 'dt': self.dt, - 'f': self.f, - 'l': self.l, - }) - - def tearDown(self): - # Restore defaults - settings.USE_I18N = self.use_i18n - settings.USE_L10N = self.use_l10n - settings.USE_THOUSAND_SEPARATOR = self.use_thousand_separator - settings.THOUSAND_SEPARATOR = self.thousand_separator - settings.NUMBER_GROUPING = self.number_grouping - - def test_locale_independent(self): - """ - Localization of numbers - """ - settings.USE_L10N = True - settings.USE_THOUSAND_SEPARATOR = False - self.assertEqual(u'66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) - self.assertEqual(u'66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) - - settings.USE_THOUSAND_SEPARATOR = True - self.assertEqual(u'66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) - self.assertEqual(u'6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) - self.assertEqual(u'-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) - self.assertEqual(u'-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1)) - self.assertEqual(u'10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1)) - - # date filter - self.assertEqual(u'31.12.2009 в 20:50', Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt)) - self.assertEqual(u'⌚ 10:15', Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt)) - - def test_l10n_disabled(self): - """ - Catalan locale with format i18n disabled translations will be used, - but not formats - """ - settings.USE_L10N = False - activate('ca') - try: - self.assertEqual(u'N j, Y', get_format('DATE_FORMAT')) - self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) - self.assertEqual(u'.', get_format('DECIMAL_SEPARATOR')) - self.assertEqual(u'10:15 a.m.', time_format(self.t)) - self.assertEqual(u'des. 31, 2009', date_format(self.d)) - self.assertEqual(u'desembre 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) - self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) - self.assertEqual(u'No localizable', localize('No localizable')) - self.assertEqual(u'66666.666', localize(self.n)) - self.assertEqual(u'99999.999', localize(self.f)) - self.assertEqual(u'10000', localize(self.l)) - self.assertEqual(u'des. 31, 2009', localize(self.d)) - self.assertEqual(u'des. 31, 2009, 8:50 p.m.', localize(self.dt)) - self.assertEqual(u'66666.666', Template('{{ n }}').render(self.ctxt)) - self.assertEqual(u'99999.999', Template('{{ f }}').render(self.ctxt)) - self.assertEqual(u'des. 31, 2009', Template('{{ d }}').render(self.ctxt)) - self.assertEqual(u'des. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt)) - self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) - self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) - self.assertEqual(u'10:15 a.m.', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)) - self.assertEqual(u'12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) - self.assertEqual(u'12/31/2009 8:50 p.m.', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) - - form = I18nForm({ - 'decimal_field': u'66666,666', - 'float_field': u'99999,999', - 'date_field': u'31/12/2009', - 'datetime_field': u'31/12/2009 20:50', - 'time_field': u'20:50', - 'integer_field': u'1.234', - }) - self.assertEqual(False, form.is_valid()) - self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['float_field']) - self.assertEqual([u'Introdu\xefu un n\xfamero.'], form.errors['decimal_field']) - self.assertEqual([u'Introdu\xefu una data v\xe0lida.'], form.errors['date_field']) - self.assertEqual([u'Introdu\xefu una data/hora v\xe0lides.'], form.errors['datetime_field']) - self.assertEqual([u'Introdu\xefu un n\xfamero sencer.'], form.errors['integer_field']) - - form2 = SelectDateForm({ - 'date_field_month': u'12', - 'date_field_day': u'31', - 'date_field_year': u'2009' - }) - self.assertEqual(True, form2.is_valid()) - self.assertEqual(datetime.date(2009, 12, 31), form2.cleaned_data['date_field']) - self.assertEqual( - u'<select name="mydate_month" id="id_mydate_month">\n<option value="1">gener</option>\n<option value="2">febrer</option>\n<option value="3">mar\xe7</option>\n<option value="4">abril</option>\n<option value="5">maig</option>\n<option value="6">juny</option>\n<option value="7">juliol</option>\n<option value="8">agost</option>\n<option value="9">setembre</option>\n<option value="10">octubre</option>\n<option value="11">novembre</option>\n<option value="12" selected="selected">desembre</option>\n</select>\n<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', - SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) - ) - - # We shouldn't change the behavior of the floatformat filter re: - # thousand separator and grouping when USE_L10N is False even - # if the USE_THOUSAND_SEPARATOR, NUMBER_GROUPING and - # THOUSAND_SEPARATOR settings are specified - settings.USE_THOUSAND_SEPARATOR = True - settings.NUMBER_GROUPING = 1 - settings.THOUSAND_SEPARATOR = '!' - self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) - self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) - finally: - deactivate() - - def test_l10n_enabled(self): - """ - Catalan locale - """ - settings.USE_L10N = True - activate('ca') - try: - self.assertEqual('j \de F \de Y', get_format('DATE_FORMAT')) - self.assertEqual(1, get_format('FIRST_DAY_OF_WEEK')) - self.assertEqual(',', get_format('DECIMAL_SEPARATOR')) - self.assertEqual(u'10:15:48', time_format(self.t)) - self.assertEqual(u'31 de desembre de 2009', date_format(self.d)) - self.assertEqual(u'desembre del 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) - self.assertEqual(u'31/12/2009 20:50', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) - self.assertEqual('No localizable', localize('No localizable')) - - settings.USE_THOUSAND_SEPARATOR = True - self.assertEqual(u'66.666,666', localize(self.n)) - self.assertEqual(u'99.999,999', localize(self.f)) - self.assertEqual(u'10.000', localize(self.l)) - self.assertEqual(u'True', localize(True)) - - settings.USE_THOUSAND_SEPARATOR = False - self.assertEqual(u'66666,666', localize(self.n)) - self.assertEqual(u'99999,999', localize(self.f)) - self.assertEqual(u'10000', localize(self.l)) - self.assertEqual(u'31 de desembre de 2009', localize(self.d)) - self.assertEqual(u'31 de desembre de 2009 a les 20:50', localize(self.dt)) - - settings.USE_THOUSAND_SEPARATOR = True - self.assertEqual(u'66.666,666', Template('{{ n }}').render(self.ctxt)) - self.assertEqual(u'99.999,999', Template('{{ f }}').render(self.ctxt)) - self.assertEqual(u'10.000', Template('{{ l }}').render(self.ctxt)) - - form3 = I18nForm({ - 'decimal_field': u'66.666,666', - 'float_field': u'99.999,999', - 'date_field': u'31/12/2009', - 'datetime_field': u'31/12/2009 20:50', - 'time_field': u'20:50', - 'integer_field': u'1.234', - }) - self.assertEqual(True, form3.is_valid()) - self.assertEqual(decimal.Decimal('66666.666'), form3.cleaned_data['decimal_field']) - self.assertEqual(99999.999, form3.cleaned_data['float_field']) - self.assertEqual(datetime.date(2009, 12, 31), form3.cleaned_data['date_field']) - self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form3.cleaned_data['datetime_field']) - self.assertEqual(datetime.time(20, 50), form3.cleaned_data['time_field']) - self.assertEqual(1234, form3.cleaned_data['integer_field']) - - settings.USE_THOUSAND_SEPARATOR = False - self.assertEqual(u'66666,666', Template('{{ n }}').render(self.ctxt)) - self.assertEqual(u'99999,999', Template('{{ f }}').render(self.ctxt)) - self.assertEqual(u'31 de desembre de 2009', Template('{{ d }}').render(self.ctxt)) - self.assertEqual(u'31 de desembre de 2009 a les 20:50', Template('{{ dt }}').render(self.ctxt)) - self.assertEqual(u'66666,67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) - self.assertEqual(u'100000,0', Template('{{ f|floatformat }}').render(self.ctxt)) - self.assertEqual(u'10:15:48', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt)) - self.assertEqual(u'31/12/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) - self.assertEqual(u'31/12/2009 20:50', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) - - form4 = I18nForm({ - 'decimal_field': u'66666,666', - 'float_field': u'99999,999', - 'date_field': u'31/12/2009', - 'datetime_field': u'31/12/2009 20:50', - 'time_field': u'20:50', - 'integer_field': u'1234', - }) - self.assertEqual(True, form4.is_valid()) - self.assertEqual(decimal.Decimal('66666.666'), form4.cleaned_data['decimal_field']) - self.assertEqual(99999.999, form4.cleaned_data['float_field']) - self.assertEqual(datetime.date(2009, 12, 31), form4.cleaned_data['date_field']) - self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form4.cleaned_data['datetime_field']) - self.assertEqual(datetime.time(20, 50), form4.cleaned_data['time_field']) - self.assertEqual(1234, form4.cleaned_data['integer_field']) - - form5 = SelectDateForm({ - 'date_field_month': u'12', - 'date_field_day': u'31', - 'date_field_year': u'2009' - }) - self.assertEqual(True, form5.is_valid()) - self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field']) - self.assertEqual( - u'<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_month" id="id_mydate_month">\n<option value="1">gener</option>\n<option value="2">febrer</option>\n<option value="3">mar\xe7</option>\n<option value="4">abril</option>\n<option value="5">maig</option>\n<option value="6">juny</option>\n<option value="7">juliol</option>\n<option value="8">agost</option>\n<option value="9">setembre</option>\n<option value="10">octubre</option>\n<option value="11">novembre</option>\n<option value="12" selected="selected">desembre</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', - SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) - ) - finally: - deactivate() - - # English locale - - settings.USE_L10N = True - activate('en') - try: - self.assertEqual('N j, Y', get_format('DATE_FORMAT')) - self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK')) - self.assertEqual('.', get_format('DECIMAL_SEPARATOR')) - self.assertEqual(u'Dec. 31, 2009', date_format(self.d)) - self.assertEqual(u'December 2009', date_format(self.d, 'YEAR_MONTH_FORMAT')) - self.assertEqual(u'12/31/2009 8:50 p.m.', date_format(self.dt, 'SHORT_DATETIME_FORMAT')) - self.assertEqual(u'No localizable', localize('No localizable')) - - settings.USE_THOUSAND_SEPARATOR = True - self.assertEqual(u'66,666.666', localize(self.n)) - self.assertEqual(u'99,999.999', localize(self.f)) - self.assertEqual(u'10,000', localize(self.l)) - - settings.USE_THOUSAND_SEPARATOR = False - self.assertEqual(u'66666.666', localize(self.n)) - self.assertEqual(u'99999.999', localize(self.f)) - self.assertEqual(u'10000', localize(self.l)) - self.assertEqual(u'Dec. 31, 2009', localize(self.d)) - self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', localize(self.dt)) - - settings.USE_THOUSAND_SEPARATOR = True - self.assertEqual(u'66,666.666', Template('{{ n }}').render(self.ctxt)) - self.assertEqual(u'99,999.999', Template('{{ f }}').render(self.ctxt)) - self.assertEqual(u'10,000', Template('{{ l }}').render(self.ctxt)) - - settings.USE_THOUSAND_SEPARATOR = False - self.assertEqual(u'66666.666', Template('{{ n }}').render(self.ctxt)) - self.assertEqual(u'99999.999', Template('{{ f }}').render(self.ctxt)) - self.assertEqual(u'Dec. 31, 2009', Template('{{ d }}').render(self.ctxt)) - self.assertEqual(u'Dec. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt)) - self.assertEqual(u'66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt)) - self.assertEqual(u'100000.0', Template('{{ f|floatformat }}').render(self.ctxt)) - self.assertEqual(u'12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt)) - self.assertEqual(u'12/31/2009 8:50 p.m.', Template('{{ dt|date:"SHORT_DATETIME_FORMAT" }}').render(self.ctxt)) - - form5 = I18nForm({ - 'decimal_field': u'66666.666', - 'float_field': u'99999.999', - 'date_field': u'12/31/2009', - 'datetime_field': u'12/31/2009 20:50', - 'time_field': u'20:50', - 'integer_field': u'1234', - }) - self.assertEqual(True, form5.is_valid()) - self.assertEqual(decimal.Decimal('66666.666'), form5.cleaned_data['decimal_field']) - self.assertEqual(99999.999, form5.cleaned_data['float_field']) - self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field']) - self.assertEqual(datetime.datetime(2009, 12, 31, 20, 50), form5.cleaned_data['datetime_field']) - self.assertEqual(datetime.time(20, 50), form5.cleaned_data['time_field']) - self.assertEqual(1234, form5.cleaned_data['integer_field']) - - form6 = SelectDateForm({ - 'date_field_month': u'12', - 'date_field_day': u'31', - 'date_field_year': u'2009' - }) - self.assertEqual(True, form6.is_valid()) - self.assertEqual(datetime.date(2009, 12, 31), form6.cleaned_data['date_field']) - self.assertEqual( - u'<select name="mydate_month" id="id_mydate_month">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12" selected="selected">December</option>\n</select>\n<select name="mydate_day" id="id_mydate_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31" selected="selected">31</option>\n</select>\n<select name="mydate_year" id="id_mydate_year">\n<option value="2009" selected="selected">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n<option value="2017">2017</option>\n<option value="2018">2018</option>\n</select>', - SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31)) - ) - finally: - deactivate() - - def test_sub_locales(self): - """ - Check if sublocales fall back to the main locale - """ - settings.USE_L10N = True - activate('de-at') - settings.USE_THOUSAND_SEPARATOR = True - try: - self.assertEqual(u'66.666,666', Template('{{ n }}').render(self.ctxt)) - finally: - deactivate() - - activate('es-us') - try: - self.assertEqual(u'31 de diciembre de 2009', date_format(self.d)) - finally: - deactivate() - - def test_localized_input(self): - """ - Tests if form input is correctly localized - """ - settings.USE_L10N = True - activate('de-at') - try: - form6 = CompanyForm({ - 'name': u'acme', - 'date_added': datetime.datetime(2009, 12, 31, 6, 0, 0), - 'cents_payed': decimal.Decimal('59.47'), - 'products_delivered': 12000, - }) - self.assertEqual(True, form6.is_valid()) - self.assertEqual( - form6.as_ul(), - u'<li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" value="acme" maxlength="50" /></li>\n<li><label for="id_date_added">Date added:</label> <input type="text" name="date_added" value="31.12.2009 06:00:00" id="id_date_added" /></li>\n<li><label for="id_cents_payed">Cents payed:</label> <input type="text" name="cents_payed" value="59,47" id="id_cents_payed" /></li>\n<li><label for="id_products_delivered">Products delivered:</label> <input type="text" name="products_delivered" value="12000" id="id_products_delivered" /></li>' - ) - self.assertEqual(localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)), '31.12.2009 06:00:00') - self.assertEqual(datetime.datetime(2009, 12, 31, 6, 0, 0), form6.cleaned_data['date_added']) - settings.USE_THOUSAND_SEPARATOR = True - # Checking for the localized "products_delivered" field - self.assert_(u'<input type="text" name="products_delivered" value="12.000" id="id_products_delivered" />' in form6.as_ul()) - finally: - deactivate() - - def test_iter_format_modules(self): - """ - Tests the iter_format_modules function. - """ - activate('de-at') - old_format_module_path = settings.FORMAT_MODULE_PATH - try: - settings.USE_L10N = True - de_format_mod = import_module('django.conf.locale.de.formats') - self.assertEqual(list(iter_format_modules('de')), [de_format_mod]) - settings.FORMAT_MODULE_PATH = 'regressiontests.i18n.other.locale' - test_de_format_mod = import_module('regressiontests.i18n.other.locale.de.formats') - self.assertEqual(list(iter_format_modules('de')), [test_de_format_mod, de_format_mod]) - finally: - settings.FORMAT_MODULE_PATH = old_format_module_path - deactivate() - - -class MiscTests(TestCase): - - def test_parse_spec_http_header(self): - """ - Testing HTTP header parsing. First, we test that we can parse the - values according to the spec (and that we extract all the pieces in - the right order). - """ - from django.utils.translation.trans_real import parse_accept_lang_header - p = parse_accept_lang_header - # Good headers. - self.assertEqual([('de', 1.0)], p('de')) - self.assertEqual([('en-AU', 1.0)], p('en-AU')) - self.assertEqual([('*', 1.0)], p('*;q=1.00')) - self.assertEqual([('en-AU', 0.123)], p('en-AU;q=0.123')) - self.assertEqual([('en-au', 0.5)], p('en-au;q=0.5')) - self.assertEqual([('en-au', 1.0)], p('en-au;q=1.0')) - self.assertEqual([('da', 1.0), ('en', 0.5), ('en-gb', 0.25)], p('da, en-gb;q=0.25, en;q=0.5')) - self.assertEqual([('en-au-xx', 1.0)], p('en-au-xx')) - self.assertEqual([('de', 1.0), ('en-au', 0.75), ('en-us', 0.5), ('en', 0.25), ('es', 0.125), ('fa', 0.125)], p('de,en-au;q=0.75,en-us;q=0.5,en;q=0.25,es;q=0.125,fa;q=0.125')) - self.assertEqual([('*', 1.0)], p('*')) - self.assertEqual([('de', 1.0)], p('de;q=0.')) - self.assertEqual([], p('')) - - # Bad headers; should always return []. - self.assertEqual([], p('en-gb;q=1.0000')) - self.assertEqual([], p('en;q=0.1234')) - self.assertEqual([], p('en;q=.2')) - self.assertEqual([], p('abcdefghi-au')) - self.assertEqual([], p('**')) - self.assertEqual([], p('en,,gb')) - self.assertEqual([], p('en-au;q=0.1.0')) - self.assertEqual([], p('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZ,en')) - self.assertEqual([], p('da, en-gb;q=0.8, en;q=0.7,#')) - self.assertEqual([], p('de;q=2.0')) - self.assertEqual([], p('de;q=0.a')) - self.assertEqual([], p('')) - - def test_parse_literal_http_header(self): - """ - Now test that we parse a literal HTTP header correctly. - """ - from django.utils.translation.trans_real import get_language_from_request - g = get_language_from_request - from django.http import HttpRequest - r = HttpRequest - r.COOKIES = {} - r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'} - self.assertEqual('pt-br', g(r)) - - r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'} - self.assertEqual('pt', g(r)) - - r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'} - self.assertEqual('es', g(r)) - - r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'} - self.assertEqual('es-ar', g(r)) - - # Python 2.3 and 2.4 return 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. (On those platforms, passing in a truly bogus locale - # will get you the default locale back.) - if sys.version_info >= (2, 5): - # 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 instead. - r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'} - self.assertEqual(g(r), 'es') - - # 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 Django without falling back nor ignoring it. - r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'} - self.assertEqual(g(r), 'zh-cn') - - def test_parse_language_cookie(self): - """ - Now test that we parse language preferences stored in a cookie correctly. - """ - from django.utils.translation.trans_real import get_language_from_request - g = get_language_from_request - from django.http import HttpRequest - r = HttpRequest - r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt-br'} - r.META = {} - self.assertEqual('pt-br', g(r)) - - r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt'} - r.META = {} - self.assertEqual('pt', g(r)) - - r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es'} - r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'} - self.assertEqual('es', g(r)) - - # Python 2.3 and 2.4 return 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. (On those platforms, passing in a truly bogus locale - # will get you the default locale back.) - if sys.version_info >= (2, 5): - # 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 instead. - r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'es-us'} - r.META = {} - self.assertEqual(g(r), 'es') - - # 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 Django without falling back nor ignoring it. - r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'zh-cn'} - r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'} - self.assertEqual(g(r), 'zh-cn') - -class ResolutionOrderI18NTests(TestCase): - - def setUp(self): - from django.utils.translation import trans_real - # Okay, this is brutal, but we have no other choice to fully reset - # the translation framework - trans_real._active = {} - trans_real._translations = {} - activate('de') - - def tearDown(self): - deactivate() - - def assertUgettext(self, msgid, msgstr): - result = ugettext(msgid) - self.assert_(msgstr in result, ("The string '%s' isn't in the " - "translation of '%s'; the actual result is '%s'." % (msgstr, msgid, result))) - -class AppResolutionOrderI18NTests(ResolutionOrderI18NTests): - - def setUp(self): - self.old_installed_apps = settings.INSTALLED_APPS - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.i18n.resolution'] - super(AppResolutionOrderI18NTests, self).setUp() - - def tearDown(self): - settings.INSTALLED_APPS = self.old_installed_apps - super(AppResolutionOrderI18NTests, self).tearDown() - - def test_app_translation(self): - self.assertUgettext('Date/time', 'APP') - -class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests): - - def setUp(self): - self.old_locale_paths = settings.LOCALE_PATHS - settings.LOCALE_PATHS += (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),) - super(LocalePathsResolutionOrderI18NTests, self).setUp() - - def tearDown(self): - settings.LOCALE_PATHS = self.old_locale_paths - super(LocalePathsResolutionOrderI18NTests, self).tearDown() - - def test_locale_paths_translation(self): - self.assertUgettext('Date/time', 'LOCALE_PATHS') - -class ProjectResolutionOrderI18NTests(ResolutionOrderI18NTests): - - def setUp(self): - self.old_settings_module = settings.SETTINGS_MODULE - settings.SETTINGS_MODULE = 'regressiontests' - super(ProjectResolutionOrderI18NTests, self).setUp() - - def tearDown(self): - settings.SETTINGS_MODULE = self.old_settings_module - super(ProjectResolutionOrderI18NTests, self).tearDown() - - def test_project_translation(self): - self.assertUgettext('Date/time', 'PROJECT') - - def test_project_override_app_translation(self): - old_installed_apps = settings.INSTALLED_APPS - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.i18n.resolution'] - self.assertUgettext('Date/time', 'PROJECT') - settings.INSTALLED_APPS = old_installed_apps - - def test_project_override_locale_paths_translation(self): - old_locale_paths = settings.LOCALE_PATHS - settings.LOCALE_PATHS += (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),) - self.assertUgettext('Date/time', 'PROJECT') - settings.LOCALE_PATHS = old_locale_paths - -class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests): - - def test_django_fallback(self): - self.assertUgettext('Date/time', 'Datum/Zeit') - - -class TestModels(TestCase): - def test_lazy(self): - tm = TestModel() - tm.save() - - def test_safestr(self): - c = Company(cents_payed=12, products_delivered=1) - c.name = SafeUnicode(u'Iñtërnâtiônàlizætiøn1') - c.save() - c.name = SafeString(u'Iñtërnâtiônàlizætiøn1'.encode('utf-8')) - c.save() diff --git a/parts/django/tests/regressiontests/initial_sql_regress/__init__.py b/parts/django/tests/regressiontests/initial_sql_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/initial_sql_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/initial_sql_regress/models.py b/parts/django/tests/regressiontests/initial_sql_regress/models.py deleted file mode 100644 index 9f91802..0000000 --- a/parts/django/tests/regressiontests/initial_sql_regress/models.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -Regression tests for initial SQL insertion. -""" - -from django.db import models - -class Simple(models.Model): - name = models.CharField(max_length = 50) - -# NOTE: The format of the included SQL file for this test suite is important. -# It must end with a trailing newline in order to test the fix for #2161. diff --git a/parts/django/tests/regressiontests/initial_sql_regress/sql/simple.sql b/parts/django/tests/regressiontests/initial_sql_regress/sql/simple.sql deleted file mode 100644 index ca9bd40..0000000 --- a/parts/django/tests/regressiontests/initial_sql_regress/sql/simple.sql +++ /dev/null @@ -1,8 +0,0 @@ -INSERT INTO initial_sql_regress_simple (name) VALUES ('John'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('Paul'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('Ringo'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('George'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('Miles O''Brien'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('Semicolon;Man'); -INSERT INTO initial_sql_regress_simple (name) VALUES ('This line has a Windows line ending');
- diff --git a/parts/django/tests/regressiontests/initial_sql_regress/tests.py b/parts/django/tests/regressiontests/initial_sql_regress/tests.py deleted file mode 100644 index 2b3ca91..0000000 --- a/parts/django/tests/regressiontests/initial_sql_regress/tests.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.test import TestCase - -from models import Simple - - -class InitialSQLTests(TestCase): - def test_initial_sql(self): - self.assertEqual(Simple.objects.count(), 7) diff --git a/parts/django/tests/regressiontests/inline_formsets/__init__.py b/parts/django/tests/regressiontests/inline_formsets/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/inline_formsets/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/inline_formsets/models.py b/parts/django/tests/regressiontests/inline_formsets/models.py deleted file mode 100644 index d76eea7..0000000 --- a/parts/django/tests/regressiontests/inline_formsets/models.py +++ /dev/null @@ -1,28 +0,0 @@ -# coding: utf-8 -from django.db import models - - -class School(models.Model): - name = models.CharField(max_length=100) - -class Parent(models.Model): - name = models.CharField(max_length=100) - -class Child(models.Model): - mother = models.ForeignKey(Parent, related_name='mothers_children') - father = models.ForeignKey(Parent, related_name='fathers_children') - school = models.ForeignKey(School) - name = models.CharField(max_length=100) - -class Poet(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - -class Poem(models.Model): - poet = models.ForeignKey(Poet) - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/regressiontests/inline_formsets/tests.py b/parts/django/tests/regressiontests/inline_formsets/tests.py deleted file mode 100644 index dd698ab..0000000 --- a/parts/django/tests/regressiontests/inline_formsets/tests.py +++ /dev/null @@ -1,163 +0,0 @@ -from django.forms.models import inlineformset_factory -from django.test import TestCase - -from regressiontests.inline_formsets.models import Poet, Poem, School, Parent, Child - - -class DeletionTests(TestCase): - - def test_deletion(self): - PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True) - poet = Poet.objects.create(name='test') - poem = poet.poem_set.create(name='test poem') - data = { - 'poem_set-TOTAL_FORMS': u'1', - 'poem_set-INITIAL_FORMS': u'1', - 'poem_set-MAX_NUM_FORMS': u'0', - 'poem_set-0-id': str(poem.pk), - 'poem_set-0-poet': str(poet.pk), - 'poem_set-0-name': u'test', - 'poem_set-0-DELETE': u'on', - } - formset = PoemFormSet(data, instance=poet) - formset.save() - self.assertTrue(formset.is_valid()) - self.assertEqual(Poem.objects.count(), 0) - - def test_add_form_deletion_when_invalid(self): - """ - Make sure that an add form that is filled out, but marked for deletion - doesn't cause validation errors. - """ - PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True) - poet = Poet.objects.create(name='test') - data = { - 'poem_set-TOTAL_FORMS': u'1', - 'poem_set-INITIAL_FORMS': u'0', - 'poem_set-MAX_NUM_FORMS': u'0', - 'poem_set-0-id': u'', - 'poem_set-0-poem': u'1', - 'poem_set-0-name': u'x' * 1000, - } - formset = PoemFormSet(data, instance=poet) - # Make sure this form doesn't pass validation. - self.assertEqual(formset.is_valid(), False) - self.assertEqual(Poem.objects.count(), 0) - - # Then make sure that it *does* pass validation and delete the object, - # even though the data isn't actually valid. - data['poem_set-0-DELETE'] = 'on' - formset = PoemFormSet(data, instance=poet) - self.assertEqual(formset.is_valid(), True) - formset.save() - self.assertEqual(Poem.objects.count(), 0) - - def test_change_form_deletion_when_invalid(self): - """ - Make sure that a change form that is filled out, but marked for deletion - doesn't cause validation errors. - """ - PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True) - poet = Poet.objects.create(name='test') - poet.poem_set.create(name='test poem') - data = { - 'poem_set-TOTAL_FORMS': u'1', - 'poem_set-INITIAL_FORMS': u'1', - 'poem_set-MAX_NUM_FORMS': u'0', - 'poem_set-0-id': u'1', - 'poem_set-0-poem': u'1', - 'poem_set-0-name': u'x' * 1000, - } - formset = PoemFormSet(data, instance=poet) - # Make sure this form doesn't pass validation. - self.assertEqual(formset.is_valid(), False) - self.assertEqual(Poem.objects.count(), 1) - - # Then make sure that it *does* pass validation and delete the object, - # even though the data isn't actually valid. - data['poem_set-0-DELETE'] = 'on' - formset = PoemFormSet(data, instance=poet) - self.assertEqual(formset.is_valid(), True) - formset.save() - self.assertEqual(Poem.objects.count(), 0) - - def test_save_new(self): - """ - Make sure inlineformsets respect commit=False - regression for #10750 - """ - # exclude some required field from the forms - ChildFormSet = inlineformset_factory(School, Child, exclude=['father', 'mother']) - school = School.objects.create(name=u'test') - mother = Parent.objects.create(name=u'mother') - father = Parent.objects.create(name=u'father') - data = { - 'child_set-TOTAL_FORMS': u'1', - 'child_set-INITIAL_FORMS': u'0', - 'child_set-MAX_NUM_FORMS': u'0', - 'child_set-0-name': u'child', - } - formset = ChildFormSet(data, instance=school) - self.assertEqual(formset.is_valid(), True) - objects = formset.save(commit=False) - for obj in objects: - obj.mother = mother - obj.father = father - obj.save() - self.assertEqual(school.child_set.count(), 1) - - -class InlineFormsetFactoryTest(TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_inline_formset_factory(self): - """ - These should both work without a problem. - """ - inlineformset_factory(Parent, Child, fk_name='mother') - inlineformset_factory(Parent, Child, fk_name='father') - - def test_exception_on_unspecified_foreign_key(self): - """ - Child has two ForeignKeys to Parent, so if we don't specify which one - to use for the inline formset, we should get an exception. - """ - self.assertRaisesErrorWithMessage(Exception, - "<class 'regressiontests.inline_formsets.models.Child'> has more than 1 ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>", - inlineformset_factory, Parent, Child - ) - - def test_fk_name_not_foreign_key_field_from_child(self): - """ - If we specify fk_name, but it isn't a ForeignKey from the child model - to the parent model, we should get an exception. - """ - self.assertRaisesErrorWithMessage(Exception, - "fk_name 'school' is not a ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>", - inlineformset_factory, Parent, Child, fk_name='school' - ) - - def test_non_foreign_key_field(self): - """ - If the field specified in fk_name is not a ForeignKey, we should get an - exception. - """ - self.assertRaisesErrorWithMessage(Exception, - "<class 'regressiontests.inline_formsets.models.Child'> has no field named 'test'", - inlineformset_factory, Parent, Child, fk_name='test' - ) - - def test_any_iterable_allowed_as_argument_to_exclude(self): - # Regression test for #9171. - inlineformset_factory( - Parent, Child, exclude=['school'], fk_name='mother' - ) - - inlineformset_factory( - Parent, Child, exclude=('school',), fk_name='mother' - ) diff --git a/parts/django/tests/regressiontests/introspection/__init__.py b/parts/django/tests/regressiontests/introspection/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/introspection/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/introspection/models.py b/parts/django/tests/regressiontests/introspection/models.py deleted file mode 100644 index ef485e3..0000000 --- a/parts/django/tests/regressiontests/introspection/models.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.db import models - -class Reporter(models.Model): - first_name = models.CharField(max_length=30) - last_name = models.CharField(max_length=30) - email = models.EmailField() - facebook_user_id = models.BigIntegerField() - - def __unicode__(self): - return u"%s %s" % (self.first_name, self.last_name) - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateField() - reporter = models.ForeignKey(Reporter) - - def __unicode__(self): - return self.headline - - class Meta: - ordering = ('headline',)
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/introspection/tests.py b/parts/django/tests/regressiontests/introspection/tests.py deleted file mode 100644 index 2a81aa8..0000000 --- a/parts/django/tests/regressiontests/introspection/tests.py +++ /dev/null @@ -1,111 +0,0 @@ -from django.conf import settings -from django.db import connection, DEFAULT_DB_ALIAS -from django.test import TestCase -from django.utils import functional - -from models import Reporter, Article - -# -# The introspection module is optional, so methods tested here might raise -# NotImplementedError. This is perfectly acceptable behavior for the backend -# in question, but the tests need to handle this without failing. Ideally we'd -# skip these tests, but until #4788 is done we'll just ignore them. -# -# The easiest way to accomplish this is to decorate every test case with a -# wrapper that ignores the exception. -# -# The metaclass is just for fun. -# - -def ignore_not_implemented(func): - def _inner(*args, **kwargs): - try: - return func(*args, **kwargs) - except NotImplementedError: - return None - functional.update_wrapper(_inner, func) - return _inner - -class IgnoreNotimplementedError(type): - def __new__(cls, name, bases, attrs): - for k,v in attrs.items(): - if k.startswith('test'): - attrs[k] = ignore_not_implemented(v) - return type.__new__(cls, name, bases, attrs) - -class IntrospectionTests(TestCase): - __metaclass__ = IgnoreNotimplementedError - - def test_table_names(self): - tl = connection.introspection.table_names() - self.assert_(Reporter._meta.db_table in tl, - "'%s' isn't in table_list()." % Reporter._meta.db_table) - self.assert_(Article._meta.db_table in tl, - "'%s' isn't in table_list()." % Article._meta.db_table) - - def test_django_table_names(self): - cursor = connection.cursor() - cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);'); - tl = connection.introspection.django_table_names() - cursor.execute("DROP TABLE django_ixn_test_table;") - self.assert_('django_ixn_testcase_table' not in tl, - "django_table_names() returned a non-Django table") - - def test_installed_models(self): - tables = [Article._meta.db_table, Reporter._meta.db_table] - models = connection.introspection.installed_models(tables) - self.assertEqual(models, set([Article, Reporter])) - - def test_sequence_list(self): - sequences = connection.introspection.sequence_list() - expected = {'table': Reporter._meta.db_table, 'column': 'id'} - self.assert_(expected in sequences, - 'Reporter sequence not found in sequence_list()') - - def test_get_table_description_names(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) - self.assertEqual([r[0] for r in desc], - [f.column for f in Reporter._meta.fields]) - - def test_get_table_description_types(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) - self.assertEqual( - [datatype(r[1], r) for r in desc], - ['IntegerField', 'CharField', 'CharField', 'CharField', 'BigIntegerField'] - ) - - # Regression test for #9991 - 'real' types in postgres - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].startswith('django.db.backends.postgresql'): - def test_postgresql_real_type(self): - cursor = connection.cursor() - cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);") - desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table') - cursor.execute('DROP TABLE django_ixn_real_test_table;') - self.assertEqual(datatype(desc[0][1], desc[0]), 'FloatField') - - def test_get_relations(self): - cursor = connection.cursor() - relations = connection.introspection.get_relations(cursor, Article._meta.db_table) - - # Older versions of MySQL don't have the chops to report on this stuff, - # so just skip it if no relations come back. If they do, though, we - # should test that the response is correct. - if relations: - # That's {field_index: (field_index_other_table, other_table)} - self.assertEqual(relations, {3: (0, Reporter._meta.db_table)}) - - def test_get_indexes(self): - cursor = connection.cursor() - indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) - self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False}) - - -def datatype(dbtype, description): - """Helper to convert a data type into a string.""" - dt = connection.introspection.get_field_type(dbtype, description) - if type(dt) is tuple: - return dt[0] - else: - return dt diff --git a/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.mo b/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 2ee860a..0000000 --- a/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.po b/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 356e3d3..0000000 --- a/parts/django/tests/regressiontests/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,22 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-14 17:33+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: models.py:3 -msgid "Date/time" -msgstr "Datum/Zeit (PROJECT)" diff --git a/parts/django/tests/regressiontests/localflavor/__init__.py b/parts/django/tests/regressiontests/localflavor/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/localflavor/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/localflavor/models.py b/parts/django/tests/regressiontests/localflavor/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/localflavor/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/localflavor/tests.py b/parts/django/tests/regressiontests/localflavor/tests.py deleted file mode 100644 index 6968236..0000000 --- a/parts/django/tests/regressiontests/localflavor/tests.py +++ /dev/null @@ -1,5 +0,0 @@ -import unittest -from django.test import TestCase - -# just import your tests here -from us.tests import * diff --git a/parts/django/tests/regressiontests/localflavor/us/__init__.py b/parts/django/tests/regressiontests/localflavor/us/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/localflavor/us/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/localflavor/us/forms.py b/parts/django/tests/regressiontests/localflavor/us/forms.py deleted file mode 100644 index 9b77e10..0000000 --- a/parts/django/tests/regressiontests/localflavor/us/forms.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.forms import ModelForm -from models import USPlace - -class USPlaceForm(ModelForm): - """docstring for PlaceForm""" - class Meta: - model = USPlace diff --git a/parts/django/tests/regressiontests/localflavor/us/models.py b/parts/django/tests/regressiontests/localflavor/us/models.py deleted file mode 100644 index a8a4cf0..0000000 --- a/parts/django/tests/regressiontests/localflavor/us/models.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.db import models -from django.contrib.localflavor.us.models import USStateField - -# When creating models you need to remember to add a app_label as -# 'localflavor', so your model can be found - -class USPlace(models.Model): - state = USStateField(blank=True) - state_req = USStateField() - state_default = USStateField(default="CA", blank=True) - name = models.CharField(max_length=20) - class Meta: - app_label = 'localflavor' diff --git a/parts/django/tests/regressiontests/localflavor/us/tests.py b/parts/django/tests/regressiontests/localflavor/us/tests.py deleted file mode 100644 index 07fe057..0000000 --- a/parts/django/tests/regressiontests/localflavor/us/tests.py +++ /dev/null @@ -1,82 +0,0 @@ -from django.test import TestCase -from forms import USPlaceForm - -class USLocalflavorTests(TestCase): - def setUp(self): - self.form = USPlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'}) - - def test_get_display_methods(self): - """Test that the get_*_display() methods are added to the model instances.""" - place = self.form.save() - self.assertEqual(place.get_state_display(), 'Georgia') - self.assertEqual(place.get_state_req_display(), 'North Carolina') - - def test_required(self): - """Test that required USStateFields throw appropriate errors.""" - form = USPlaceForm({'state':'GA', 'name':'Place in GA'}) - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors['state_req'], [u'This field is required.']) - - def test_field_blank_option(self): - """Test that the empty option is there.""" - state_select_html = """\ -<select name="state" id="id_state"> -<option value="">---------</option> -<option value="AL">Alabama</option> -<option value="AK">Alaska</option> -<option value="AS">American Samoa</option> -<option value="AZ">Arizona</option> -<option value="AR">Arkansas</option> -<option value="CA">California</option> -<option value="CO">Colorado</option> -<option value="CT">Connecticut</option> -<option value="DE">Delaware</option> -<option value="DC">District of Columbia</option> -<option value="FL">Florida</option> -<option value="GA" selected="selected">Georgia</option> -<option value="GU">Guam</option> -<option value="HI">Hawaii</option> -<option value="ID">Idaho</option> -<option value="IL">Illinois</option> -<option value="IN">Indiana</option> -<option value="IA">Iowa</option> -<option value="KS">Kansas</option> -<option value="KY">Kentucky</option> -<option value="LA">Louisiana</option> -<option value="ME">Maine</option> -<option value="MD">Maryland</option> -<option value="MA">Massachusetts</option> -<option value="MI">Michigan</option> -<option value="MN">Minnesota</option> -<option value="MS">Mississippi</option> -<option value="MO">Missouri</option> -<option value="MT">Montana</option> -<option value="NE">Nebraska</option> -<option value="NV">Nevada</option> -<option value="NH">New Hampshire</option> -<option value="NJ">New Jersey</option> -<option value="NM">New Mexico</option> -<option value="NY">New York</option> -<option value="NC">North Carolina</option> -<option value="ND">North Dakota</option> -<option value="MP">Northern Mariana Islands</option> -<option value="OH">Ohio</option> -<option value="OK">Oklahoma</option> -<option value="OR">Oregon</option> -<option value="PA">Pennsylvania</option> -<option value="PR">Puerto Rico</option> -<option value="RI">Rhode Island</option> -<option value="SC">South Carolina</option> -<option value="SD">South Dakota</option> -<option value="TN">Tennessee</option> -<option value="TX">Texas</option> -<option value="UT">Utah</option> -<option value="VT">Vermont</option> -<option value="VI">Virgin Islands</option> -<option value="VA">Virginia</option> -<option value="WA">Washington</option> -<option value="WV">West Virginia</option> -<option value="WI">Wisconsin</option> -<option value="WY">Wyoming</option> -</select>""" - self.assertEqual(str(self.form['state']), state_select_html) diff --git a/parts/django/tests/regressiontests/m2m_regress/__init__.py b/parts/django/tests/regressiontests/m2m_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/m2m_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/m2m_regress/models.py b/parts/django/tests/regressiontests/m2m_regress/models.py deleted file mode 100644 index 1c2126d..0000000 --- a/parts/django/tests/regressiontests/m2m_regress/models.py +++ /dev/null @@ -1,58 +0,0 @@ -from django.db import models -from django.contrib.auth import models as auth - -# No related name is needed here, since symmetrical relations are not -# explicitly reversible. -class SelfRefer(models.Model): - name = models.CharField(max_length=10) - references = models.ManyToManyField('self') - related = models.ManyToManyField('self') - - def __unicode__(self): - return self.name - -class Tag(models.Model): - name = models.CharField(max_length=10) - - def __unicode__(self): - return self.name - -# Regression for #11956 -- a many to many to the base class -class TagCollection(Tag): - tags = models.ManyToManyField(Tag, related_name='tag_collections') - - def __unicode__(self): - return self.name - -# A related_name is required on one of the ManyToManyField entries here because -# they are both addressable as reverse relations from Tag. -class Entry(models.Model): - name = models.CharField(max_length=10) - topics = models.ManyToManyField(Tag) - related = models.ManyToManyField(Tag, related_name="similar") - - def __unicode__(self): - return self.name - -# Two models both inheriting from a base model with a self-referential m2m field -class SelfReferChild(SelfRefer): - pass - -class SelfReferChildSibling(SelfRefer): - pass - -# Many-to-Many relation between models, where one of the PK's isn't an Autofield -class Line(models.Model): - name = models.CharField(max_length=100) - -class Worksheet(models.Model): - id = models.CharField(primary_key=True, max_length=100) - lines = models.ManyToManyField(Line, blank=True, null=True) - -# Regression for #11226 -- A model with the same name that another one to -# which it has a m2m relation. This shouldn't cause a name clash between -# the automatically created m2m intermediary table FK field names when -# running syncdb -class User(models.Model): - name = models.CharField(max_length=30) - friends = models.ManyToManyField(auth.User) diff --git a/parts/django/tests/regressiontests/m2m_regress/tests.py b/parts/django/tests/regressiontests/m2m_regress/tests.py deleted file mode 100644 index 7e5e5c3..0000000 --- a/parts/django/tests/regressiontests/m2m_regress/tests.py +++ /dev/null @@ -1,82 +0,0 @@ -from django.core.exceptions import FieldError -from django.test import TestCase - -from models import (SelfRefer, Tag, TagCollection, Entry, SelfReferChild, - SelfReferChildSibling, Worksheet) - - -class M2MRegressionTests(TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_multiple_m2m(self): - # Multiple m2m references to model must be distinguished when - # accessing the relations through an instance attribute. - - s1 = SelfRefer.objects.create(name='s1') - s2 = SelfRefer.objects.create(name='s2') - s3 = SelfRefer.objects.create(name='s3') - s1.references.add(s2) - s1.related.add(s3) - - e1 = Entry.objects.create(name='e1') - t1 = Tag.objects.create(name='t1') - t2 = Tag.objects.create(name='t2') - - e1.topics.add(t1) - e1.related.add(t2) - - self.assertQuerysetEqual(s1.references.all(), ["<SelfRefer: s2>"]) - self.assertQuerysetEqual(s1.related.all(), ["<SelfRefer: s3>"]) - - self.assertQuerysetEqual(e1.topics.all(), ["<Tag: t1>"]) - self.assertQuerysetEqual(e1.related.all(), ["<Tag: t2>"]) - - def test_internal_related_name_not_in_error_msg(self): - # The secret internal related names for self-referential many-to-many - # fields shouldn't appear in the list when an error is made. - - self.assertRaisesErrorWithMessage(FieldError, - "Cannot resolve keyword 'porcupine' into field. Choices are: id, name, references, related, selfreferchild, selfreferchildsibling", - lambda: SelfRefer.objects.filter(porcupine='fred') - ) - - def test_m2m_inheritance_symmetry(self): - # Test to ensure that the relationship between two inherited models - # with a self-referential m2m field maintains symmetry - - sr_child = SelfReferChild(name="Hanna") - sr_child.save() - - sr_sibling = SelfReferChildSibling(name="Beth") - sr_sibling.save() - sr_child.related.add(sr_sibling) - - self.assertQuerysetEqual(sr_child.related.all(), ["<SelfRefer: Beth>"]) - self.assertQuerysetEqual(sr_sibling.related.all(), ["<SelfRefer: Hanna>"]) - - def test_m2m_pk_field_type(self): - # Regression for #11311 - The primary key for models in a m2m relation - # doesn't have to be an AutoField - - w = Worksheet(id='abc') - w.save() - w.delete() - - def test_add_m2m_with_base_class(self): - # Regression for #11956 -- You can add an object to a m2m with the - # base class without causing integrity errors - - t1 = Tag.objects.create(name='t1') - t2 = Tag.objects.create(name='t2') - - c1 = TagCollection.objects.create(name='c1') - c1.tags = [t1,t2] - c1 = TagCollection.objects.get(name='c1') - - self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"]) - self.assertQuerysetEqual(t1.tag_collections.all(), ["<TagCollection: c1>"]) diff --git a/parts/django/tests/regressiontests/m2m_through_regress/__init__.py b/parts/django/tests/regressiontests/m2m_through_regress/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/regressiontests/m2m_through_regress/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json b/parts/django/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json deleted file mode 100644 index 6f24886..0000000 --- a/parts/django/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "pk": "1", - "model": "m2m_through_regress.person", - "fields": { - "name": "Guido" - } - }, - { - "pk": "1", - "model": "auth.user", - "fields": { - "username": "Guido", - "email": "bdfl@python.org", - "password": "abcde" - } - }, - { - "pk": "1", - "model": "m2m_through_regress.group", - "fields": { - "name": "Python Core Group" - } - }, - { - "pk": "1", - "model": "m2m_through_regress.usermembership", - "fields": { - "user": "1", - "group": "1", - "price": "100" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/m2m_through_regress/models.py b/parts/django/tests/regressiontests/m2m_through_regress/models.py deleted file mode 100644 index ec87985..0000000 --- a/parts/django/tests/regressiontests/m2m_through_regress/models.py +++ /dev/null @@ -1,55 +0,0 @@ -from datetime import datetime - -from django.contrib.auth.models import User -from django.core import management -from django.db import models - - -# Forward declared intermediate model -class Membership(models.Model): - person = models.ForeignKey('Person') - group = models.ForeignKey('Group') - price = models.IntegerField(default=100) - - def __unicode__(self): - return "%s is a member of %s" % (self.person.name, self.group.name) - -# using custom id column to test ticket #11107 -class UserMembership(models.Model): - id = models.AutoField(db_column='usermembership_id', primary_key=True) - user = models.ForeignKey(User) - group = models.ForeignKey('Group') - price = models.IntegerField(default=100) - - def __unicode__(self): - return "%s is a user and member of %s" % (self.user.username, self.group.name) - -class Person(models.Model): - name = models.CharField(max_length=128) - - def __unicode__(self): - return self.name - -class Group(models.Model): - name = models.CharField(max_length=128) - # Membership object defined as a class - members = models.ManyToManyField(Person, through=Membership) - user_members = models.ManyToManyField(User, through='UserMembership') - - def __unicode__(self): - return self.name - -# A set of models that use an non-abstract inherited model as the 'through' model. -class A(models.Model): - a_text = models.CharField(max_length=20) - -class ThroughBase(models.Model): - a = models.ForeignKey(A) - b = models.ForeignKey('B') - -class Through(ThroughBase): - extra = models.CharField(max_length=20) - -class B(models.Model): - b_text = models.CharField(max_length=20) - a_list = models.ManyToManyField(A, through=Through) diff --git a/parts/django/tests/regressiontests/m2m_through_regress/tests.py b/parts/django/tests/regressiontests/m2m_through_regress/tests.py deleted file mode 100644 index 2eaf886..0000000 --- a/parts/django/tests/regressiontests/m2m_through_regress/tests.py +++ /dev/null @@ -1,128 +0,0 @@ -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -from django.core import management -from django.contrib.auth.models import User -from django.test import TestCase - -from models import Person, Group, Membership, UserMembership - - -class M2MThroughTestCase(TestCase): - def test_everything(self): - bob = Person.objects.create(name="Bob") - jim = Person.objects.create(name="Jim") - - rock = Group.objects.create(name="Rock") - roll = Group.objects.create(name="Roll") - - frank = User.objects.create_user("frank", "frank@example.com", "password") - jane = User.objects.create_user("jane", "jane@example.com", "password") - - Membership.objects.create(person=bob, group=rock) - Membership.objects.create(person=bob, group=roll) - Membership.objects.create(person=jim, group=rock) - - self.assertQuerysetEqual( - bob.group_set.all(), [ - "<Group: Rock>", - "<Group: Roll>", - ] - ) - - self.assertQuerysetEqual( - roll.members.all(), [ - "<Person: Bob>", - ] - ) - - self.assertRaises(AttributeError, setattr, bob, "group_set", []) - self.assertRaises(AttributeError, setattr, roll, "members", []) - - self.assertRaises(AttributeError, rock.members.create, name="Anne") - self.assertRaises(AttributeError, bob.group_set.create, name="Funk") - - UserMembership.objects.create(user=frank, group=rock) - UserMembership.objects.create(user=frank, group=roll) - UserMembership.objects.create(user=jane, group=rock) - - self.assertQuerysetEqual( - frank.group_set.all(), [ - "<Group: Rock>", - "<Group: Roll>", - ] - ) - - self.assertQuerysetEqual( - roll.user_members.all(), [ - "<User: frank>", - ] - ) - - def test_serialization(self): - "m2m-through models aren't serialized as m2m fields. Refs #8134" - - p = Person.objects.create(name="Bob") - g = Group.objects.create(name="Roll") - m = Membership.objects.create(person=p, group=g) - - pks = {"p_pk": p.pk, "g_pk": g.pk, "m_pk": m.pk} - - out = StringIO() - management.call_command("dumpdata", "m2m_through_regress", format="json", stdout=out) - self.assertEqual(out.getvalue().strip(), """[{"pk": %(m_pk)s, "model": "m2m_through_regress.membership", "fields": {"person": %(p_pk)s, "price": 100, "group": %(g_pk)s}}, {"pk": %(p_pk)s, "model": "m2m_through_regress.person", "fields": {"name": "Bob"}}, {"pk": %(g_pk)s, "model": "m2m_through_regress.group", "fields": {"name": "Roll"}}]""" % pks) - - out = StringIO() - management.call_command("dumpdata", "m2m_through_regress", format="xml", - indent=2, stdout=out) - self.assertEqual(out.getvalue().strip(), """ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="%(m_pk)s" model="m2m_through_regress.membership"> - <field to="m2m_through_regress.person" name="person" rel="ManyToOneRel">%(p_pk)s</field> - <field to="m2m_through_regress.group" name="group" rel="ManyToOneRel">%(g_pk)s</field> - <field type="IntegerField" name="price">100</field> - </object> - <object pk="%(p_pk)s" model="m2m_through_regress.person"> - <field type="CharField" name="name">Bob</field> - </object> - <object pk="%(g_pk)s" model="m2m_through_regress.group"> - <field type="CharField" name="name">Roll</field> - </object> -</django-objects> - """.strip() % pks) - - def test_join_trimming(self): - "Check that we don't involve too many copies of the intermediate table when doing a join. Refs #8046, #8254" - bob = Person.objects.create(name="Bob") - jim = Person.objects.create(name="Jim") - - rock = Group.objects.create(name="Rock") - roll = Group.objects.create(name="Roll") - - Membership.objects.create(person=bob, group=rock) - Membership.objects.create(person=jim, group=rock, price=50) - Membership.objects.create(person=bob, group=roll, price=50) - - self.assertQuerysetEqual( - rock.members.filter(membership__price=50), [ - "<Person: Jim>", - ] - ) - - self.assertQuerysetEqual( - bob.group_set.filter(membership__price=50), [ - "<Group: Roll>", - ] - ) - -class ThroughLoadDataTestCase(TestCase): - fixtures = ["m2m_through"] - - def test_sequence_creation(self): - "Check that sequences on an m2m_through are created for the through model, not a phantom auto-generated m2m table. Refs #11107" - out = StringIO() - management.call_command("dumpdata", "m2m_through_regress", format="json", stdout=out) - self.assertEqual(out.getvalue().strip(), """[{"pk": 1, "model": "m2m_through_regress.usermembership", "fields": {"price": 100, "group": 1, "user": 1}}, {"pk": 1, "model": "m2m_through_regress.person", "fields": {"name": "Guido"}}, {"pk": 1, "model": "m2m_through_regress.group", "fields": {"name": "Python Core Group"}}]""") diff --git a/parts/django/tests/regressiontests/mail/__init__.py b/parts/django/tests/regressiontests/mail/__init__.py deleted file mode 100644 index 139597f..0000000 --- a/parts/django/tests/regressiontests/mail/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/parts/django/tests/regressiontests/mail/custombackend.py b/parts/django/tests/regressiontests/mail/custombackend.py deleted file mode 100644 index 6b0e15a..0000000 --- a/parts/django/tests/regressiontests/mail/custombackend.py +++ /dev/null @@ -1,15 +0,0 @@ -"""A custom backend for testing.""" - -from django.core.mail.backends.base import BaseEmailBackend - - -class EmailBackend(BaseEmailBackend): - - def __init__(self, *args, **kwargs): - super(EmailBackend, self).__init__(*args, **kwargs) - self.test_outbox = [] - - def send_messages(self, email_messages): - # Messages are stored in a instance variable for testing. - self.test_outbox.extend(email_messages) - return len(email_messages) diff --git a/parts/django/tests/regressiontests/mail/models.py b/parts/django/tests/regressiontests/mail/models.py deleted file mode 100644 index 7ff128f..0000000 --- a/parts/django/tests/regressiontests/mail/models.py +++ /dev/null @@ -1 +0,0 @@ -# This file intentionally left blank
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/mail/tests.py b/parts/django/tests/regressiontests/mail/tests.py deleted file mode 100644 index 877df1c..0000000 --- a/parts/django/tests/regressiontests/mail/tests.py +++ /dev/null @@ -1,375 +0,0 @@ -# coding: utf-8 -import email -import os -import shutil -import sys -import tempfile -from StringIO import StringIO -from django.conf import settings -from django.core import mail -from django.core.mail import EmailMessage, mail_admins, mail_managers, EmailMultiAlternatives -from django.core.mail import send_mail, send_mass_mail -from django.core.mail.backends.base import BaseEmailBackend -from django.core.mail.backends import console, dummy, locmem, filebased, smtp -from django.core.mail.message import BadHeaderError -from django.test import TestCase -from django.utils.translation import ugettext_lazy - -class MailTests(TestCase): - - def test_ascii(self): - email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com']) - message = email.message() - self.assertEqual(message['Subject'].encode(), 'Subject') - self.assertEqual(message.get_payload(), 'Content') - self.assertEqual(message['From'], 'from@example.com') - self.assertEqual(message['To'], 'to@example.com') - - def test_multiple_recipients(self): - email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com','other@example.com']) - message = email.message() - self.assertEqual(message['Subject'].encode(), 'Subject') - self.assertEqual(message.get_payload(), 'Content') - self.assertEqual(message['From'], 'from@example.com') - self.assertEqual(message['To'], 'to@example.com, other@example.com') - - def test_header_injection(self): - email = EmailMessage('Subject\nInjection Test', 'Content', 'from@example.com', ['to@example.com']) - self.assertRaises(BadHeaderError, email.message) - email = EmailMessage(ugettext_lazy('Subject\nInjection Test'), 'Content', 'from@example.com', ['to@example.com']) - self.assertRaises(BadHeaderError, email.message) - - def test_space_continuation(self): - """ - Test for space continuation character in long (ascii) subject headers (#7747) - """ - email = EmailMessage('Long subject lines that get wrapped should use a space continuation character to get expected behaviour in Outlook and Thunderbird', 'Content', 'from@example.com', ['to@example.com']) - message = email.message() - self.assertEqual(message['Subject'], 'Long subject lines that get wrapped should use a space continuation\n character to get expected behaviour in Outlook and Thunderbird') - - def test_message_header_overrides(self): - """ - Specifying dates or message-ids in the extra headers overrides the - default values (#9233) - """ - headers = {"date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} - email = EmailMessage('subject', 'content', 'from@example.com', ['to@example.com'], headers=headers) - self.assertEqual(email.message().as_string(), 'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: subject\nFrom: from@example.com\nTo: to@example.com\ndate: Fri, 09 Nov 2001 01:08:47 -0000\nMessage-ID: foo\n\ncontent') - - def test_empty_admins(self): - """ - Test that mail_admins/mail_managers doesn't connect to the mail server - if there are no recipients (#9383) - """ - old_admins = settings.ADMINS - old_managers = settings.MANAGERS - - settings.ADMINS = settings.MANAGERS = [('nobody','nobody@example.com')] - mail.outbox = [] - mail_admins('hi', 'there') - self.assertEqual(len(mail.outbox), 1) - mail.outbox = [] - mail_managers('hi', 'there') - self.assertEqual(len(mail.outbox), 1) - - settings.ADMINS = settings.MANAGERS = [] - mail.outbox = [] - mail_admins('hi', 'there') - self.assertEqual(len(mail.outbox), 0) - mail.outbox = [] - mail_managers('hi', 'there') - self.assertEqual(len(mail.outbox), 0) - - settings.ADMINS = old_admins - settings.MANAGERS = old_managers - - def test_from_header(self): - """ - Make sure we can manually set the From header (#9214) - """ - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - message = email.message() - self.assertEqual(message['From'], 'from@example.com') - - def test_multiple_message_call(self): - """ - Regression for #13259 - Make sure that headers are not changed when - calling EmailMessage.message() - """ - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - message = email.message() - self.assertEqual(message['From'], 'from@example.com') - message = email.message() - self.assertEqual(message['From'], 'from@example.com') - - def test_unicode_header(self): - """ - Regression for #11144 - When a to/from/cc header contains unicode, - make sure the email addresses are parsed correctly (especially with - regards to commas) - """ - email = EmailMessage('Subject', 'Content', 'from@example.com', ['"Firstname Sürname" <to@example.com>','other@example.com']) - self.assertEqual(email.message()['To'], '=?utf-8?q?Firstname_S=C3=BCrname?= <to@example.com>, other@example.com') - email = EmailMessage('Subject', 'Content', 'from@example.com', ['"Sürname, Firstname" <to@example.com>','other@example.com']) - self.assertEqual(email.message()['To'], '=?utf-8?q?S=C3=BCrname=2C_Firstname?= <to@example.com>, other@example.com') - - def test_safe_mime_multipart(self): - """ - Make sure headers can be set with a different encoding than utf-8 in - SafeMIMEMultipart as well - """ - headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} - subject, from_email, to = 'hello', 'from@example.com', '"Sürname, Firstname" <to@example.com>' - text_content = 'This is an important message.' - html_content = '<p>This is an <strong>important</strong> message.</p>' - msg = EmailMultiAlternatives('Message from Firstname Sürname', text_content, from_email, [to], headers=headers) - msg.attach_alternative(html_content, "text/html") - msg.encoding = 'iso-8859-1' - self.assertEqual(msg.message()['To'], '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <to@example.com>') - self.assertEqual(msg.message()['Subject'].encode(), u'=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=') - - def test_encoding(self): - """ - Regression for #12791 - Encode body correctly with other encodings - than utf-8 - """ - email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', 'from@example.com', ['other@example.com']) - email.encoding = 'iso-8859-1' - message = email.message() - self.assertTrue(message.as_string().startswith('Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: from@example.com\nTo: other@example.com')) - self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.') - - # Make sure MIME attachments also works correctly with other encodings than utf-8 - text_content = 'Firstname Sürname is a great guy.' - html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>' - msg = EmailMultiAlternatives('Subject', text_content, 'from@example.com', ['to@example.com']) - msg.encoding = 'iso-8859-1' - msg.attach_alternative(html_content, "text/html") - self.assertEqual(msg.message().get_payload(0).as_string(), 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.') - self.assertEqual(msg.message().get_payload(1).as_string(), 'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>') - - def test_attachments(self): - """Regression test for #9367""" - headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} - subject, from_email, to = 'hello', 'from@example.com', 'to@example.com' - text_content = 'This is an important message.' - html_content = '<p>This is an <strong>important</strong> message.</p>' - msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers) - msg.attach_alternative(html_content, "text/html") - msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf") - msg_str = msg.message().as_string() - message = email.message_from_string(msg_str) - self.assertTrue(message.is_multipart()) - self.assertEqual(message.get_content_type(), 'multipart/mixed') - self.assertEqual(message.get_default_type(), 'text/plain') - payload = message.get_payload() - self.assertEqual(payload[0].get_content_type(), 'multipart/alternative') - self.assertEqual(payload[1].get_content_type(), 'application/pdf') - - def test_arbitrary_stream(self): - """ - Test that the console backend can be pointed at an arbitrary stream. - """ - s = StringIO() - connection = mail.get_connection('django.core.mail.backends.console.EmailBackend', stream=s) - send_mail('Subject', 'Content', 'from@example.com', ['to@example.com'], connection=connection) - self.assertTrue(s.getvalue().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: ')) - - def test_stdout(self): - """Make sure that the console backend writes to stdout by default""" - old_stdout = sys.stdout - sys.stdout = StringIO() - connection = console.EmailBackend() - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - connection.send_messages([email]) - self.assertTrue(sys.stdout.getvalue().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: ')) - sys.stdout = old_stdout - - def test_dummy(self): - """ - Make sure that dummy backends returns correct number of sent messages - """ - connection = dummy.EmailBackend() - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - self.assertEqual(connection.send_messages([email, email, email]), 3) - - def test_locmem(self): - """ - Make sure that the locmen backend populates the outbox. - """ - mail.outbox = [] - connection = locmem.EmailBackend() - email1 = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - email2 = EmailMessage('Subject 2', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - connection.send_messages([email1, email2]) - self.assertEqual(len(mail.outbox), 2) - self.assertEqual(mail.outbox[0].subject, 'Subject') - self.assertEqual(mail.outbox[1].subject, 'Subject 2') - - # Make sure that multiple locmem connections share mail.outbox - mail.outbox = [] - connection2 = locmem.EmailBackend() - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - connection.send_messages([email]) - connection2.send_messages([email]) - self.assertEqual(len(mail.outbox), 2) - - def test_file_backend(self): - tmp_dir = tempfile.mkdtemp() - connection = filebased.EmailBackend(file_path=tmp_dir) - email1 = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - connection.send_messages([email1]) - self.assertEqual(len(os.listdir(tmp_dir)), 1) - message = email.message_from_file(open(os.path.join(tmp_dir, os.listdir(tmp_dir)[0]))) - self.assertEqual(message.get_content_type(), 'text/plain') - self.assertEqual(message.get('subject'), 'Subject') - self.assertEqual(message.get('from'), 'from@example.com') - self.assertEqual(message.get('to'), 'to@example.com') - connection2 = filebased.EmailBackend(file_path=tmp_dir) - connection2.send_messages([email1]) - self.assertEqual(len(os.listdir(tmp_dir)), 2) - connection.send_messages([email1]) - self.assertEqual(len(os.listdir(tmp_dir)), 2) - email1.connection = filebased.EmailBackend(file_path=tmp_dir) - connection_created = connection.open() - email1.send() - self.assertEqual(len(os.listdir(tmp_dir)), 3) - email1.send() - self.assertEqual(len(os.listdir(tmp_dir)), 3) - connection.close() - shutil.rmtree(tmp_dir) - - def test_arbitrary_keyword(self): - """ - Make sure that get_connection() accepts arbitrary keyword that might be - used with custom backends. - """ - c = mail.get_connection(fail_silently=True, foo='bar') - self.assertTrue(c.fail_silently) - - def test_custom_backend(self): - """Test custom backend defined in this suite.""" - conn = mail.get_connection('regressiontests.mail.custombackend.EmailBackend') - self.assertTrue(hasattr(conn, 'test_outbox')) - email = EmailMessage('Subject', 'Content', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'}) - conn.send_messages([email]) - self.assertEqual(len(conn.test_outbox), 1) - - def test_backend_arg(self): - """Test backend argument of mail.get_connection()""" - self.assertTrue(isinstance(mail.get_connection('django.core.mail.backends.smtp.EmailBackend'), smtp.EmailBackend)) - self.assertTrue(isinstance(mail.get_connection('django.core.mail.backends.locmem.EmailBackend'), locmem.EmailBackend)) - self.assertTrue(isinstance(mail.get_connection('django.core.mail.backends.dummy.EmailBackend'), dummy.EmailBackend)) - self.assertTrue(isinstance(mail.get_connection('django.core.mail.backends.console.EmailBackend'), console.EmailBackend)) - tmp_dir = tempfile.mkdtemp() - self.assertTrue(isinstance(mail.get_connection('django.core.mail.backends.filebased.EmailBackend', file_path=tmp_dir), filebased.EmailBackend)) - shutil.rmtree(tmp_dir) - self.assertTrue(isinstance(mail.get_connection(), locmem.EmailBackend)) - - def test_connection_arg(self): - """Test connection argument to send_mail(), et. al.""" - connection = mail.get_connection('django.core.mail.backends.locmem.EmailBackend') - - mail.outbox = [] - send_mail('Subject', 'Content', 'from@example.com', ['to@example.com'], connection=connection) - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, 'Subject') - self.assertEqual(message.from_email, 'from@example.com') - self.assertEqual(message.to, ['to@example.com']) - - mail.outbox = [] - send_mass_mail([ - ('Subject1', 'Content1', 'from1@example.com', ['to1@example.com']), - ('Subject2', 'Content2', 'from2@example.com', ['to2@example.com']) - ], connection=connection) - self.assertEqual(len(mail.outbox), 2) - message = mail.outbox[0] - self.assertEqual(message.subject, 'Subject1') - self.assertEqual(message.from_email, 'from1@example.com') - self.assertEqual(message.to, ['to1@example.com']) - message = mail.outbox[1] - self.assertEqual(message.subject, 'Subject2') - self.assertEqual(message.from_email, 'from2@example.com') - self.assertEqual(message.to, ['to2@example.com']) - - old_admins = settings.ADMINS - old_managers = settings.MANAGERS - settings.ADMINS = settings.MANAGERS = [('nobody','nobody@example.com')] - - mail.outbox = [] - mail_admins('Subject', 'Content', connection=connection) - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, '[Django] Subject') - self.assertEqual(message.from_email, 'root@localhost') - self.assertEqual(message.to, ['nobody@example.com']) - - mail.outbox = [] - mail_managers('Subject', 'Content', connection=connection) - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, '[Django] Subject') - self.assertEqual(message.from_email, 'root@localhost') - self.assertEqual(message.to, ['nobody@example.com']) - - settings.ADMINS = old_admins - settings.MANAGERS = old_managers - - def test_mail_prefix(self): - """Test prefix argument in manager/admin mail.""" - # Regression for #13494. - old_admins = settings.ADMINS - old_managers = settings.MANAGERS - settings.ADMINS = settings.MANAGERS = [('nobody','nobody@example.com')] - - mail_managers(ugettext_lazy('Subject'), 'Content') - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, '[Django] Subject') - - mail.outbox = [] - mail_admins(ugettext_lazy('Subject'), 'Content') - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, '[Django] Subject') - - settings.ADMINS = old_admins - settings.MANAGERS = old_managers - - def test_idn_validation(self): - """Test internationalized email adresses""" - # Regression for #14301. - mail.outbox = [] - from_email = u'fröm@öäü.com' - to_email = u'tö@öäü.com' - connection = mail.get_connection('django.core.mail.backends.locmem.EmailBackend') - send_mail('Subject', 'Content', from_email, [to_email], connection=connection) - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0] - self.assertEqual(message.subject, 'Subject') - self.assertEqual(message.from_email, from_email) - self.assertEqual(message.to, [to_email]) - self.assertTrue(message.message().as_string().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: =?utf-8?b?ZnLDtm1Aw7bDpMO8LmNvbQ==?=\nTo: =?utf-8?b?dMO2QMO2w6TDvC5jb20=?=')) - - def test_idn_smtp_send(self): - import smtplib - smtplib.SMTP = MockSMTP - from_email = u'fröm@öäü.com' - to_email = u'tö@öäü.com' - connection = mail.get_connection('django.core.mail.backends.smtp.EmailBackend') - self.assertTrue(send_mail('Subject', 'Content', from_email, [to_email], connection=connection)) - -class MockSMTP(object): - def __init__(self, host='', port=0, local_hostname=None, - timeout=1): - pass - - def sendmail(self, from_addr, to_addrs, msg, mail_options=[], - rcpt_options=[]): - for addr in to_addrs: - str(addr.split('@', 1)[-1]) - return {} - - def quit(self): - return 0 diff --git a/parts/django/tests/regressiontests/makemessages/__init__.py b/parts/django/tests/regressiontests/makemessages/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/makemessages/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/makemessages/extraction.py b/parts/django/tests/regressiontests/makemessages/extraction.py deleted file mode 100644 index 6df6e90..0000000 --- a/parts/django/tests/regressiontests/makemessages/extraction.py +++ /dev/null @@ -1,109 +0,0 @@ -import os -import re -import shutil -from django.test import TestCase -from django.core import management - -LOCALE='de' - -class ExtractorTests(TestCase): - - PO_FILE='locale/%s/LC_MESSAGES/django.po' % LOCALE - - def setUp(self): - self._cwd = os.getcwd() - self.test_dir = os.path.abspath(os.path.dirname(__file__)) - - def _rmrf(self, dname): - if os.path.commonprefix([self.test_dir, os.path.abspath(dname)]) != self.test_dir: - return - shutil.rmtree(dname) - - def tearDown(self): - os.chdir(self.test_dir) - try: - self._rmrf('locale/%s' % LOCALE) - except OSError: - pass - os.chdir(self._cwd) - - def assertMsgId(self, msgid, s): - return self.assert_(re.search('^msgid "%s"' % msgid, s, re.MULTILINE)) - - def assertNotMsgId(self, msgid, s): - return self.assert_(not re.search('^msgid "%s"' % msgid, s, re.MULTILINE)) - - -class TemplateExtractorTests(ExtractorTests): - - def test_templatize(self): - os.chdir(self.test_dir) - management.call_command('makemessages', locale=LOCALE, verbosity=0) - self.assert_(os.path.exists(self.PO_FILE)) - po_contents = open(self.PO_FILE, 'r').read() - self.assertMsgId('I think that 100%% is more that 50%% of anything.', po_contents) - self.assertMsgId('I think that 100%% is more that 50%% of %\(obj\)s.', po_contents) - - -class JavascriptExtractorTests(ExtractorTests): - - PO_FILE='locale/%s/LC_MESSAGES/djangojs.po' % LOCALE - - def test_javascript_literals(self): - os.chdir(self.test_dir) - management.call_command('makemessages', domain='djangojs', locale=LOCALE, verbosity=0) - self.assert_(os.path.exists(self.PO_FILE)) - po_contents = open(self.PO_FILE, 'r').read() - self.assertMsgId('This literal should be included.', po_contents) - self.assertMsgId('This one as well.', po_contents) - - -class IgnoredExtractorTests(ExtractorTests): - - def test_ignore_option(self): - os.chdir(self.test_dir) - management.call_command('makemessages', locale=LOCALE, verbosity=0, ignore_patterns=['ignore_dir/*']) - self.assert_(os.path.exists(self.PO_FILE)) - po_contents = open(self.PO_FILE, 'r').read() - self.assertMsgId('This literal should be included.', po_contents) - self.assertNotMsgId('This should be ignored.', po_contents) - - -class SymlinkExtractorTests(ExtractorTests): - - def setUp(self): - self._cwd = os.getcwd() - self.test_dir = os.path.abspath(os.path.dirname(__file__)) - self.symlinked_dir = os.path.join(self.test_dir, 'templates_symlinked') - - def tearDown(self): - super(SymlinkExtractorTests, self).tearDown() - os.chdir(self.test_dir) - try: - os.remove(self.symlinked_dir) - except OSError: - pass - os.chdir(self._cwd) - - def test_symlink(self): - if hasattr(os, 'symlink'): - if os.path.exists(self.symlinked_dir): - self.assert_(os.path.islink(self.symlinked_dir)) - else: - os.symlink(os.path.join(self.test_dir, 'templates'), self.symlinked_dir) - os.chdir(self.test_dir) - management.call_command('makemessages', locale=LOCALE, verbosity=0, symlinks=True) - self.assert_(os.path.exists(self.PO_FILE)) - po_contents = open(self.PO_FILE, 'r').read() - self.assertMsgId('This literal should be included.', po_contents) - self.assert_('templates_symlinked/test.html' in po_contents) - - -class CopyPluralFormsExtractorTests(ExtractorTests): - - def test_copy_plural_forms(self): - os.chdir(self.test_dir) - management.call_command('makemessages', locale=LOCALE, verbosity=0) - self.assert_(os.path.exists(self.PO_FILE)) - po_contents = open(self.PO_FILE, 'r').read() - self.assert_('Plural-Forms: nplurals=2; plural=(n != 1)' in po_contents) diff --git a/parts/django/tests/regressiontests/makemessages/ignore_dir/ignored.html b/parts/django/tests/regressiontests/makemessages/ignore_dir/ignored.html deleted file mode 100644 index 6a29678..0000000 --- a/parts/django/tests/regressiontests/makemessages/ignore_dir/ignored.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% trans "This should be ignored." %} diff --git a/parts/django/tests/regressiontests/makemessages/javascript.js b/parts/django/tests/regressiontests/makemessages/javascript.js deleted file mode 100644 index bc5ec87..0000000 --- a/parts/django/tests/regressiontests/makemessages/javascript.js +++ /dev/null @@ -1,4 +0,0 @@ -// ' -gettext('This literal should be included.') -// ' -gettext('This one as well.') diff --git a/parts/django/tests/regressiontests/makemessages/locale/dummy b/parts/django/tests/regressiontests/makemessages/locale/dummy deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/makemessages/locale/dummy +++ /dev/null diff --git a/parts/django/tests/regressiontests/makemessages/models.py b/parts/django/tests/regressiontests/makemessages/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/makemessages/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/makemessages/templates/test.html b/parts/django/tests/regressiontests/makemessages/templates/test.html deleted file mode 100644 index 96438e1..0000000 --- a/parts/django/tests/regressiontests/makemessages/templates/test.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load i18n %} -{% trans "This literal should be included." %} -{% blocktrans %}I think that 100% is more that 50% of anything.{% endblocktrans %} -{% blocktrans with 'txt' as obj %}I think that 100% is more that 50% of {{ obj }}.{% endblocktrans %}
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/makemessages/tests.py b/parts/django/tests/regressiontests/makemessages/tests.py deleted file mode 100644 index 5798e67..0000000 --- a/parts/django/tests/regressiontests/makemessages/tests.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import re -from subprocess import Popen, PIPE - -def find_command(cmd, path=None, pathext=None): - if path is None: - path = os.environ.get('PATH', []).split(os.pathsep) - if isinstance(path, basestring): - path = [path] - # check if there are funny path extensions for executables, e.g. Windows - if pathext is None: - pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD').split(os.pathsep) - # don't use extensions if the command ends with one of them - for ext in pathext: - if cmd.endswith(ext): - pathext = [''] - break - # check if we find the command on PATH - for p in path: - f = os.path.join(p, cmd) - if os.path.isfile(f): - return f - for ext in pathext: - fext = f + ext - if os.path.isfile(fext): - return fext - return None - -# checks if it can find xgettext on the PATH and -# imports the extraction tests if yes -xgettext_cmd = find_command('xgettext') -if xgettext_cmd: - p = Popen('%s --version' % xgettext_cmd, shell=True, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt', universal_newlines=True) - output = p.communicate()[0] - match = re.search(r'(?P<major>\d+)\.(?P<minor>\d+)', output) - if match: - xversion = (int(match.group('major')), int(match.group('minor'))) - if xversion >= (0, 15): - from extraction import * - del p diff --git a/parts/django/tests/regressiontests/managers_regress/__init__.py b/parts/django/tests/regressiontests/managers_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/managers_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/managers_regress/models.py b/parts/django/tests/regressiontests/managers_regress/models.py deleted file mode 100644 index 1e1b1c9..0000000 --- a/parts/django/tests/regressiontests/managers_regress/models.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -Various edge-cases for model managers. -""" - -from django.db import models - -class OnlyFred(models.Manager): - def get_query_set(self): - return super(OnlyFred, self).get_query_set().filter(name='fred') - -class OnlyBarney(models.Manager): - def get_query_set(self): - return super(OnlyBarney, self).get_query_set().filter(name='barney') - -class Value42(models.Manager): - def get_query_set(self): - return super(Value42, self).get_query_set().filter(value=42) - -class AbstractBase1(models.Model): - name = models.CharField(max_length=50) - - class Meta: - abstract = True - - # Custom managers - manager1 = OnlyFred() - manager2 = OnlyBarney() - objects = models.Manager() - -class AbstractBase2(models.Model): - value = models.IntegerField() - - class Meta: - abstract = True - - # Custom manager - restricted = Value42() - -# No custom manager on this class to make sure the default case doesn't break. -class AbstractBase3(models.Model): - comment = models.CharField(max_length=50) - - class Meta: - abstract = True - -class Parent(models.Model): - name = models.CharField(max_length=50) - - manager = OnlyFred() - - def __unicode__(self): - return self.name - -# Managers from base classes are inherited and, if no manager is specified -# *and* the parent has a manager specified, the first one (in the MRO) will -# become the default. -class Child1(AbstractBase1): - data = models.CharField(max_length=25) - - def __unicode__(self): - return self.data - -class Child2(AbstractBase1, AbstractBase2): - data = models.CharField(max_length=25) - - def __unicode__(self): - return self.data - -class Child3(AbstractBase1, AbstractBase3): - data = models.CharField(max_length=25) - - def __unicode__(self): - return self.data - -class Child4(AbstractBase1): - data = models.CharField(max_length=25) - - # Should be the default manager, although the parent managers are - # inherited. - default = models.Manager() - - def __unicode__(self): - return self.data - -class Child5(AbstractBase3): - name = models.CharField(max_length=25) - - default = OnlyFred() - objects = models.Manager() - - def __unicode__(self): - return self.name - -# Will inherit managers from AbstractBase1, but not Child4. -class Child6(Child4): - value = models.IntegerField() - -# Will not inherit default manager from parent. -class Child7(Parent): - pass diff --git a/parts/django/tests/regressiontests/managers_regress/tests.py b/parts/django/tests/regressiontests/managers_regress/tests.py deleted file mode 100644 index 9a6db61..0000000 --- a/parts/django/tests/regressiontests/managers_regress/tests.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.test import TestCase - -from models import Child1, Child2, Child3, Child4, Child5, Child6, Child7 - - -class ManagersRegressionTests(TestCase): - def test_managers(self): - a1 = Child1.objects.create(name='fred', data='a1') - a2 = Child1.objects.create(name='barney', data='a2') - b1 = Child2.objects.create(name='fred', data='b1', value=1) - b2 = Child2.objects.create(name='barney', data='b2', value=42) - c1 = Child3.objects.create(name='fred', data='c1', comment='yes') - c2 = Child3.objects.create(name='barney', data='c2', comment='no') - d1 = Child4.objects.create(name='fred', data='d1') - d2 = Child4.objects.create(name='barney', data='d2') - e1 = Child5.objects.create(name='fred', comment='yes') - e2 = Child5.objects.create(name='barney', comment='no') - f1 = Child6.objects.create(name='fred', data='f1', value=42) - f2 = Child6.objects.create(name='barney', data='f2', value=42) - g1 = Child7.objects.create(name='fred') - g2 = Child7.objects.create(name='barney') - - self.assertQuerysetEqual(Child1.manager1.all(), ["<Child1: a1>"]) - self.assertQuerysetEqual(Child1.manager2.all(), ["<Child1: a2>"]) - self.assertQuerysetEqual(Child1._default_manager.all(), ["<Child1: a1>"]) - - self.assertQuerysetEqual(Child2._default_manager.all(), ["<Child2: b1>"]) - self.assertQuerysetEqual(Child2.restricted.all(), ["<Child2: b2>"]) - - self.assertQuerysetEqual(Child3._default_manager.all(), ["<Child3: c1>"]) - self.assertQuerysetEqual(Child3.manager1.all(), ["<Child3: c1>"]) - self.assertQuerysetEqual(Child3.manager2.all(), ["<Child3: c2>"]) - - # Since Child6 inherits from Child4, the corresponding rows from f1 and - # f2 also appear here. This is the expected result. - self.assertQuerysetEqual(Child4._default_manager.order_by('data'), [ - "<Child4: d1>", - "<Child4: d2>", - "<Child4: f1>", - "<Child4: f2>" - ] - ) - self.assertQuerysetEqual(Child4.manager1.all(), [ - "<Child4: d1>", - "<Child4: f1>" - ] - ) - self.assertQuerysetEqual(Child5._default_manager.all(), ["<Child5: fred>"]) - self.assertQuerysetEqual(Child6._default_manager.all(), ["<Child6: f1>"]) - self.assertQuerysetEqual(Child7._default_manager.order_by('name'), [ - "<Child7: barney>", - "<Child7: fred>" - ] - ) diff --git a/parts/django/tests/regressiontests/many_to_one_regress/__init__.py b/parts/django/tests/regressiontests/many_to_one_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/many_to_one_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/many_to_one_regress/models.py b/parts/django/tests/regressiontests/many_to_one_regress/models.py deleted file mode 100644 index 53348a7..0000000 --- a/parts/django/tests/regressiontests/many_to_one_regress/models.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -Regression tests for a few ForeignKey bugs. -""" - -from django.db import models - -# If ticket #1578 ever slips back in, these models will not be able to be -# created (the field names being lower-cased versions of their opposite -# classes is important here). - -class First(models.Model): - second = models.IntegerField() - -class Second(models.Model): - first = models.ForeignKey(First, related_name = 'the_first') - -# Protect against repetition of #1839, #2415 and #2536. -class Third(models.Model): - name = models.CharField(max_length=20) - third = models.ForeignKey('self', null=True, related_name='child_set') - -class Parent(models.Model): - name = models.CharField(max_length=20) - bestchild = models.ForeignKey('Child', null=True, related_name='favored_by') - -class Child(models.Model): - name = models.CharField(max_length=20) - parent = models.ForeignKey(Parent) - - -# Multiple paths to the same model (#7110, #7125) -class Category(models.Model): - name = models.CharField(max_length=20) - - def __unicode__(self): - return self.name - -class Record(models.Model): - category = models.ForeignKey(Category) - -class Relation(models.Model): - left = models.ForeignKey(Record, related_name='left_set') - right = models.ForeignKey(Record, related_name='right_set') - - def __unicode__(self): - return u"%s - %s" % (self.left.category.name, self.right.category.name) diff --git a/parts/django/tests/regressiontests/many_to_one_regress/tests.py b/parts/django/tests/regressiontests/many_to_one_regress/tests.py deleted file mode 100644 index 7d2a49c..0000000 --- a/parts/django/tests/regressiontests/many_to_one_regress/tests.py +++ /dev/null @@ -1,105 +0,0 @@ -from django.db import models -from django.test import TestCase - -from models import First, Second, Third, Parent, Child, Category, Record, Relation - -class ManyToOneRegressionTests(TestCase): - def test_object_creation(self): - Third.objects.create(id='3', name='An example') - parent = Parent(name='fred') - parent.save() - Child.objects.create(name='bam-bam', parent=parent) - - def test_fk_assignment_and_related_object_cache(self): - # Tests of ForeignKey assignment and the related-object cache (see #6886). - - p = Parent.objects.create(name="Parent") - c = Child.objects.create(name="Child", parent=p) - - # Look up the object again so that we get a "fresh" object. - c = Child.objects.get(name="Child") - p = c.parent - - # Accessing the related object again returns the exactly same object. - self.assertTrue(c.parent is p) - - # But if we kill the cache, we get a new object. - del c._parent_cache - self.assertFalse(c.parent is p) - - # Assigning a new object results in that object getting cached immediately. - p2 = Parent.objects.create(name="Parent 2") - c.parent = p2 - self.assertTrue(c.parent is p2) - - # Assigning None succeeds if field is null=True. - p.bestchild = None - self.assertTrue(p.bestchild is None) - - # bestchild should still be None after saving. - p.save() - self.assertTrue(p.bestchild is None) - - # bestchild should still be None after fetching the object again. - p = Parent.objects.get(name="Parent") - self.assertTrue(p.bestchild is None) - - # Assigning None fails: Child.parent is null=False. - self.assertRaises(ValueError, setattr, c, "parent", None) - - # You also can't assign an object of the wrong type here - self.assertRaises(ValueError, setattr, c, "parent", First(id=1, second=1)) - - # Nor can you explicitly assign None to Child.parent during object - # creation (regression for #9649). - self.assertRaises(ValueError, Child, name='xyzzy', parent=None) - self.assertRaises(ValueError, Child.objects.create, name='xyzzy', parent=None) - - # Creation using keyword argument should cache the related object. - p = Parent.objects.get(name="Parent") - c = Child(parent=p) - self.assertTrue(c.parent is p) - - # Creation using keyword argument and unsaved related instance (#8070). - p = Parent() - c = Child(parent=p) - self.assertTrue(c.parent is p) - - # Creation using attname keyword argument and an id will cause the - # related object to be fetched. - p = Parent.objects.get(name="Parent") - c = Child(parent_id=p.id) - self.assertFalse(c.parent is p) - self.assertEqual(c.parent, p) - - def test_multiple_foreignkeys(self): - # Test of multiple ForeignKeys to the same model (bug #7125). - c1 = Category.objects.create(name='First') - c2 = Category.objects.create(name='Second') - c3 = Category.objects.create(name='Third') - r1 = Record.objects.create(category=c1) - r2 = Record.objects.create(category=c1) - r3 = Record.objects.create(category=c2) - r4 = Record.objects.create(category=c2) - r5 = Record.objects.create(category=c3) - r = Relation.objects.create(left=r1, right=r2) - r = Relation.objects.create(left=r3, right=r4) - r = Relation.objects.create(left=r1, right=r3) - r = Relation.objects.create(left=r5, right=r2) - r = Relation.objects.create(left=r3, right=r2) - - q1 = Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second']) - self.assertQuerysetEqual(q1, ["<Relation: First - Second>"]) - - q2 = Category.objects.filter(record__left_set__right__category__name='Second').order_by('name') - self.assertQuerysetEqual(q2, ["<Category: First>", "<Category: Second>"]) - - p = Parent.objects.create(name="Parent") - c = Child.objects.create(name="Child", parent=p) - self.assertRaises(ValueError, Child.objects.create, name="Grandchild", parent=c) - - def test_fk_instantiation_outside_model(self): - # Regression for #12190 -- Should be able to instantiate a FK outside - # of a model, and interrogate its related field. - cat = models.ForeignKey(Category) - self.assertEqual('id', cat.rel.get_related_field().name) diff --git a/parts/django/tests/regressiontests/max_lengths/__init__.py b/parts/django/tests/regressiontests/max_lengths/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/parts/django/tests/regressiontests/max_lengths/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/parts/django/tests/regressiontests/max_lengths/models.py b/parts/django/tests/regressiontests/max_lengths/models.py deleted file mode 100644 index 78eb30c..0000000 --- a/parts/django/tests/regressiontests/max_lengths/models.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.db import models - -class PersonWithDefaultMaxLengths(models.Model): - email = models.EmailField() - vcard = models.FileField(upload_to='/tmp') - homepage = models.URLField() - avatar = models.FilePathField() - -class PersonWithCustomMaxLengths(models.Model): - email = models.EmailField(max_length=250) - vcard = models.FileField(upload_to='/tmp', max_length=250) - homepage = models.URLField(max_length=250) - avatar = models.FilePathField(max_length=250) diff --git a/parts/django/tests/regressiontests/max_lengths/tests.py b/parts/django/tests/regressiontests/max_lengths/tests.py deleted file mode 100644 index 0fb2f30..0000000 --- a/parts/django/tests/regressiontests/max_lengths/tests.py +++ /dev/null @@ -1,36 +0,0 @@ -from unittest import TestCase -from django.db import DatabaseError -from regressiontests.max_lengths.models import PersonWithDefaultMaxLengths, PersonWithCustomMaxLengths - -class MaxLengthArgumentsTests(TestCase): - - def verify_max_length(self, model,field,length): - self.assertEquals(model._meta.get_field(field).max_length,length) - - def test_default_max_lengths(self): - self.verify_max_length(PersonWithDefaultMaxLengths, 'email', 75) - self.verify_max_length(PersonWithDefaultMaxLengths, 'vcard', 100) - self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200) - self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100) - - def test_custom_max_lengths(self): - self.verify_max_length(PersonWithCustomMaxLengths, 'email', 250) - self.verify_max_length(PersonWithCustomMaxLengths, 'vcard', 250) - self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 250) - self.verify_max_length(PersonWithCustomMaxLengths, 'avatar', 250) - -class MaxLengthORMTests(TestCase): - - def test_custom_max_lengths(self): - args = { - "email": "someone@example.com", - "vcard": "vcard", - "homepage": "http://example.com/", - "avatar": "me.jpg" - } - - for field in ("email", "vcard", "homepage", "avatar"): - new_args = args.copy() - new_args[field] = "X" * 250 # a value longer than any of the default fields could hold. - p = PersonWithCustomMaxLengths.objects.create(**new_args) - self.assertEqual(getattr(p, field), ("X" * 250))
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/middleware/__init__.py b/parts/django/tests/regressiontests/middleware/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/middleware/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/middleware/extra_urls.py b/parts/django/tests/regressiontests/middleware/extra_urls.py deleted file mode 100644 index b2a8902..0000000 --- a/parts/django/tests/regressiontests/middleware/extra_urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.conf.urls.defaults import patterns - -urlpatterns = patterns('', - (r'^middleware/customurlconf/noslash$', 'view'), - (r'^middleware/customurlconf/slash/$', 'view'), - (r'^middleware/customurlconf/needsquoting#/$', 'view'), -) diff --git a/parts/django/tests/regressiontests/middleware/models.py b/parts/django/tests/regressiontests/middleware/models.py deleted file mode 100644 index 71abcc5..0000000 --- a/parts/django/tests/regressiontests/middleware/models.py +++ /dev/null @@ -1 +0,0 @@ -# models.py file for tests to run. diff --git a/parts/django/tests/regressiontests/middleware/tests.py b/parts/django/tests/regressiontests/middleware/tests.py deleted file mode 100644 index b77a2a3..0000000 --- a/parts/django/tests/regressiontests/middleware/tests.py +++ /dev/null @@ -1,249 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.conf import settings -from django.http import HttpRequest -from django.middleware.common import CommonMiddleware -from django.test import TestCase - - -class CommonMiddlewareTest(TestCase): - def setUp(self): - self.slash = settings.APPEND_SLASH - self.www = settings.PREPEND_WWW - - def tearDown(self): - settings.APPEND_SLASH = self.slash - settings.PREPEND_WWW = self.www - - def _get_request(self, path): - request = HttpRequest() - request.META = { - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - } - request.path = request.path_info = "/middleware/%s" % path - return request - - def test_append_slash_have_slash(self): - """ - Tests that URLs with slashes go unmolested. - """ - settings.APPEND_SLASH = True - request = self._get_request('slash/') - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_slashless_resource(self): - """ - Tests that matches to explicit slashless URLs go unmolested. - """ - settings.APPEND_SLASH = True - request = self._get_request('noslash') - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_slashless_unknown(self): - """ - Tests that APPEND_SLASH doesn't redirect to unknown resources. - """ - settings.APPEND_SLASH = True - request = self._get_request('unknown') - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_redirect(self): - """ - Tests that APPEND_SLASH redirects slashless URLs to a valid pattern. - """ - settings.APPEND_SLASH = True - request = self._get_request('slash') - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], 'http://testserver/middleware/slash/') - - def test_append_slash_no_redirect_on_POST_in_DEBUG(self): - """ - Tests that while in debug mode, an exception is raised with a warning - when a failed attempt is made to POST to an URL which would normally be - redirected to a slashed version. - """ - settings.APPEND_SLASH = True - settings.DEBUG = True - request = self._get_request('slash') - request.method = 'POST' - self.assertRaises( - RuntimeError, - CommonMiddleware().process_request, - request) - try: - CommonMiddleware().process_request(request) - except RuntimeError, e: - self.assertTrue('end in a slash' in str(e)) - settings.DEBUG = False - - def test_append_slash_disabled(self): - """ - Tests disabling append slash functionality. - """ - settings.APPEND_SLASH = False - request = self._get_request('slash') - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_quoted(self): - """ - Tests that URLs which require quoting are redirected to their slash - version ok. - """ - settings.APPEND_SLASH = True - request = self._get_request('needsquoting#') - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals( - r['Location'], - 'http://testserver/middleware/needsquoting%23/') - - def test_prepend_www(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = False - request = self._get_request('path/') - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals( - r['Location'], - 'http://www.testserver/middleware/path/') - - def test_prepend_www_append_slash_have_slash(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = True - request = self._get_request('slash/') - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], - 'http://www.testserver/middleware/slash/') - - def test_prepend_www_append_slash_slashless(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = True - request = self._get_request('slash') - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], - 'http://www.testserver/middleware/slash/') - - - # The following tests examine expected behavior given a custom urlconf that - # overrides the default one through the request object. - - def test_append_slash_have_slash_custom_urlconf(self): - """ - Tests that URLs with slashes go unmolested. - """ - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/slash/') - request.urlconf = 'regressiontests.middleware.extra_urls' - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_slashless_resource_custom_urlconf(self): - """ - Tests that matches to explicit slashless URLs go unmolested. - """ - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/noslash') - request.urlconf = 'regressiontests.middleware.extra_urls' - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_slashless_unknown_custom_urlconf(self): - """ - Tests that APPEND_SLASH doesn't redirect to unknown resources. - """ - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/unknown') - request.urlconf = 'regressiontests.middleware.extra_urls' - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_redirect_custom_urlconf(self): - """ - Tests that APPEND_SLASH redirects slashless URLs to a valid pattern. - """ - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/slash') - request.urlconf = 'regressiontests.middleware.extra_urls' - r = CommonMiddleware().process_request(request) - self.assertFalse(r is None, - "CommonMiddlware failed to return APPEND_SLASH redirect using request.urlconf") - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], 'http://testserver/middleware/customurlconf/slash/') - - def test_append_slash_no_redirect_on_POST_in_DEBUG_custom_urlconf(self): - """ - Tests that while in debug mode, an exception is raised with a warning - when a failed attempt is made to POST to an URL which would normally be - redirected to a slashed version. - """ - settings.APPEND_SLASH = True - settings.DEBUG = True - request = self._get_request('customurlconf/slash') - request.urlconf = 'regressiontests.middleware.extra_urls' - request.method = 'POST' - self.assertRaises( - RuntimeError, - CommonMiddleware().process_request, - request) - try: - CommonMiddleware().process_request(request) - except RuntimeError, e: - self.assertTrue('end in a slash' in str(e)) - settings.DEBUG = False - - def test_append_slash_disabled_custom_urlconf(self): - """ - Tests disabling append slash functionality. - """ - settings.APPEND_SLASH = False - request = self._get_request('customurlconf/slash') - request.urlconf = 'regressiontests.middleware.extra_urls' - self.assertEquals(CommonMiddleware().process_request(request), None) - - def test_append_slash_quoted_custom_urlconf(self): - """ - Tests that URLs which require quoting are redirected to their slash - version ok. - """ - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/needsquoting#') - request.urlconf = 'regressiontests.middleware.extra_urls' - r = CommonMiddleware().process_request(request) - self.assertFalse(r is None, - "CommonMiddlware failed to return APPEND_SLASH redirect using request.urlconf") - self.assertEquals(r.status_code, 301) - self.assertEquals( - r['Location'], - 'http://testserver/middleware/customurlconf/needsquoting%23/') - - def test_prepend_www_custom_urlconf(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = False - request = self._get_request('customurlconf/path/') - request.urlconf = 'regressiontests.middleware.extra_urls' - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals( - r['Location'], - 'http://www.testserver/middleware/customurlconf/path/') - - def test_prepend_www_append_slash_have_slash_custom_urlconf(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/slash/') - request.urlconf = 'regressiontests.middleware.extra_urls' - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], - 'http://www.testserver/middleware/customurlconf/slash/') - - def test_prepend_www_append_slash_slashless_custom_urlconf(self): - settings.PREPEND_WWW = True - settings.APPEND_SLASH = True - request = self._get_request('customurlconf/slash') - request.urlconf = 'regressiontests.middleware.extra_urls' - r = CommonMiddleware().process_request(request) - self.assertEquals(r.status_code, 301) - self.assertEquals(r['Location'], - 'http://www.testserver/middleware/customurlconf/slash/') diff --git a/parts/django/tests/regressiontests/middleware/urls.py b/parts/django/tests/regressiontests/middleware/urls.py deleted file mode 100644 index 88a4b37..0000000 --- a/parts/django/tests/regressiontests/middleware/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.conf.urls.defaults import patterns - -urlpatterns = patterns('', - (r'^noslash$', 'view'), - (r'^slash/$', 'view'), - (r'^needsquoting#/$', 'view'), -) diff --git a/parts/django/tests/regressiontests/middleware_exceptions/__init__.py b/parts/django/tests/regressiontests/middleware_exceptions/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/middleware_exceptions/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/middleware_exceptions/models.py b/parts/django/tests/regressiontests/middleware_exceptions/models.py deleted file mode 100644 index 137941f..0000000 --- a/parts/django/tests/regressiontests/middleware_exceptions/models.py +++ /dev/null @@ -1 +0,0 @@ -from django.db import models diff --git a/parts/django/tests/regressiontests/middleware_exceptions/tests.py b/parts/django/tests/regressiontests/middleware_exceptions/tests.py deleted file mode 100644 index 3d9c5f6..0000000 --- a/parts/django/tests/regressiontests/middleware_exceptions/tests.py +++ /dev/null @@ -1,40 +0,0 @@ -import sys - -from django.test import TestCase -from django.core.signals import got_request_exception - -class TestException(Exception): - pass - -class TestMiddleware(object): - def process_request(self, request): - raise TestException('Test Exception') - -class MiddlewareExceptionTest(TestCase): - def setUp(self): - self.exceptions = [] - got_request_exception.connect(self._on_request_exception) - self.client.handler.load_middleware() - - def tearDown(self): - got_request_exception.disconnect(self._on_request_exception) - self.exceptions = [] - - def _on_request_exception(self, sender, request, **kwargs): - self.exceptions.append(sys.exc_info()) - - def test_process_request(self): - self.client.handler._request_middleware.insert(0, TestMiddleware().process_request) - try: - response = self.client.get('/') - except TestException, e: - # Test client indefinitely re-raises any exceptions being raised - # during request handling. Hence actual testing that exception was - # properly handled is done by relying on got_request_exception - # signal being sent. - pass - except Exception, e: - self.fail("Unexpected exception: %s" % e) - self.assertEquals(len(self.exceptions), 1) - exception, value, tb = self.exceptions[0] - self.assertEquals(value.args, ('Test Exception', )) diff --git a/parts/django/tests/regressiontests/middleware_exceptions/urls.py b/parts/django/tests/regressiontests/middleware_exceptions/urls.py deleted file mode 100644 index 63f3ba1..0000000 --- a/parts/django/tests/regressiontests/middleware_exceptions/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -# coding: utf-8 -from django.conf.urls.defaults import * - -import views - -urlpatterns = patterns('', - (r'^$', views.index), -) diff --git a/parts/django/tests/regressiontests/middleware_exceptions/views.py b/parts/django/tests/regressiontests/middleware_exceptions/views.py deleted file mode 100644 index e2d597d..0000000 --- a/parts/django/tests/regressiontests/middleware_exceptions/views.py +++ /dev/null @@ -1,4 +0,0 @@ -from django import http - -def index(request): - return http.HttpResponse('') diff --git a/parts/django/tests/regressiontests/model_fields/4x8.png b/parts/django/tests/regressiontests/model_fields/4x8.png Binary files differdeleted file mode 100644 index ffce444..0000000 --- a/parts/django/tests/regressiontests/model_fields/4x8.png +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_fields/8x4.png b/parts/django/tests/regressiontests/model_fields/8x4.png Binary files differdeleted file mode 100644 index 60e6d69..0000000 --- a/parts/django/tests/regressiontests/model_fields/8x4.png +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_fields/__init__.py b/parts/django/tests/regressiontests/model_fields/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_fields/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_fields/imagefield.py b/parts/django/tests/regressiontests/model_fields/imagefield.py deleted file mode 100644 index dd79e7a..0000000 --- a/parts/django/tests/regressiontests/model_fields/imagefield.py +++ /dev/null @@ -1,420 +0,0 @@ -import os -import shutil - -from django.core.files import File -from django.core.files.base import ContentFile -from django.core.files.images import ImageFile -from django.test import TestCase - -from models import Image, Person, PersonWithHeight, PersonWithHeightAndWidth, \ - PersonDimensionsFirst, PersonTwoImages, TestImageFieldFile - - -# If PIL available, do these tests. -if Image: - - from models import temp_storage_dir - - - class ImageFieldTestMixin(object): - """ - Mixin class to provide common functionality to ImageField test classes. - """ - - # Person model to use for tests. - PersonModel = PersonWithHeightAndWidth - # File class to use for file instances. - File = ImageFile - - def setUp(self): - """ - Creates a pristine temp directory (or deletes and recreates if it - already exists) that the model uses as its storage directory. - - Sets up two ImageFile instances for use in tests. - """ - if os.path.exists(temp_storage_dir): - shutil.rmtree(temp_storage_dir) - os.mkdir(temp_storage_dir) - - file_path1 = os.path.join(os.path.dirname(__file__), "4x8.png") - self.file1 = self.File(open(file_path1, 'rb')) - - file_path2 = os.path.join(os.path.dirname(__file__), "8x4.png") - self.file2 = self.File(open(file_path2, 'rb')) - - def tearDown(self): - """ - Removes temp directory and all its contents. - """ - shutil.rmtree(temp_storage_dir) - - def check_dimensions(self, instance, width, height, - field_name='mugshot'): - """ - Asserts that the given width and height values match both the - field's height and width attributes and the height and width fields - (if defined) the image field is caching to. - - Note, this method will check for dimension fields named by adding - "_width" or "_height" to the name of the ImageField. So, the - models used in these tests must have their fields named - accordingly. - - By default, we check the field named "mugshot", but this can be - specified by passing the field_name parameter. - """ - field = getattr(instance, field_name) - # Check height/width attributes of field. - if width is None and height is None: - self.assertRaises(ValueError, getattr, field, 'width') - self.assertRaises(ValueError, getattr, field, 'height') - else: - self.assertEqual(field.width, width) - self.assertEqual(field.height, height) - - # Check height/width fields of model, if defined. - width_field_name = field_name + '_width' - if hasattr(instance, width_field_name): - self.assertEqual(getattr(instance, width_field_name), width) - height_field_name = field_name + '_height' - if hasattr(instance, height_field_name): - self.assertEqual(getattr(instance, height_field_name), height) - - - class ImageFieldTests(ImageFieldTestMixin, TestCase): - """ - Tests for ImageField that don't need to be run with each of the - different test model classes. - """ - - def test_equal_notequal_hash(self): - """ - Bug #9786: Ensure '==' and '!=' work correctly. - Bug #9508: make sure hash() works as expected (equal items must - hash to the same value). - """ - # Create two Persons with different mugshots. - p1 = self.PersonModel(name="Joe") - p1.mugshot.save("mug", self.file1) - p2 = self.PersonModel(name="Bob") - p2.mugshot.save("mug", self.file2) - self.assertEqual(p1.mugshot == p2.mugshot, False) - self.assertEqual(p1.mugshot != p2.mugshot, True) - - # Test again with an instance fetched from the db. - p1_db = self.PersonModel.objects.get(name="Joe") - self.assertEqual(p1_db.mugshot == p2.mugshot, False) - self.assertEqual(p1_db.mugshot != p2.mugshot, True) - - # Instance from db should match the local instance. - self.assertEqual(p1_db.mugshot == p1.mugshot, True) - self.assertEqual(hash(p1_db.mugshot), hash(p1.mugshot)) - self.assertEqual(p1_db.mugshot != p1.mugshot, False) - - def test_instantiate_missing(self): - """ - If the underlying file is unavailable, still create instantiate the - object without error. - """ - p = self.PersonModel(name="Joan") - p.mugshot.save("shot", self.file1) - p = self.PersonModel.objects.get(name="Joan") - path = p.mugshot.path - shutil.move(path, path + '.moved') - p2 = self.PersonModel.objects.get(name="Joan") - - def test_delete_when_missing(self): - """ - Bug #8175: correctly delete an object where the file no longer - exists on the file system. - """ - p = self.PersonModel(name="Fred") - p.mugshot.save("shot", self.file1) - os.remove(p.mugshot.path) - p.delete() - - def test_size_method(self): - """ - Bug #8534: FileField.size should not leave the file open. - """ - p = self.PersonModel(name="Joan") - p.mugshot.save("shot", self.file1) - - # Get a "clean" model instance - p = self.PersonModel.objects.get(name="Joan") - # It won't have an opened file. - self.assertEqual(p.mugshot.closed, True) - - # After asking for the size, the file should still be closed. - _ = p.mugshot.size - self.assertEqual(p.mugshot.closed, True) - - def test_pickle(self): - """ - Tests that ImageField can be pickled, unpickled, and that the - image of the unpickled version is the same as the original. - """ - import pickle - - p = Person(name="Joe") - p.mugshot.save("mug", self.file1) - dump = pickle.dumps(p) - - p2 = Person(name="Bob") - p2.mugshot = self.file1 - - loaded_p = pickle.loads(dump) - self.assertEqual(p.mugshot, loaded_p.mugshot) - - - class ImageFieldTwoDimensionsTests(ImageFieldTestMixin, TestCase): - """ - Tests behavior of an ImageField and its dimensions fields. - """ - - def test_constructor(self): - """ - Tests assigning an image field through the model's constructor. - """ - p = self.PersonModel(name='Joe', mugshot=self.file1) - self.check_dimensions(p, 4, 8) - p.save() - self.check_dimensions(p, 4, 8) - - def test_image_after_constructor(self): - """ - Tests behavior when image is not passed in constructor. - """ - p = self.PersonModel(name='Joe') - # TestImageField value will default to being an instance of its - # attr_class, a TestImageFieldFile, with name == None, which will - # cause it to evaluate as False. - self.assertEqual(isinstance(p.mugshot, TestImageFieldFile), True) - self.assertEqual(bool(p.mugshot), False) - - # Test setting a fresh created model instance. - p = self.PersonModel(name='Joe') - p.mugshot = self.file1 - self.check_dimensions(p, 4, 8) - - def test_create(self): - """ - Tests assigning an image in Manager.create(). - """ - p = self.PersonModel.objects.create(name='Joe', mugshot=self.file1) - self.check_dimensions(p, 4, 8) - - def test_default_value(self): - """ - Tests that the default value for an ImageField is an instance of - the field's attr_class (TestImageFieldFile in this case) with no - name (name set to None). - """ - p = self.PersonModel() - self.assertEqual(isinstance(p.mugshot, TestImageFieldFile), True) - self.assertEqual(bool(p.mugshot), False) - - def test_assignment_to_None(self): - """ - Tests that assigning ImageField to None clears dimensions. - """ - p = self.PersonModel(name='Joe', mugshot=self.file1) - self.check_dimensions(p, 4, 8) - - # If image assigned to None, dimension fields should be cleared. - p.mugshot = None - self.check_dimensions(p, None, None) - - p.mugshot = self.file2 - self.check_dimensions(p, 8, 4) - - def test_field_save_and_delete_methods(self): - """ - Tests assignment using the field's save method and deletion using - the field's delete method. - """ - p = self.PersonModel(name='Joe') - p.mugshot.save("mug", self.file1) - self.check_dimensions(p, 4, 8) - - # A new file should update dimensions. - p.mugshot.save("mug", self.file2) - self.check_dimensions(p, 8, 4) - - # Field and dimensions should be cleared after a delete. - p.mugshot.delete(save=False) - self.assertEqual(p.mugshot, None) - self.check_dimensions(p, None, None) - - def test_dimensions(self): - """ - Checks that dimensions are updated correctly in various situations. - """ - p = self.PersonModel(name='Joe') - - # Dimensions should get set if file is saved. - p.mugshot.save("mug", self.file1) - self.check_dimensions(p, 4, 8) - - # Test dimensions after fetching from database. - p = self.PersonModel.objects.get(name='Joe') - # Bug 11084: Dimensions should not get recalculated if file is - # coming from the database. We test this by checking if the file - # was opened. - self.assertEqual(p.mugshot.was_opened, False) - self.check_dimensions(p, 4, 8) - # After checking dimensions on the image field, the file will have - # opened. - self.assertEqual(p.mugshot.was_opened, True) - # Dimensions should now be cached, and if we reset was_opened and - # check dimensions again, the file should not have opened. - p.mugshot.was_opened = False - self.check_dimensions(p, 4, 8) - self.assertEqual(p.mugshot.was_opened, False) - - # If we assign a new image to the instance, the dimensions should - # update. - p.mugshot = self.file2 - self.check_dimensions(p, 8, 4) - # Dimensions were recalculated, and hence file should have opened. - self.assertEqual(p.mugshot.was_opened, True) - - - class ImageFieldNoDimensionsTests(ImageFieldTwoDimensionsTests): - """ - Tests behavior of an ImageField with no dimension fields. - """ - - PersonModel = Person - - - class ImageFieldOneDimensionTests(ImageFieldTwoDimensionsTests): - """ - Tests behavior of an ImageField with one dimensions field. - """ - - PersonModel = PersonWithHeight - - - class ImageFieldDimensionsFirstTests(ImageFieldTwoDimensionsTests): - """ - Tests behavior of an ImageField where the dimensions fields are - defined before the ImageField. - """ - - PersonModel = PersonDimensionsFirst - - - class ImageFieldUsingFileTests(ImageFieldTwoDimensionsTests): - """ - Tests behavior of an ImageField when assigning it a File instance - rather than an ImageFile instance. - """ - - PersonModel = PersonDimensionsFirst - File = File - - - class TwoImageFieldTests(ImageFieldTestMixin, TestCase): - """ - Tests a model with two ImageFields. - """ - - PersonModel = PersonTwoImages - - def test_constructor(self): - p = self.PersonModel(mugshot=self.file1, headshot=self.file2) - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - p.save() - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - - def test_create(self): - p = self.PersonModel.objects.create(mugshot=self.file1, - headshot=self.file2) - self.check_dimensions(p, 4, 8) - self.check_dimensions(p, 8, 4, 'headshot') - - def test_assignment(self): - p = self.PersonModel() - self.check_dimensions(p, None, None, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - - p.mugshot = self.file1 - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - p.headshot = self.file2 - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - - # Clear the ImageFields one at a time. - p.mugshot = None - self.check_dimensions(p, None, None, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - p.headshot = None - self.check_dimensions(p, None, None, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - - def test_field_save_and_delete_methods(self): - p = self.PersonModel(name='Joe') - p.mugshot.save("mug", self.file1) - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - p.headshot.save("head", self.file2) - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - - # We can use save=True when deleting the image field with null=True - # dimension fields and the other field has an image. - p.headshot.delete(save=True) - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - p.mugshot.delete(save=False) - self.check_dimensions(p, None, None, 'mugshot') - self.check_dimensions(p, None, None, 'headshot') - - def test_dimensions(self): - """ - Checks that dimensions are updated correctly in various situations. - """ - p = self.PersonModel(name='Joe') - - # Dimensions should get set for the saved file. - p.mugshot.save("mug", self.file1) - p.headshot.save("head", self.file2) - self.check_dimensions(p, 4, 8, 'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - - # Test dimensions after fetching from database. - p = self.PersonModel.objects.get(name='Joe') - # Bug 11084: Dimensions should not get recalculated if file is - # coming from the database. We test this by checking if the file - # was opened. - self.assertEqual(p.mugshot.was_opened, False) - self.assertEqual(p.headshot.was_opened, False) - self.check_dimensions(p, 4, 8,'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - # After checking dimensions on the image fields, the files will - # have been opened. - self.assertEqual(p.mugshot.was_opened, True) - self.assertEqual(p.headshot.was_opened, True) - # Dimensions should now be cached, and if we reset was_opened and - # check dimensions again, the file should not have opened. - p.mugshot.was_opened = False - p.headshot.was_opened = False - self.check_dimensions(p, 4, 8,'mugshot') - self.check_dimensions(p, 8, 4, 'headshot') - self.assertEqual(p.mugshot.was_opened, False) - self.assertEqual(p.headshot.was_opened, False) - - # If we assign a new image to the instance, the dimensions should - # update. - p.mugshot = self.file2 - p.headshot = self.file1 - self.check_dimensions(p, 8, 4, 'mugshot') - self.check_dimensions(p, 4, 8, 'headshot') - # Dimensions were recalculated, and hence file should have opened. - self.assertEqual(p.mugshot.was_opened, True) - self.assertEqual(p.headshot.was_opened, True) diff --git a/parts/django/tests/regressiontests/model_fields/models.py b/parts/django/tests/regressiontests/model_fields/models.py deleted file mode 100644 index 45cd223..0000000 --- a/parts/django/tests/regressiontests/model_fields/models.py +++ /dev/null @@ -1,154 +0,0 @@ -import os -import tempfile - -# Try to import PIL in either of the two ways it can end up installed. -# Checking for the existence of Image is enough for CPython, but for PyPy, -# you need to check for the underlying modules. - -try: - from PIL import Image, _imaging -except ImportError: - try: - import Image, _imaging - except ImportError: - Image = None - -from django.core.files.storage import FileSystemStorage -from django.db import models -from django.db.models.fields.files import ImageFieldFile, ImageField - - -class Foo(models.Model): - a = models.CharField(max_length=10) - d = models.DecimalField(max_digits=5, decimal_places=3) - -def get_foo(): - return Foo.objects.get(id=1) - -class Bar(models.Model): - b = models.CharField(max_length=10) - a = models.ForeignKey(Foo, default=get_foo) - -class Whiz(models.Model): - CHOICES = ( - ('Group 1', ( - (1,'First'), - (2,'Second'), - ) - ), - ('Group 2', ( - (3,'Third'), - (4,'Fourth'), - ) - ), - (0,'Other'), - ) - c = models.IntegerField(choices=CHOICES, null=True) - -class BigD(models.Model): - d = models.DecimalField(max_digits=38, decimal_places=30) - -class BigS(models.Model): - s = models.SlugField(max_length=255) - -class BigInt(models.Model): - value = models.BigIntegerField() - null_value = models.BigIntegerField(null = True, blank = True) - -class Post(models.Model): - title = models.CharField(max_length=100) - body = models.TextField() - -class NullBooleanModel(models.Model): - nbfield = models.NullBooleanField() - -class BooleanModel(models.Model): - bfield = models.BooleanField() - string = models.CharField(max_length=10, default='abc') - -############################################################################### -# ImageField - -# If PIL available, do these tests. -if Image: - class TestImageFieldFile(ImageFieldFile): - """ - Custom Field File class that records whether or not the underlying file - was opened. - """ - def __init__(self, *args, **kwargs): - self.was_opened = False - super(TestImageFieldFile, self).__init__(*args,**kwargs) - def open(self): - self.was_opened = True - super(TestImageFieldFile, self).open() - - class TestImageField(ImageField): - attr_class = TestImageFieldFile - - # Set up a temp directory for file storage. - temp_storage_dir = tempfile.mkdtemp() - temp_storage = FileSystemStorage(temp_storage_dir) - temp_upload_to_dir = os.path.join(temp_storage.location, 'tests') - - class Person(models.Model): - """ - Model that defines an ImageField with no dimension fields. - """ - name = models.CharField(max_length=50) - mugshot = TestImageField(storage=temp_storage, upload_to='tests') - - class PersonWithHeight(models.Model): - """ - Model that defines an ImageField with only one dimension field. - """ - name = models.CharField(max_length=50) - mugshot = TestImageField(storage=temp_storage, upload_to='tests', - height_field='mugshot_height') - mugshot_height = models.PositiveSmallIntegerField() - - class PersonWithHeightAndWidth(models.Model): - """ - Model that defines height and width fields after the ImageField. - """ - name = models.CharField(max_length=50) - mugshot = TestImageField(storage=temp_storage, upload_to='tests', - height_field='mugshot_height', - width_field='mugshot_width') - mugshot_height = models.PositiveSmallIntegerField() - mugshot_width = models.PositiveSmallIntegerField() - - class PersonDimensionsFirst(models.Model): - """ - Model that defines height and width fields before the ImageField. - """ - name = models.CharField(max_length=50) - mugshot_height = models.PositiveSmallIntegerField() - mugshot_width = models.PositiveSmallIntegerField() - mugshot = TestImageField(storage=temp_storage, upload_to='tests', - height_field='mugshot_height', - width_field='mugshot_width') - - class PersonTwoImages(models.Model): - """ - Model that: - * Defines two ImageFields - * Defines the height/width fields before the ImageFields - * Has a nullalble ImageField - """ - name = models.CharField(max_length=50) - mugshot_height = models.PositiveSmallIntegerField() - mugshot_width = models.PositiveSmallIntegerField() - mugshot = TestImageField(storage=temp_storage, upload_to='tests', - height_field='mugshot_height', - width_field='mugshot_width') - headshot_height = models.PositiveSmallIntegerField( - blank=True, null=True) - headshot_width = models.PositiveSmallIntegerField( - blank=True, null=True) - headshot = TestImageField(blank=True, null=True, - storage=temp_storage, upload_to='tests', - height_field='headshot_height', - width_field='headshot_width') - -############################################################################### diff --git a/parts/django/tests/regressiontests/model_fields/tests.py b/parts/django/tests/regressiontests/model_fields/tests.py deleted file mode 100644 index 72a7d4d..0000000 --- a/parts/django/tests/regressiontests/model_fields/tests.py +++ /dev/null @@ -1,313 +0,0 @@ -import datetime -import unittest -from decimal import Decimal - -import django.test -from django import forms -from django.db import models -from django.core.exceptions import ValidationError - -from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, NullBooleanModel, BooleanModel - -# If PIL available, do these tests. -if Image: - from imagefield import \ - ImageFieldTests, \ - ImageFieldTwoDimensionsTests, \ - ImageFieldNoDimensionsTests, \ - ImageFieldOneDimensionTests, \ - ImageFieldDimensionsFirstTests, \ - ImageFieldUsingFileTests, \ - TwoImageFieldTests - - -class BasicFieldTests(django.test.TestCase): - def test_show_hidden_initial(self): - """ - Regression test for #12913. Make sure fields with choices respect - show_hidden_initial as a kwarg to models.Field.formfield() - """ - choices = [(0, 0), (1, 1)] - model_field = models.Field(choices=choices) - form_field = model_field.formfield(show_hidden_initial=True) - self.assertTrue(form_field.show_hidden_initial) - - form_field = model_field.formfield(show_hidden_initial=False) - self.assertFalse(form_field.show_hidden_initial) - - def test_nullbooleanfield_blank(self): - """ - Regression test for #13071: NullBooleanField should not throw - a validation error when given a value of None. - - """ - nullboolean = NullBooleanModel(nbfield=None) - try: - nullboolean.full_clean() - except ValidationError, e: - self.fail("NullBooleanField failed validation with value of None: %s" % e.messages) - -class DecimalFieldTests(django.test.TestCase): - def test_to_python(self): - f = models.DecimalField(max_digits=4, decimal_places=2) - self.assertEqual(f.to_python(3), Decimal("3")) - self.assertEqual(f.to_python("3.14"), Decimal("3.14")) - self.assertRaises(ValidationError, f.to_python, "abc") - - def test_default(self): - f = models.DecimalField(default=Decimal("0.00")) - self.assertEqual(f.get_default(), Decimal("0.00")) - - def test_format(self): - f = models.DecimalField(max_digits=5, decimal_places=1) - self.assertEqual(f._format(f.to_python(2)), u'2.0') - self.assertEqual(f._format(f.to_python('2.6')), u'2.6') - self.assertEqual(f._format(None), None) - - def test_get_db_prep_lookup(self): - from django.db import connection - f = models.DecimalField(max_digits=5, decimal_places=1) - self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None]) - - def test_filter_with_strings(self): - """ - We should be able to filter decimal fields using strings (#8023) - """ - Foo.objects.create(id=1, a='abc', d=Decimal("12.34")) - self.assertEqual(list(Foo.objects.filter(d=u'1.23')), []) - - def test_save_without_float_conversion(self): - """ - Ensure decimals don't go through a corrupting float conversion during - save (#5079). - """ - bd = BigD(d="12.9") - bd.save() - bd = BigD.objects.get(pk=bd.pk) - self.assertEqual(bd.d, Decimal("12.9")) - - def test_lookup_really_big_value(self): - """ - Ensure that really big values can be used in a filter statement, even - with older Python versions. - """ - # This should not crash. That counts as a win for our purposes. - Foo.objects.filter(d__gte=100000000000) - -class ForeignKeyTests(django.test.TestCase): - def test_callable_default(self): - """Test the use of a lazy callable for ForeignKey.default""" - a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34")) - b = Bar.objects.create(b="bcd") - self.assertEqual(b.a, a) - -class DateTimeFieldTests(unittest.TestCase): - def test_datetimefield_to_python_usecs(self): - """DateTimeField.to_python should support usecs""" - f = models.DateTimeField() - self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'), - datetime.datetime(2001, 1, 2, 3, 4, 5, 6)) - self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'), - datetime.datetime(2001, 1, 2, 3, 4, 5, 999999)) - - def test_timefield_to_python_usecs(self): - """TimeField.to_python should support usecs""" - f = models.TimeField() - self.assertEqual(f.to_python('01:02:03.000004'), - datetime.time(1, 2, 3, 4)) - self.assertEqual(f.to_python('01:02:03.999999'), - datetime.time(1, 2, 3, 999999)) - -class BooleanFieldTests(unittest.TestCase): - def _test_get_db_prep_lookup(self, f): - from django.db import connection - self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True]) - self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True]) - self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True]) - self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False]) - self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False]) - self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False]) - self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None]) - - def _test_to_python(self, f): - self.assertTrue(f.to_python(1) is True) - self.assertTrue(f.to_python(0) is False) - - def test_booleanfield_get_db_prep_lookup(self): - self._test_get_db_prep_lookup(models.BooleanField()) - - def test_nullbooleanfield_get_db_prep_lookup(self): - self._test_get_db_prep_lookup(models.NullBooleanField()) - - def test_booleanfield_to_python(self): - self._test_to_python(models.BooleanField()) - - def test_nullbooleanfield_to_python(self): - self._test_to_python(models.NullBooleanField()) - - def test_booleanfield_choices_blank(self): - """ - Test that BooleanField with choices and defaults doesn't generate a - formfield with the blank option (#9640, #10549). - """ - choices = [(1, u'Si'), (2, 'No')] - f = models.BooleanField(choices=choices, default=1, null=True) - self.assertEqual(f.formfield().choices, [('', '---------')] + choices) - - f = models.BooleanField(choices=choices, default=1, null=False) - self.assertEqual(f.formfield().choices, choices) - - def test_return_type(self): - b = BooleanModel() - b.bfield = True - b.save() - b2 = BooleanModel.objects.get(pk=b.pk) - self.assertTrue(isinstance(b2.bfield, bool)) - self.assertEqual(b2.bfield, True) - - b3 = BooleanModel() - b3.bfield = False - b3.save() - b4 = BooleanModel.objects.get(pk=b3.pk) - self.assertTrue(isinstance(b4.bfield, bool)) - self.assertEqual(b4.bfield, False) - - b = NullBooleanModel() - b.nbfield = True - b.save() - b2 = NullBooleanModel.objects.get(pk=b.pk) - self.assertTrue(isinstance(b2.nbfield, bool)) - self.assertEqual(b2.nbfield, True) - - b3 = NullBooleanModel() - b3.nbfield = False - b3.save() - b4 = NullBooleanModel.objects.get(pk=b3.pk) - self.assertTrue(isinstance(b4.nbfield, bool)) - self.assertEqual(b4.nbfield, False) - - # http://code.djangoproject.com/ticket/13293 - # Verify that when an extra clause exists, the boolean - # conversions are applied with an offset - b5 = BooleanModel.objects.all().extra( - select={'string_length': 'LENGTH(string)'})[0] - self.assertFalse(isinstance(b5.pk, bool)) - -class ChoicesTests(django.test.TestCase): - def test_choices_and_field_display(self): - """ - Check that get_choices and get_flatchoices interact with - get_FIELD_display to return the expected values (#7913). - """ - self.assertEqual(Whiz(c=1).get_c_display(), 'First') # A nested value - self.assertEqual(Whiz(c=0).get_c_display(), 'Other') # A top level value - self.assertEqual(Whiz(c=9).get_c_display(), 9) # Invalid value - self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value - self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value - -class SlugFieldTests(django.test.TestCase): - def test_slugfield_max_length(self): - """ - Make sure SlugField honors max_length (#9706) - """ - bs = BigS.objects.create(s = 'slug'*50) - bs = BigS.objects.get(pk=bs.pk) - self.assertEqual(bs.s, 'slug'*50) - - -class ValidationTest(django.test.TestCase): - def test_charfield_raises_error_on_empty_string(self): - f = models.CharField() - self.assertRaises(ValidationError, f.clean, "", None) - - def test_charfield_cleans_empty_string_when_blank_true(self): - f = models.CharField(blank=True) - self.assertEqual('', f.clean('', None)) - - def test_integerfield_cleans_valid_string(self): - f = models.IntegerField() - self.assertEqual(2, f.clean('2', None)) - - def test_integerfield_raises_error_on_invalid_intput(self): - f = models.IntegerField() - self.assertRaises(ValidationError, f.clean, "a", None) - - def test_charfield_with_choices_cleans_valid_choice(self): - f = models.CharField(max_length=1, choices=[('a','A'), ('b','B')]) - self.assertEqual('a', f.clean('a', None)) - - def test_charfield_with_choices_raises_error_on_invalid_choice(self): - f = models.CharField(choices=[('a','A'), ('b','B')]) - self.assertRaises(ValidationError, f.clean, "not a", None) - - def test_choices_validation_supports_named_groups(self): - f = models.IntegerField(choices=(('group',((10,'A'),(20,'B'))),(30,'C'))) - self.assertEqual(10, f.clean(10, None)) - - def test_nullable_integerfield_raises_error_with_blank_false(self): - f = models.IntegerField(null=True, blank=False) - self.assertRaises(ValidationError, f.clean, None, None) - - def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self): - f = models.IntegerField(null=True, blank=True) - self.assertEqual(None, f.clean(None, None)) - - def test_integerfield_raises_error_on_empty_input(self): - f = models.IntegerField(null=False) - self.assertRaises(ValidationError, f.clean, None, None) - self.assertRaises(ValidationError, f.clean, '', None) - - def test_charfield_raises_error_on_empty_input(self): - f = models.CharField(null=False) - self.assertRaises(ValidationError, f.clean, None, None) - - def test_datefield_cleans_date(self): - f = models.DateField() - self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', None)) - - def test_boolean_field_doesnt_accept_empty_input(self): - f = models.BooleanField() - self.assertRaises(ValidationError, f.clean, None, None) - - -class BigIntegerFieldTests(django.test.TestCase): - def test_limits(self): - # Ensure that values that are right at the limits can be saved - # and then retrieved without corruption. - maxval = 9223372036854775807 - minval = -maxval - 1 - BigInt.objects.create(value=maxval) - qs = BigInt.objects.filter(value__gte=maxval) - self.assertEqual(qs.count(), 1) - self.assertEqual(qs[0].value, maxval) - BigInt.objects.create(value=minval) - qs = BigInt.objects.filter(value__lte=minval) - self.assertEqual(qs.count(), 1) - self.assertEqual(qs[0].value, minval) - - def test_types(self): - b = BigInt(value = 0) - self.assertTrue(isinstance(b.value, (int, long))) - b.save() - self.assertTrue(isinstance(b.value, (int, long))) - b = BigInt.objects.all()[0] - self.assertTrue(isinstance(b.value, (int, long))) - - def test_coercing(self): - BigInt.objects.create(value ='10') - b = BigInt.objects.get(value = '10') - self.assertEqual(b.value, 10) - -class TypeCoercionTests(django.test.TestCase): - """ - Test that database lookups can accept the wrong types and convert - them with no error: especially on Postgres 8.3+ which does not do - automatic casting at the DB level. See #10015. - - """ - def test_lookup_integer_in_charfield(self): - self.assertEquals(Post.objects.filter(title=9).count(), 0) - - def test_lookup_integer_in_textfield(self): - self.assertEquals(Post.objects.filter(body=24).count(), 0) - diff --git a/parts/django/tests/regressiontests/model_forms_regress/__init__.py b/parts/django/tests/regressiontests/model_forms_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_forms_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_forms_regress/models.py b/parts/django/tests/regressiontests/model_forms_regress/models.py deleted file mode 100644 index 4f9811a..0000000 --- a/parts/django/tests/regressiontests/model_forms_regress/models.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -from django.db import models -from django.core.exceptions import ValidationError - - -class Person(models.Model): - name = models.CharField(max_length=100) - -class Triple(models.Model): - left = models.IntegerField() - middle = models.IntegerField() - right = models.IntegerField() - - class Meta: - unique_together = (('left', 'middle'), (u'middle', u'right')) - -class FilePathModel(models.Model): - path = models.FilePathField(path=os.path.dirname(__file__), match=".*\.py$", blank=True) - -class Publication(models.Model): - title = models.CharField(max_length=30) - date_published = models.DateField() - - def __unicode__(self): - return self.title - -class Article(models.Model): - headline = models.CharField(max_length=100) - publications = models.ManyToManyField(Publication) - - def __unicode__(self): - return self.headline - -class CustomFileField(models.FileField): - def save_form_data(self, instance, data): - been_here = getattr(self, 'been_saved', False) - assert not been_here, "save_form_data called more than once" - setattr(self, 'been_saved', True) - -class CustomFF(models.Model): - f = CustomFileField(upload_to='unused', blank=True) - -class RealPerson(models.Model): - name = models.CharField(max_length=100) - - def clean(self): - if self.name.lower() == 'anonymous': - raise ValidationError("Please specify a real name.") - -class Author(models.Model): - publication = models.OneToOneField(Publication, null=True, blank=True) - full_name = models.CharField(max_length=255) - -class Author1(models.Model): - publication = models.OneToOneField(Publication, null=False) - full_name = models.CharField(max_length=255) - -class Homepage(models.Model): - url = models.URLField(verify_exists=False) diff --git a/parts/django/tests/regressiontests/model_forms_regress/tests.py b/parts/django/tests/regressiontests/model_forms_regress/tests.py deleted file mode 100644 index 1d0d6ed..0000000 --- a/parts/django/tests/regressiontests/model_forms_regress/tests.py +++ /dev/null @@ -1,311 +0,0 @@ -from datetime import date - -from django import db, forms -from django.conf import settings -from django.forms.models import modelform_factory, ModelChoiceField -from django.test import TestCase - -from models import Person, RealPerson, Triple, FilePathModel, Article, \ - Publication, CustomFF, Author, Author1, Homepage - - -class ModelMultipleChoiceFieldTests(TestCase): - - def setUp(self): - self.old_debug = settings.DEBUG - settings.DEBUG = True - - def tearDown(self): - settings.DEBUG = self.old_debug - - def test_model_multiple_choice_number_of_queries(self): - """ - Test that ModelMultipleChoiceField does O(1) queries instead of - O(n) (#10156). - """ - for i in range(30): - Person.objects.create(name="Person %s" % i) - - db.reset_queries() - f = forms.ModelMultipleChoiceField(queryset=Person.objects.all()) - selected = f.clean([1, 3, 5, 7, 9]) - self.assertEquals(len(db.connection.queries), 1) - - def test_model_multiple_choice_run_validators(self): - """ - Test that ModelMultipleChoiceField run given validators (#14144). - """ - for i in range(30): - Person.objects.create(name="Person %s" % i) - - self._validator_run = False - def my_validator(value): - self._validator_run = True - - f = forms.ModelMultipleChoiceField(queryset=Person.objects.all(), - validators=[my_validator]) - - f.clean([p.pk for p in Person.objects.all()[8:9]]) - self.assertTrue(self._validator_run) - -class TripleForm(forms.ModelForm): - class Meta: - model = Triple - -class UniqueTogetherTests(TestCase): - def test_multiple_field_unique_together(self): - """ - When the same field is involved in multiple unique_together - constraints, we need to make sure we don't remove the data for it - before doing all the validation checking (not just failing after - the first one). - """ - Triple.objects.create(left=1, middle=2, right=3) - - form = TripleForm({'left': '1', 'middle': '2', 'right': '3'}) - self.assertFalse(form.is_valid()) - - form = TripleForm({'left': '1', 'middle': '3', 'right': '1'}) - self.assertTrue(form.is_valid()) - -class TripleFormWithCleanOverride(forms.ModelForm): - class Meta: - model = Triple - - def clean(self): - if not self.cleaned_data['left'] == self.cleaned_data['right']: - raise forms.ValidationError('Left and right should be equal') - return self.cleaned_data - -class OverrideCleanTests(TestCase): - def test_override_clean(self): - """ - Regression for #12596: Calling super from ModelForm.clean() should be - optional. - """ - form = TripleFormWithCleanOverride({'left': 1, 'middle': 2, 'right': 1}) - self.assertTrue(form.is_valid()) - # form.instance.left will be None if the instance was not constructed - # by form.full_clean(). - self.assertEquals(form.instance.left, 1) - -# Regression test for #12960. -# Make sure the cleaned_data returned from ModelForm.clean() is applied to the -# model instance. - -class PublicationForm(forms.ModelForm): - def clean(self): - self.cleaned_data['title'] = self.cleaned_data['title'].upper() - return self.cleaned_data - - class Meta: - model = Publication - -class ModelFormCleanTest(TestCase): - def test_model_form_clean_applies_to_model(self): - data = {'title': 'test', 'date_published': '2010-2-25'} - form = PublicationForm(data) - publication = form.save() - self.assertEqual(publication.title, 'TEST') - -class FPForm(forms.ModelForm): - class Meta: - model = FilePathModel - -class FilePathFieldTests(TestCase): - def test_file_path_field_blank(self): - """ - Regression test for #8842: FilePathField(blank=True) - """ - form = FPForm() - names = [p[1] for p in form['path'].field.choices] - names.sort() - self.assertEqual(names, ['---------', '__init__.py', 'models.py', 'tests.py']) - -class ManyToManyCallableInitialTests(TestCase): - def test_callable(self): - "Regression for #10349: A callable can be provided as the initial value for an m2m field" - - # Set up a callable initial value - def formfield_for_dbfield(db_field, **kwargs): - if db_field.name == 'publications': - kwargs['initial'] = lambda: Publication.objects.all().order_by('date_published')[:2] - return db_field.formfield(**kwargs) - - # Set up some Publications to use as data - Publication(title="First Book", date_published=date(2007,1,1)).save() - Publication(title="Second Book", date_published=date(2008,1,1)).save() - Publication(title="Third Book", date_published=date(2009,1,1)).save() - - # Create a ModelForm, instantiate it, and check that the output is as expected - ModelForm = modelform_factory(Article, formfield_callback=formfield_for_dbfield) - form = ModelForm() - self.assertEquals(form.as_ul(), u"""<li><label for="id_headline">Headline:</label> <input id="id_headline" type="text" name="headline" maxlength="100" /></li> -<li><label for="id_publications">Publications:</label> <select multiple="multiple" name="publications" id="id_publications"> -<option value="1" selected="selected">First Book</option> -<option value="2" selected="selected">Second Book</option> -<option value="3">Third Book</option> -</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li>""") - -class CFFForm(forms.ModelForm): - class Meta: - model = CustomFF - -class CustomFieldSaveTests(TestCase): - def test_save(self): - "Regression for #11149: save_form_data should be called only once" - - # It's enough that the form saves without error -- the custom save routine will - # generate an AssertionError if it is called more than once during save. - form = CFFForm(data = {'f': None}) - form.save() - -class ModelChoiceIteratorTests(TestCase): - def test_len(self): - class Form(forms.ModelForm): - class Meta: - model = Article - fields = ["publications"] - - Publication.objects.create(title="Pravda", - date_published=date(1991, 8, 22)) - f = Form() - self.assertEqual(len(f.fields["publications"].choices), 1) - -class RealPersonForm(forms.ModelForm): - class Meta: - model = RealPerson - -class CustomModelFormSaveMethod(TestCase): - def test_string_message(self): - data = {'name': 'anonymous'} - form = RealPersonForm(data) - self.assertEqual(form.is_valid(), False) - self.assertEqual(form.errors['__all__'], ['Please specify a real name.']) - -class ModelClassTests(TestCase): - def test_no_model_class(self): - class NoModelModelForm(forms.ModelForm): - pass - self.assertRaises(ValueError, NoModelModelForm) - -class OneToOneFieldTests(TestCase): - def test_assignment_of_none(self): - class AuthorForm(forms.ModelForm): - class Meta: - model = Author - fields = ['publication', 'full_name'] - - publication = Publication.objects.create(title="Pravda", - date_published=date(1991, 8, 22)) - author = Author.objects.create(publication=publication, full_name='John Doe') - form = AuthorForm({'publication':u'', 'full_name':'John Doe'}, instance=author) - self.assert_(form.is_valid()) - self.assertEqual(form.cleaned_data['publication'], None) - author = form.save() - # author object returned from form still retains original publication object - # that's why we need to retreive it from database again - new_author = Author.objects.get(pk=author.pk) - self.assertEqual(new_author.publication, None) - - def test_assignment_of_none_null_false(self): - class AuthorForm(forms.ModelForm): - class Meta: - model = Author1 - fields = ['publication', 'full_name'] - - publication = Publication.objects.create(title="Pravda", - date_published=date(1991, 8, 22)) - author = Author1.objects.create(publication=publication, full_name='John Doe') - form = AuthorForm({'publication':u'', 'full_name':'John Doe'}, instance=author) - self.assert_(not form.is_valid()) - - -class ModelChoiceForm(forms.Form): - person = ModelChoiceField(Person.objects.all()) - - -class TestTicket11183(TestCase): - def test_11183(self): - form1 = ModelChoiceForm() - field1 = form1.fields['person'] - # To allow the widget to change the queryset of field1.widget.choices correctly, - # without affecting other forms, the following must hold: - self.assert_(field1 is not ModelChoiceForm.base_fields['person']) - self.assert_(field1.widget.choices.field is field1) - -class HomepageForm(forms.ModelForm): - class Meta: - model = Homepage - -class URLFieldTests(TestCase): - def test_url_on_modelform(self): - "Check basic URL field validation on model forms" - self.assertFalse(HomepageForm({'url': 'foo'}).is_valid()) - self.assertFalse(HomepageForm({'url': 'http://'}).is_valid()) - self.assertFalse(HomepageForm({'url': 'http://example'}).is_valid()) - self.assertFalse(HomepageForm({'url': 'http://example.'}).is_valid()) - self.assertFalse(HomepageForm({'url': 'http://com.'}).is_valid()) - - self.assertTrue(HomepageForm({'url': 'http://localhost'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://example.com'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://www.example.com'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://www.example.com:8000'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://www.example.com/test'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://www.example.com:8000/test'}).is_valid()) - self.assertTrue(HomepageForm({'url': 'http://example.com/foo/bar'}).is_valid()) - - def test_http_prefixing(self): - "If the http:// prefix is omitted on form input, the field adds it again. (Refs #13613)" - form = HomepageForm({'url': 'example.com'}) - form.is_valid() - # self.assertTrue(form.is_valid()) - # self.assertEquals(form.cleaned_data['url'], 'http://example.com/') - - form = HomepageForm({'url': 'example.com/test'}) - form.is_valid() - # self.assertTrue(form.is_valid()) - # self.assertEquals(form.cleaned_data['url'], 'http://example.com/test') - - -class FormFieldCallbackTests(TestCase): - - def test_baseform_with_widgets_in_meta(self): - """Regression for #13095: Using base forms with widgets defined in Meta should not raise errors.""" - widget = forms.Textarea() - - class BaseForm(forms.ModelForm): - class Meta: - model = Person - widgets = {'name': widget} - - Form = modelform_factory(Person, form=BaseForm) - self.assertTrue(Form.base_fields['name'].widget is widget) - - def test_custom_callback(self): - """Test that a custom formfield_callback is used if provided""" - - callback_args = [] - - def callback(db_field, **kwargs): - callback_args.append((db_field, kwargs)) - return db_field.formfield(**kwargs) - - widget = forms.Textarea() - - class BaseForm(forms.ModelForm): - class Meta: - model = Person - widgets = {'name': widget} - - _ = modelform_factory(Person, form=BaseForm, - formfield_callback=callback) - id_field, name_field = Person._meta.fields - - self.assertEqual(callback_args, - [(id_field, {}), (name_field, {'widget': widget})]) - - def test_bad_callback(self): - # A bad callback provided by user still gives an error - self.assertRaises(TypeError, modelform_factory, Person, - formfield_callback='not a function or callable') diff --git a/parts/django/tests/regressiontests/model_formsets_regress/__init__.py b/parts/django/tests/regressiontests/model_formsets_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_formsets_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_formsets_regress/models.py b/parts/django/tests/regressiontests/model_formsets_regress/models.py deleted file mode 100644 index bd12dd6..0000000 --- a/parts/django/tests/regressiontests/model_formsets_regress/models.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.db import models - -class User(models.Model): - username = models.CharField(max_length=12, unique=True) - serial = models.IntegerField() - -class UserSite(models.Model): - user = models.ForeignKey(User, to_field="username") - data = models.IntegerField() - -class Place(models.Model): - name = models.CharField(max_length=50) - -class Restaurant(Place): - pass - -class Manager(models.Model): - retaurant = models.ForeignKey(Restaurant) - name = models.CharField(max_length=50) diff --git a/parts/django/tests/regressiontests/model_formsets_regress/tests.py b/parts/django/tests/regressiontests/model_formsets_regress/tests.py deleted file mode 100644 index ee2a26f..0000000 --- a/parts/django/tests/regressiontests/model_formsets_regress/tests.py +++ /dev/null @@ -1,218 +0,0 @@ -from django import forms -from django.forms.models import modelform_factory, inlineformset_factory, modelformset_factory -from django.test import TestCase - -from models import User, UserSite, Restaurant, Manager - - -class InlineFormsetTests(TestCase): - def test_formset_over_to_field(self): - "A formset over a ForeignKey with a to_field can be saved. Regression for #10243" - Form = modelform_factory(User) - FormSet = inlineformset_factory(User, UserSite) - - # Instantiate the Form and FormSet to prove - # you can create a form with no data - form = Form() - form_set = FormSet(instance=User()) - - # Now create a new User and UserSite instance - data = { - 'serial': u'1', - 'username': u'apollo13', - 'usersite_set-TOTAL_FORMS': u'1', - 'usersite_set-INITIAL_FORMS': u'0', - 'usersite_set-MAX_NUM_FORMS': u'0', - 'usersite_set-0-data': u'10', - 'usersite_set-0-user': u'apollo13' - } - user = User() - form = Form(data) - if form.is_valid(): - user = form.save() - else: - self.fail('Errors found on form:%s' % form_set) - - form_set = FormSet(data, instance=user) - if form_set.is_valid(): - form_set.save() - usersite = UserSite.objects.all().values() - self.assertEqual(usersite[0]['data'], 10) - self.assertEqual(usersite[0]['user_id'], u'apollo13') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - # Now update the UserSite instance - data = { - 'usersite_set-TOTAL_FORMS': u'1', - 'usersite_set-INITIAL_FORMS': u'1', - 'usersite_set-MAX_NUM_FORMS': u'0', - 'usersite_set-0-id': unicode(usersite[0]['id']), - 'usersite_set-0-data': u'11', - 'usersite_set-0-user': u'apollo13' - } - form_set = FormSet(data, instance=user) - if form_set.is_valid(): - form_set.save() - usersite = UserSite.objects.all().values() - self.assertEqual(usersite[0]['data'], 11) - self.assertEqual(usersite[0]['user_id'], u'apollo13') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - # Now add a new UserSite instance - data = { - 'usersite_set-TOTAL_FORMS': u'2', - 'usersite_set-INITIAL_FORMS': u'1', - 'usersite_set-MAX_NUM_FORMS': u'0', - 'usersite_set-0-id': unicode(usersite[0]['id']), - 'usersite_set-0-data': u'11', - 'usersite_set-0-user': u'apollo13', - 'usersite_set-1-data': u'42', - 'usersite_set-1-user': u'apollo13' - } - form_set = FormSet(data, instance=user) - if form_set.is_valid(): - form_set.save() - usersite = UserSite.objects.all().values().order_by('data') - self.assertEqual(usersite[0]['data'], 11) - self.assertEqual(usersite[0]['user_id'], u'apollo13') - self.assertEqual(usersite[1]['data'], 42) - self.assertEqual(usersite[1]['user_id'], u'apollo13') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - def test_formset_over_inherited_model(self): - "A formset over a ForeignKey with a to_field can be saved. Regression for #11120" - Form = modelform_factory(Restaurant) - FormSet = inlineformset_factory(Restaurant, Manager) - - # Instantiate the Form and FormSet to prove - # you can create a form with no data - form = Form() - form_set = FormSet(instance=Restaurant()) - - # Now create a new Restaurant and Manager instance - data = { - 'name': u"Guido's House of Pasta", - 'manager_set-TOTAL_FORMS': u'1', - 'manager_set-INITIAL_FORMS': u'0', - 'manager_set-MAX_NUM_FORMS': u'0', - 'manager_set-0-name': u'Guido Van Rossum' - } - restaurant = User() - form = Form(data) - if form.is_valid(): - restaurant = form.save() - else: - self.fail('Errors found on form:%s' % form_set) - - form_set = FormSet(data, instance=restaurant) - if form_set.is_valid(): - form_set.save() - manager = Manager.objects.all().values() - self.assertEqual(manager[0]['name'], 'Guido Van Rossum') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - # Now update the Manager instance - data = { - 'manager_set-TOTAL_FORMS': u'1', - 'manager_set-INITIAL_FORMS': u'1', - 'manager_set-MAX_NUM_FORMS': u'0', - 'manager_set-0-id': unicode(manager[0]['id']), - 'manager_set-0-name': u'Terry Gilliam' - } - form_set = FormSet(data, instance=restaurant) - if form_set.is_valid(): - form_set.save() - manager = Manager.objects.all().values() - self.assertEqual(manager[0]['name'], 'Terry Gilliam') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - # Now add a new Manager instance - data = { - 'manager_set-TOTAL_FORMS': u'2', - 'manager_set-INITIAL_FORMS': u'1', - 'manager_set-MAX_NUM_FORMS': u'0', - 'manager_set-0-id': unicode(manager[0]['id']), - 'manager_set-0-name': u'Terry Gilliam', - 'manager_set-1-name': u'John Cleese' - } - form_set = FormSet(data, instance=restaurant) - if form_set.is_valid(): - form_set.save() - manager = Manager.objects.all().values().order_by('name') - self.assertEqual(manager[0]['name'], 'John Cleese') - self.assertEqual(manager[1]['name'], 'Terry Gilliam') - else: - self.fail('Errors found on formset:%s' % form_set.errors) - - def test_formset_with_none_instance(self): - "A formset with instance=None can be created. Regression for #11872" - Form = modelform_factory(User) - FormSet = inlineformset_factory(User, UserSite) - - # Instantiate the Form and FormSet to prove - # you can create a formset with an instance of None - form = Form(instance=None) - formset = FormSet(instance=None) - - -class CustomWidget(forms.CharField): - pass - - -class UserSiteForm(forms.ModelForm): - class Meta: - model = UserSite - widgets = {'data': CustomWidget} - - -class Callback(object): - - def __init__(self): - self.log = [] - - def __call__(self, db_field, **kwargs): - self.log.append((db_field, kwargs)) - return db_field.formfield(**kwargs) - - -class FormfieldCallbackTests(TestCase): - """ - Regression for #13095: Using base forms with widgets - defined in Meta should not raise errors. - """ - - def test_inlineformset_factory_default(self): - Formset = inlineformset_factory(User, UserSite, form=UserSiteForm) - form = Formset({}).forms[0] - self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) - - def test_modelformset_factory_default(self): - Formset = modelformset_factory(UserSite, form=UserSiteForm) - form = Formset({}).forms[0] - self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) - - def assertCallbackCalled(self, callback): - id_field, user_field, data_field = UserSite._meta.fields - expected_log = [ - (id_field, {}), - (user_field, {}), - (data_field, {'widget': CustomWidget}), - ] - self.assertEqual(callback.log, expected_log) - - def test_inlineformset_custom_callback(self): - callback = Callback() - inlineformset_factory(User, UserSite, form=UserSiteForm, - formfield_callback=callback) - self.assertCallbackCalled(callback) - - def test_modelformset_custom_callback(self): - callback = Callback() - modelformset_factory(UserSite, form=UserSiteForm, - formfield_callback=callback) - self.assertCallbackCalled(callback) diff --git a/parts/django/tests/regressiontests/model_inheritance_regress/__init__.py b/parts/django/tests/regressiontests/model_inheritance_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_inheritance_regress/models.py b/parts/django/tests/regressiontests/model_inheritance_regress/models.py deleted file mode 100644 index 787f163..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_regress/models.py +++ /dev/null @@ -1,148 +0,0 @@ -import datetime - -from django.db import models - -class Place(models.Model): - name = models.CharField(max_length=50) - address = models.CharField(max_length=80) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return u"%s the place" % self.name - -class Restaurant(Place): - serves_hot_dogs = models.BooleanField() - serves_pizza = models.BooleanField() - - def __unicode__(self): - return u"%s the restaurant" % self.name - -class ItalianRestaurant(Restaurant): - serves_gnocchi = models.BooleanField() - - def __unicode__(self): - return u"%s the italian restaurant" % self.name - -class ParkingLot(Place): - # An explicit link to the parent (we can control the attribute name). - parent = models.OneToOneField(Place, primary_key=True, parent_link=True) - capacity = models.IntegerField() - - def __unicode__(self): - return u"%s the parking lot" % self.name - -class ParkingLot2(Place): - # In lieu of any other connector, an existing OneToOneField will be - # promoted to the primary key. - parent = models.OneToOneField(Place) - -class ParkingLot3(Place): - # The parent_link connector need not be the pk on the model. - primary_key = models.AutoField(primary_key=True) - parent = models.OneToOneField(Place, parent_link=True) - -class Supplier(models.Model): - restaurant = models.ForeignKey(Restaurant) - -class Wholesaler(Supplier): - retailer = models.ForeignKey(Supplier,related_name='wholesale_supplier') - -class Parent(models.Model): - created = models.DateTimeField(default=datetime.datetime.now) - -class Child(Parent): - name = models.CharField(max_length=10) - -class SelfRefParent(models.Model): - parent_data = models.IntegerField() - self_data = models.ForeignKey('self', null=True) - -class SelfRefChild(SelfRefParent): - child_data = models.IntegerField() - -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateTimeField() - class Meta: - ordering = ('-pub_date', 'headline') - - def __unicode__(self): - return self.headline - -class ArticleWithAuthor(Article): - author = models.CharField(max_length=100) - -class M2MBase(models.Model): - articles = models.ManyToManyField(Article) - -class M2MChild(M2MBase): - name = models.CharField(max_length=50) - -class Evaluation(Article): - quality = models.IntegerField() - - class Meta: - abstract = True - -class QualityControl(Evaluation): - assignee = models.CharField(max_length=50) - -class BaseM(models.Model): - base_name = models.CharField(max_length=100) - - def __unicode__(self): - return self.base_name - -class DerivedM(BaseM): - customPK = models.IntegerField(primary_key=True) - derived_name = models.CharField(max_length=100) - - def __unicode__(self): - return "PK = %d, base_name = %s, derived_name = %s" \ - % (self.customPK, self.base_name, self.derived_name) - -class AuditBase(models.Model): - planned_date = models.DateField() - - class Meta: - abstract = True - verbose_name_plural = u'Audits' - -class CertificationAudit(AuditBase): - class Meta(AuditBase.Meta): - abstract = True - -class InternalCertificationAudit(CertificationAudit): - auditing_dept = models.CharField(max_length=20) - -# Check that abstract classes don't get m2m tables autocreated. -class Person(models.Model): - name = models.CharField(max_length=100) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return self.name - -class AbstractEvent(models.Model): - name = models.CharField(max_length=100) - attendees = models.ManyToManyField(Person, related_name="%(class)s_set") - - class Meta: - abstract = True - ordering = ('name',) - - def __unicode__(self): - return self.name - -class BirthdayParty(AbstractEvent): - pass - -class BachelorParty(AbstractEvent): - pass - -class MessyBachelorParty(BachelorParty): - pass diff --git a/parts/django/tests/regressiontests/model_inheritance_regress/tests.py b/parts/django/tests/regressiontests/model_inheritance_regress/tests.py deleted file mode 100644 index dac2cb5..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_regress/tests.py +++ /dev/null @@ -1,388 +0,0 @@ -""" -Regression tests for Model inheritance behaviour. -""" - -import datetime -from operator import attrgetter - -from django.test import TestCase - -from models import (Place, Restaurant, ItalianRestaurant, ParkingLot, - ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent, - SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM, - Person, BirthdayParty, BachelorParty, MessyBachelorParty, - InternalCertificationAudit) - - -class ModelInheritanceTest(TestCase): - def test_model_inheritance(self): - # Regression for #7350, #7202 - # Check that when you create a Parent object with a specific reference - # to an existent child instance, saving the Parent doesn't duplicate - # the child. This behaviour is only activated during a raw save - it - # is mostly relevant to deserialization, but any sort of CORBA style - # 'narrow()' API would require a similar approach. - - # Create a child-parent-grandparent chain - place1 = Place( - name="Guido's House of Pasta", - address='944 W. Fullerton') - place1.save_base(raw=True) - restaurant = Restaurant( - place_ptr=place1, - serves_hot_dogs=True, - serves_pizza=False) - restaurant.save_base(raw=True) - italian_restaurant = ItalianRestaurant( - restaurant_ptr=restaurant, - serves_gnocchi=True) - italian_restaurant.save_base(raw=True) - - # Create a child-parent chain with an explicit parent link - place2 = Place(name='Main St', address='111 Main St') - place2.save_base(raw=True) - park = ParkingLot(parent=place2, capacity=100) - park.save_base(raw=True) - - # Check that no extra parent objects have been created. - places = list(Place.objects.all()) - self.assertEqual(places, [place1, place2]) - - dicts = list(Restaurant.objects.values('name','serves_hot_dogs')) - self.assertEqual(dicts, [{ - 'name': u"Guido's House of Pasta", - 'serves_hot_dogs': True - }]) - - dicts = list(ItalianRestaurant.objects.values( - 'name','serves_hot_dogs','serves_gnocchi')) - self.assertEqual(dicts, [{ - 'name': u"Guido's House of Pasta", - 'serves_gnocchi': True, - 'serves_hot_dogs': True, - }]) - - dicts = list(ParkingLot.objects.values('name','capacity')) - self.assertEqual(dicts, [{ - 'capacity': 100, - 'name': u'Main St', - }]) - - # You can also update objects when using a raw save. - place1.name = "Guido's All New House of Pasta" - place1.save_base(raw=True) - - restaurant.serves_hot_dogs = False - restaurant.save_base(raw=True) - - italian_restaurant.serves_gnocchi = False - italian_restaurant.save_base(raw=True) - - place2.name='Derelict lot' - place2.save_base(raw=True) - - park.capacity = 50 - park.save_base(raw=True) - - # No extra parent objects after an update, either. - places = list(Place.objects.all()) - self.assertEqual(places, [place2, place1]) - self.assertEqual(places[0].name, 'Derelict lot') - self.assertEqual(places[1].name, "Guido's All New House of Pasta") - - dicts = list(Restaurant.objects.values('name','serves_hot_dogs')) - self.assertEqual(dicts, [{ - 'name': u"Guido's All New House of Pasta", - 'serves_hot_dogs': False, - }]) - - dicts = list(ItalianRestaurant.objects.values( - 'name', 'serves_hot_dogs', 'serves_gnocchi')) - self.assertEqual(dicts, [{ - 'name': u"Guido's All New House of Pasta", - 'serves_gnocchi': False, - 'serves_hot_dogs': False, - }]) - - dicts = list(ParkingLot.objects.values('name','capacity')) - self.assertEqual(dicts, [{ - 'capacity': 50, - 'name': u'Derelict lot', - }]) - - # If you try to raw_save a parent attribute onto a child object, - # the attribute will be ignored. - - italian_restaurant.name = "Lorenzo's Pasta Hut" - italian_restaurant.save_base(raw=True) - - # Note that the name has not changed - # - name is an attribute of Place, not ItalianRestaurant - dicts = list(ItalianRestaurant.objects.values( - 'name','serves_hot_dogs','serves_gnocchi')) - self.assertEqual(dicts, [{ - 'name': u"Guido's All New House of Pasta", - 'serves_gnocchi': False, - 'serves_hot_dogs': False, - }]) - - def test_issue_7105(self): - # Regressions tests for #7105: dates() queries should be able to use - # fields from the parent model as easily as the child. - obj = Child.objects.create( - name='child', - created=datetime.datetime(2008, 6, 26, 17, 0, 0)) - dates = list(Child.objects.dates('created', 'month')) - self.assertEqual(dates, [datetime.datetime(2008, 6, 1, 0, 0)]) - - def test_issue_7276(self): - # Regression test for #7276: calling delete() on a model with - # multi-table inheritance should delete the associated rows from any - # ancestor tables, as well as any descendent objects. - place1 = Place( - name="Guido's House of Pasta", - address='944 W. Fullerton') - place1.save_base(raw=True) - restaurant = Restaurant( - place_ptr=place1, - serves_hot_dogs=True, - serves_pizza=False) - restaurant.save_base(raw=True) - italian_restaurant = ItalianRestaurant( - restaurant_ptr=restaurant, - serves_gnocchi=True) - italian_restaurant.save_base(raw=True) - - ident = ItalianRestaurant.objects.all()[0].id - self.assertEqual(Place.objects.get(pk=ident), place1) - xx = Restaurant.objects.create( - name='a', - address='xx', - serves_hot_dogs=True, - serves_pizza=False) - - # This should delete both Restuarants, plus the related places, plus - # the ItalianRestaurant. - Restaurant.objects.all().delete() - - self.assertRaises( - Place.DoesNotExist, - Place.objects.get, - pk=ident) - self.assertRaises( - ItalianRestaurant.DoesNotExist, - ItalianRestaurant.objects.get, - pk=ident) - - def test_issue_6755(self): - """ - Regression test for #6755 - """ - r = Restaurant(serves_pizza=False) - r.save() - self.assertEqual(r.id, r.place_ptr_id) - orig_id = r.id - r = Restaurant(place_ptr_id=orig_id, serves_pizza=True) - r.save() - self.assertEqual(r.id, orig_id) - self.assertEqual(r.id, r.place_ptr_id) - - def test_issue_7488(self): - # Regression test for #7488. This looks a little crazy, but it's the - # equivalent of what the admin interface has to do for the edit-inline - # case. - suppliers = Supplier.objects.filter( - restaurant=Restaurant(name='xx', address='yy')) - suppliers = list(suppliers) - self.assertEqual(suppliers, []) - - def test_issue_11764(self): - """ - Regression test for #11764 - """ - wholesalers = list(Wholesaler.objects.all().select_related()) - self.assertEqual(wholesalers, []) - - def test_issue_7853(self): - """ - Regression test for #7853 - If the parent class has a self-referential link, make sure that any - updates to that link via the child update the right table. - """ - obj = SelfRefChild.objects.create(child_data=37, parent_data=42) - obj.delete() - - def test_get_next_previous_by_date(self): - """ - Regression tests for #8076 - get_(next/previous)_by_date should work - """ - c1 = ArticleWithAuthor( - headline='ArticleWithAuthor 1', - author="Person 1", - pub_date=datetime.datetime(2005, 8, 1, 3, 0)) - c1.save() - c2 = ArticleWithAuthor( - headline='ArticleWithAuthor 2', - author="Person 2", - pub_date=datetime.datetime(2005, 8, 1, 10, 0)) - c2.save() - c3 = ArticleWithAuthor( - headline='ArticleWithAuthor 3', - author="Person 3", - pub_date=datetime.datetime(2005, 8, 2)) - c3.save() - - self.assertEqual(c1.get_next_by_pub_date(), c2) - self.assertEqual(c2.get_next_by_pub_date(), c3) - self.assertRaises( - ArticleWithAuthor.DoesNotExist, - c3.get_next_by_pub_date) - self.assertEqual(c3.get_previous_by_pub_date(), c2) - self.assertEqual(c2.get_previous_by_pub_date(), c1) - self.assertRaises( - ArticleWithAuthor.DoesNotExist, - c1.get_previous_by_pub_date) - - def test_inherited_fields(self): - """ - Regression test for #8825 and #9390 - Make sure all inherited fields (esp. m2m fields, in this case) appear - on the child class. - """ - m2mchildren = list(M2MChild.objects.filter(articles__isnull=False)) - self.assertEqual(m2mchildren, []) - - # Ordering should not include any database column more than once (this - # is most likely to ocurr naturally with model inheritance, so we - # check it here). Regression test for #9390. This necessarily pokes at - # the SQL string for the query, since the duplicate problems are only - # apparent at that late stage. - qs = ArticleWithAuthor.objects.order_by('pub_date', 'pk') - sql = qs.query.get_compiler(qs.db).as_sql()[0] - fragment = sql[sql.find('ORDER BY'):] - pos = fragment.find('pub_date') - self.assertEqual(fragment.find('pub_date', pos + 1), -1) - - def test_queryset_update_on_parent_model(self): - """ - Regression test for #10362 - It is possible to call update() and only change a field in - an ancestor model. - """ - article = ArticleWithAuthor.objects.create( - author="fred", - headline="Hey there!", - pub_date=datetime.datetime(2009, 3, 1, 8, 0, 0)) - update = ArticleWithAuthor.objects.filter( - author="fred").update(headline="Oh, no!") - self.assertEqual(update, 1) - update = ArticleWithAuthor.objects.filter( - pk=article.pk).update(headline="Oh, no!") - self.assertEqual(update, 1) - - derivedm1 = DerivedM.objects.create( - customPK=44, - base_name="b1", - derived_name="d1") - self.assertEqual(derivedm1.customPK, 44) - self.assertEqual(derivedm1.base_name, 'b1') - self.assertEqual(derivedm1.derived_name, 'd1') - derivedms = list(DerivedM.objects.all()) - self.assertEqual(derivedms, [derivedm1]) - - def test_use_explicit_o2o_to_parent_as_pk(self): - """ - Regression tests for #10406 - If there's a one-to-one link between a child model and the parent and - no explicit pk declared, we can use the one-to-one link as the pk on - the child. - """ - self.assertEqual(ParkingLot2._meta.pk.name, "parent") - - # However, the connector from child to parent need not be the pk on - # the child at all. - self.assertEqual(ParkingLot3._meta.pk.name, "primary_key") - # the child->parent link - self.assertEqual( - ParkingLot3._meta.get_ancestor_link(Place).name, - "parent") - - def test_all_fields_from_abstract_base_class(self): - """ - Regression tests for #7588 - """ - # All fields from an ABC, including those inherited non-abstractly - # should be available on child classes (#7588). Creating this instance - # should work without error. - QualityControl.objects.create( - headline="Problems in Django", - pub_date=datetime.datetime.now(), - quality=10, - assignee="adrian") - - def test_abstract_base_class_m2m_relation_inheritance(self): - # Check that many-to-many relations defined on an abstract base class - # are correctly inherited (and created) on the child class. - p1 = Person.objects.create(name='Alice') - p2 = Person.objects.create(name='Bob') - p3 = Person.objects.create(name='Carol') - p4 = Person.objects.create(name='Dave') - - birthday = BirthdayParty.objects.create( - name='Birthday party for Alice') - birthday.attendees = [p1, p3] - - bachelor = BachelorParty.objects.create(name='Bachelor party for Bob') - bachelor.attendees = [p2, p4] - - parties = list(p1.birthdayparty_set.all()) - self.assertEqual(parties, [birthday]) - - parties = list(p1.bachelorparty_set.all()) - self.assertEqual(parties, []) - - parties = list(p2.bachelorparty_set.all()) - self.assertEqual(parties, [bachelor]) - - # Check that a subclass of a subclass of an abstract model doesn't get - # it's own accessor. - self.assertFalse(hasattr(p2, 'messybachelorparty_set')) - - # ... but it does inherit the m2m from it's parent - messy = MessyBachelorParty.objects.create( - name='Bachelor party for Dave') - messy.attendees = [p4] - messy_parent = messy.bachelorparty_ptr - - parties = list(p4.bachelorparty_set.all()) - self.assertEqual(parties, [bachelor, messy_parent]) - - def test_11369(self): - """ - verbose_name_plural correctly inherited from ABC if inheritance chain - includes an abstract model. - """ - # Regression test for #11369: verbose_name_plural should be inherited - # from an ABC even when there are one or more intermediate - # abstract models in the inheritance chain, for consistency with - # verbose_name. - self.assertEquals( - InternalCertificationAudit._meta.verbose_name_plural, - u'Audits' - ) - - def test_inherited_nullable_exclude(self): - obj = SelfRefChild.objects.create(child_data=37, parent_data=42) - self.assertQuerysetEqual( - SelfRefParent.objects.exclude(self_data=72), [ - obj.pk - ], - attrgetter("pk") - ) - self.assertQuerysetEqual( - SelfRefChild.objects.exclude(self_data=72), [ - obj.pk - ], - attrgetter("pk") - ) diff --git a/parts/django/tests/regressiontests/model_inheritance_select_related/__init__.py b/parts/django/tests/regressiontests/model_inheritance_select_related/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_select_related/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_inheritance_select_related/models.py b/parts/django/tests/regressiontests/model_inheritance_select_related/models.py deleted file mode 100644 index 5851e46..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_select_related/models.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -Regression tests for the interaction between model inheritance and -select_related(). -""" - -from django.db import models - -class Place(models.Model): - name = models.CharField(max_length=50) - - class Meta: - ordering = ('name',) - - def __unicode__(self): - return u"%s the place" % self.name - -class Restaurant(Place): - serves_sushi = models.BooleanField() - serves_steak = models.BooleanField() - - def __unicode__(self): - return u"%s the restaurant" % self.name - -class Person(models.Model): - name = models.CharField(max_length=50) - favorite_restaurant = models.ForeignKey(Restaurant) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/regressiontests/model_inheritance_select_related/tests.py b/parts/django/tests/regressiontests/model_inheritance_select_related/tests.py deleted file mode 100644 index e1ed609..0000000 --- a/parts/django/tests/regressiontests/model_inheritance_select_related/tests.py +++ /dev/null @@ -1,29 +0,0 @@ -from operator import attrgetter - -from django.test import TestCase - -from models import Restaurant, Person - - -class ModelInheritanceSelectRelatedTests(TestCase): - def test_inherited_select_related(self): - # Regression test for #7246 - r1 = Restaurant.objects.create( - name="Nobu", serves_sushi=True, serves_steak=False - ) - r2 = Restaurant.objects.create( - name="Craft", serves_sushi=False, serves_steak=True - ) - p1 = Person.objects.create(name="John", favorite_restaurant=r1) - p2 = Person.objects.create(name="Jane", favorite_restaurant=r2) - - self.assertQuerysetEqual( - Person.objects.order_by("name").select_related(), [ - "Jane", - "John", - ], - attrgetter("name") - ) - - jane = Person.objects.order_by("name").select_related("favorite_restaurant")[0] - self.assertEqual(jane.favorite_restaurant.name, "Craft") diff --git a/parts/django/tests/regressiontests/model_regress/__init__.py b/parts/django/tests/regressiontests/model_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/model_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/model_regress/models.py b/parts/django/tests/regressiontests/model_regress/models.py deleted file mode 100644 index f30b3ee..0000000 --- a/parts/django/tests/regressiontests/model_regress/models.py +++ /dev/null @@ -1,59 +0,0 @@ -# coding: utf-8 -from django.db import models - - -CHOICES = ( - (1, 'first'), - (2, 'second'), -) - -class Article(models.Model): - headline = models.CharField(max_length=100, default='Default headline') - pub_date = models.DateTimeField() - status = models.IntegerField(blank=True, null=True, choices=CHOICES) - misc_data = models.CharField(max_length=100, blank=True) - article_text = models.TextField() - - 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 - -class Movie(models.Model): - #5218: Test models with non-default primary keys / AutoFields - movie_id = models.AutoField(primary_key=True) - name = models.CharField(max_length=60) - -class Party(models.Model): - when = models.DateField(null=True) - -class Event(models.Model): - when = models.DateTimeField() - -class Department(models.Model): - id = models.PositiveIntegerField(primary_key=True) - name = models.CharField(max_length=200) - - def __unicode__(self): - return self.name - -class Worker(models.Model): - department = models.ForeignKey(Department) - name = models.CharField(max_length=200) - - def __unicode__(self): - return self.name - -class BrokenUnicodeMethod(models.Model): - name = models.CharField(max_length=7) - - def __unicode__(self): - # Intentionally broken (trying to insert a unicode value into a str - # object). - return 'Názov: %s' % self.name - -class NonAutoPK(models.Model): - name = models.CharField(max_length=10, primary_key=True) diff --git a/parts/django/tests/regressiontests/model_regress/tests.py b/parts/django/tests/regressiontests/model_regress/tests.py deleted file mode 100644 index 8009839..0000000 --- a/parts/django/tests/regressiontests/model_regress/tests.py +++ /dev/null @@ -1,175 +0,0 @@ -import datetime -from operator import attrgetter - -from django.conf import settings -from django.core.exceptions import ValidationError -from django.db import DEFAULT_DB_ALIAS -from django.test import TestCase -from django.utils import tzinfo - -from models import (Worker, Article, Party, Event, Department, - BrokenUnicodeMethod, NonAutoPK) - - - -class ModelTests(TestCase): - # The bug is that the following queries would raise: - # "TypeError: Related Field has invalid lookup: gte" - def test_related_gte_lookup(self): - """ - Regression test for #10153: foreign key __gte lookups. - """ - Worker.objects.filter(department__gte=0) - - def test_related_lte_lookup(self): - """ - Regression test for #10153: foreign key __lte lookups. - """ - Worker.objects.filter(department__lte=0) - - def test_empty_choice(self): - # NOTE: Part of the regression test here is merely parsing the model - # declaration. The verbose_name, in particular, did not always work. - a = Article.objects.create( - headline="Look at me!", pub_date=datetime.datetime.now() - ) - # An empty choice field should return None for the display name. - self.assertEqual(a.get_status_display(), None) - - # Empty strings should be returned as Unicode - a = Article.objects.get(pk=a.pk) - self.assertEqual(a.misc_data, u'') - self.assertEqual(type(a.misc_data), unicode) - - def test_long_textfield(self): - # TextFields can hold more than 4000 characters (this was broken in - # Oracle). - a = Article.objects.create( - headline="Really, really big", - pub_date=datetime.datetime.now(), - article_text = "ABCDE" * 1000 - ) - a = Article.objects.get(pk=a.pk) - self.assertEqual - (len(a.article_text), 5000) - - def test_date_lookup(self): - # Regression test for #659 - Party.objects.create(when=datetime.datetime(1999, 12, 31)) - Party.objects.create(when=datetime.datetime(1998, 12, 31)) - Party.objects.create(when=datetime.datetime(1999, 1, 1)) - self.assertQuerysetEqual( - Party.objects.filter(when__month=2), [] - ) - self.assertQuerysetEqual( - Party.objects.filter(when__month=1), [ - datetime.date(1999, 1, 1) - ], - attrgetter("when") - ) - self.assertQuerysetEqual( - Party.objects.filter(when__month=12), [ - datetime.date(1999, 12, 31), - datetime.date(1998, 12, 31), - ], - attrgetter("when") - ) - self.assertQuerysetEqual( - Party.objects.filter(when__year=1998), [ - datetime.date(1998, 12, 31), - ], - attrgetter("when") - ) - # Regression test for #8510 - self.assertQuerysetEqual( - Party.objects.filter(when__day="31"), [ - datetime.date(1999, 12, 31), - datetime.date(1998, 12, 31), - ], - attrgetter("when") - ) - self.assertQuerysetEqual( - Party.objects.filter(when__month="12"), [ - datetime.date(1999, 12, 31), - datetime.date(1998, 12, 31), - ], - attrgetter("when") - ) - self.assertQuerysetEqual( - Party.objects.filter(when__year="1998"), [ - datetime.date(1998, 12, 31), - ], - attrgetter("when") - ) - - def test_date_filter_null(self): - # Date filtering was failing with NULL date values in SQLite - # (regression test for #3501, amongst other things). - Party.objects.create(when=datetime.datetime(1999, 1, 1)) - Party.objects.create() - p = Party.objects.filter(when__month=1)[0] - self.assertEqual(p.when, datetime.date(1999, 1, 1)) - self.assertQuerysetEqual( - Party.objects.filter(pk=p.pk).dates("when", "month"), [ - 1 - ], - attrgetter("month") - ) - - def test_get_next_prev_by_field(self): - # Check that get_next_by_FIELD and get_previous_by_FIELD don't crash - # when we have usecs values stored on the database - # - # It crashed after the Field.get_db_prep_* refactor, because on most - # backends DateTimeFields supports usecs, but DateTimeField.to_python - # didn't recognize them. (Note that - # Model._get_next_or_previous_by_FIELD coerces values to strings) - Event.objects.create(when=datetime.datetime(2000, 1, 1, 16, 0, 0)) - Event.objects.create(when=datetime.datetime(2000, 1, 1, 6, 1, 1)) - Event.objects.create(when=datetime.datetime(2000, 1, 1, 13, 1, 1)) - e = Event.objects.create(when=datetime.datetime(2000, 1, 1, 12, 0, 20, 24)) - - self.assertEqual( - e.get_next_by_when().when, datetime.datetime(2000, 1, 1, 13, 1, 1) - ) - self.assertEqual( - e.get_previous_by_when().when, datetime.datetime(2000, 1, 1, 6, 1, 1) - ) - - def test_primary_key_foreign_key_types(self): - # Check Department and Worker (non-default PK type) - d = Department.objects.create(id=10, name="IT") - w = Worker.objects.create(department=d, name="Full-time") - self.assertEqual(unicode(w), "Full-time") - - def test_broken_unicode(self): - # Models with broken unicode methods should still have a printable repr - b = BrokenUnicodeMethod.objects.create(name="Jerry") - self.assertEqual(repr(b), "<BrokenUnicodeMethod: [Bad Unicode data]>") - - if settings.DATABASES[DEFAULT_DB_ALIAS]["ENGINE"] not in [ - "django.db.backends.mysql", - "django.db.backends.oracle" - ]: - def test_timezones(self): - # Saving an updating with timezone-aware datetime Python objects. - # Regression test for #10443. - # The idea is that all these creations and saving should work - # without crashing. It's not rocket science. - dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(600)) - dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=tzinfo.FixedOffset(600)) - obj = Article.objects.create( - headline="A headline", pub_date=dt1, article_text="foo" - ) - obj.pub_date = dt2 - obj.save() - self.assertEqual( - Article.objects.filter(headline="A headline").update(pub_date=dt1), - 1 - ) - -class ModelValidationTest(TestCase): - def test_pk_validation(self): - one = NonAutoPK.objects.create(name="one") - again = NonAutoPK(name="one") - self.assertRaises(ValidationError, again.validate_unique) diff --git a/parts/django/tests/regressiontests/modeladmin/__init__.py b/parts/django/tests/regressiontests/modeladmin/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/modeladmin/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/modeladmin/models.py b/parts/django/tests/regressiontests/modeladmin/models.py deleted file mode 100644 index 20dfe2c..0000000 --- a/parts/django/tests/regressiontests/modeladmin/models.py +++ /dev/null @@ -1,36 +0,0 @@ -# coding: utf-8 -from datetime import date - -from django.db import models -from django.contrib.auth.models import User - -class Band(models.Model): - name = models.CharField(max_length=100) - bio = models.TextField() - sign_date = models.DateField() - - def __unicode__(self): - return self.name - -class Concert(models.Model): - main_band = models.ForeignKey(Band, related_name='main_concerts') - opening_band = models.ForeignKey(Band, related_name='opening_concerts', - blank=True) - day = models.CharField(max_length=3, choices=((1, 'Fri'), (2, 'Sat'))) - transport = models.CharField(max_length=100, choices=( - (1, 'Plane'), - (2, 'Train'), - (3, 'Bus') - ), blank=True) - -class ValidationTestModel(models.Model): - name = models.CharField(max_length=100) - slug = models.SlugField() - users = models.ManyToManyField(User) - state = models.CharField(max_length=2, choices=(("CO", "Colorado"), ("WA", "Washington"))) - is_active = models.BooleanField() - pub_date = models.DateTimeField() - band = models.ForeignKey(Band) - -class ValidationTestInlineModel(models.Model): - parent = models.ForeignKey(ValidationTestModel) diff --git a/parts/django/tests/regressiontests/modeladmin/tests.py b/parts/django/tests/regressiontests/modeladmin/tests.py deleted file mode 100644 index b13a0ec..0000000 --- a/parts/django/tests/regressiontests/modeladmin/tests.py +++ /dev/null @@ -1,1226 +0,0 @@ -from datetime import date -import unittest - -from django import forms -from django.conf import settings -from django.contrib.admin.options import ModelAdmin, TabularInline, \ - HORIZONTAL, VERTICAL -from django.contrib.admin.sites import AdminSite -from django.contrib.admin.validation import validate -from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect -from django.core.exceptions import ImproperlyConfigured -from django.forms.models import BaseModelFormSet -from django.forms.widgets import Select -from django.test import TestCase - -from models import Band, Concert, ValidationTestModel, \ - ValidationTestInlineModel - - -# None of the following tests really depend on the content of the request, -# so we'll just pass in None. -request = None - - -class ModelAdminTests(TestCase): - - def setUp(self): - self.band = Band.objects.create( - name='The Doors', - bio='', - sign_date=date(1965, 1, 1), - ) - self.site = AdminSite() - - # form/fields/fieldsets interaction ############################## - - def test_default_fields(self): - ma = ModelAdmin(Band, self.site) - - self.assertEquals(ma.get_form(request).base_fields.keys(), - ['name', 'bio', 'sign_date']) - - def test_default_fieldsets(self): - # fieldsets_add and fieldsets_change should return a special data structure that - # is used in the templates. They should generate the "right thing" whether we - # have specified a custom form, the fields argument, or nothing at all. - # - # Here's the default case. There are no custom form_add/form_change methods, - # no fields argument, and no fieldsets argument. - ma = ModelAdmin(Band, self.site) - self.assertEqual(ma.get_fieldsets(request), - [(None, {'fields': ['name', 'bio', 'sign_date']})]) - - self.assertEqual(ma.get_fieldsets(request, self.band), - [(None, {'fields': ['name', 'bio', 'sign_date']})]) - - def test_field_arguments(self): - # If we specify the fields argument, fieldsets_add and fielsets_change should - # just stick the fields into a formsets structure and return it. - class BandAdmin(ModelAdmin): - fields = ['name'] - - ma = BandAdmin(Band, self.site) - - self.assertEqual( ma.get_fieldsets(request), - [(None, {'fields': ['name']})]) - - self.assertEqual(ma.get_fieldsets(request, self.band), - [(None, {'fields': ['name']})]) - - def test_field_arguments_restricted_on_form(self): - # If we specify fields or fieldsets, it should exclude fields on the Form class - # to the fields specified. This may cause errors to be raised in the db layer if - # required model fields arent in fields/fieldsets, but that's preferable to - # ghost errors where you have a field in your Form class that isn't being - # displayed because you forgot to add it to fields/fieldsets - - # Using `fields`. - class BandAdmin(ModelAdmin): - fields = ['name'] - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), ['name']) - self.assertEqual(ma.get_form(request, self.band).base_fields.keys(), - ['name']) - - # Using `fieldsets`. - class BandAdmin(ModelAdmin): - fieldsets = [(None, {'fields': ['name']})] - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), ['name']) - self.assertEqual(ma.get_form(request, self.band).base_fields.keys(), - ['name']) - - # Using `exclude`. - class BandAdmin(ModelAdmin): - exclude = ['bio'] - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['name', 'sign_date']) - - # You can also pass a tuple to `exclude`. - class BandAdmin(ModelAdmin): - exclude = ('bio',) - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['name', 'sign_date']) - - # Using `fields` and `exclude`. - class BandAdmin(ModelAdmin): - fields = ['name', 'bio'] - exclude = ['bio'] - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['name']) - - def test_custom_form_validation(self): - # If we specify a form, it should use it allowing custom validation to work - # properly. This won't, however, break any of the admin widgets or media. - - class AdminBandForm(forms.ModelForm): - delete = forms.BooleanField() - - class Meta: - model = Band - - class BandAdmin(ModelAdmin): - form = AdminBandForm - - ma = BandAdmin(Band, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['name', 'bio', 'sign_date', 'delete']) - - self.assertEqual( - type(ma.get_form(request).base_fields['sign_date'].widget), - AdminDateWidget) - - def test_queryset_override(self): - # If we need to override the queryset of a ModelChoiceField in our custom form - # make sure that RelatedFieldWidgetWrapper doesn't mess that up. - - band2 = Band(name='The Beatles', bio='', sign_date=date(1962, 1, 1)) - band2.save() - - class ConcertAdmin(ModelAdmin): - pass - ma = ConcertAdmin(Concert, self.site) - form = ma.get_form(request)() - - self.assertEqual(str(form["main_band"]), - '<select name="main_band" id="id_main_band">\n' - '<option value="" selected="selected">---------</option>\n' - '<option value="%d">The Doors</option>\n' - '<option value="%d">The Beatles</option>\n' - '</select>' % (self.band.id, band2.id)) - - class AdminConcertForm(forms.ModelForm): - class Meta: - model = Concert - - def __init__(self, *args, **kwargs): - super(AdminConcertForm, self).__init__(*args, **kwargs) - self.fields["main_band"].queryset = Band.objects.filter(name='The Doors') - - class ConcertAdmin(ModelAdmin): - form = AdminConcertForm - - ma = ConcertAdmin(Concert, self.site) - form = ma.get_form(request)() - - self.assertEqual(str(form["main_band"]), - '<select name="main_band" id="id_main_band">\n' - '<option value="" selected="selected">---------</option>\n' - '<option value="%d">The Doors</option>\n' - '</select>' % self.band.id) - - # radio_fields behavior ########################################### - - def test_default_foreign_key_widget(self): - # First, without any radio_fields specified, the widgets for ForeignKey - # and fields with choices specified ought to be a basic Select widget. - # ForeignKey widgets in the admin are wrapped with RelatedFieldWidgetWrapper so - # they need to be handled properly when type checking. For Select fields, all of - # the choices lists have a first entry of dashes. - - cma = ModelAdmin(Concert, self.site) - cmafa = cma.get_form(request) - - self.assertEqual(type(cmafa.base_fields['main_band'].widget.widget), - Select) - self.assertEqual( - list(cmafa.base_fields['main_band'].widget.choices), - [(u'', u'---------'), (self.band.id, u'The Doors')]) - - self.assertEqual( - type(cmafa.base_fields['opening_band'].widget.widget), Select) - self.assertEqual( - list(cmafa.base_fields['opening_band'].widget.choices), - [(u'', u'---------'), (self.band.id, u'The Doors')]) - - self.assertEqual(type(cmafa.base_fields['day'].widget), Select) - self.assertEqual(list(cmafa.base_fields['day'].widget.choices), - [('', '---------'), (1, 'Fri'), (2, 'Sat')]) - - self.assertEqual(type(cmafa.base_fields['transport'].widget), - Select) - self.assertEqual( - list(cmafa.base_fields['transport'].widget.choices), - [('', '---------'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')]) - - def test_foreign_key_as_radio_field(self): - # Now specify all the fields as radio_fields. Widgets should now be - # RadioSelect, and the choices list should have a first entry of 'None' if - # blank=True for the model field. Finally, the widget should have the - # 'radiolist' attr, and 'inline' as well if the field is specified HORIZONTAL. - - class ConcertAdmin(ModelAdmin): - radio_fields = { - 'main_band': HORIZONTAL, - 'opening_band': VERTICAL, - 'day': VERTICAL, - 'transport': HORIZONTAL, - } - - cma = ConcertAdmin(Concert, self.site) - cmafa = cma.get_form(request) - - self.assertEqual(type(cmafa.base_fields['main_band'].widget.widget), - AdminRadioSelect) - self.assertEqual(cmafa.base_fields['main_band'].widget.attrs, - {'class': 'radiolist inline'}) - self.assertEqual(list(cmafa.base_fields['main_band'].widget.choices), - [(self.band.id, u'The Doors')]) - - self.assertEqual( - type(cmafa.base_fields['opening_band'].widget.widget), - AdminRadioSelect) - self.assertEqual(cmafa.base_fields['opening_band'].widget.attrs, - {'class': 'radiolist'}) - self.assertEqual( - list(cmafa.base_fields['opening_band'].widget.choices), - [(u'', u'None'), (self.band.id, u'The Doors')]) - - self.assertEqual(type(cmafa.base_fields['day'].widget), - AdminRadioSelect) - self.assertEqual(cmafa.base_fields['day'].widget.attrs, - {'class': 'radiolist'}) - self.assertEqual(list(cmafa.base_fields['day'].widget.choices), - [(1, 'Fri'), (2, 'Sat')]) - - self.assertEqual(type(cmafa.base_fields['transport'].widget), - AdminRadioSelect) - self.assertEqual(cmafa.base_fields['transport'].widget.attrs, - {'class': 'radiolist inline'}) - self.assertEqual(list(cmafa.base_fields['transport'].widget.choices), - [('', u'None'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')]) - - class AdminConcertForm(forms.ModelForm): - class Meta: - model = Concert - exclude = ('transport',) - - class ConcertAdmin(ModelAdmin): - form = AdminConcertForm - - ma = ConcertAdmin(Concert, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['main_band', 'opening_band', 'day']) - - class AdminConcertForm(forms.ModelForm): - extra = forms.CharField() - - class Meta: - model = Concert - fields = ['extra', 'transport'] - - class ConcertAdmin(ModelAdmin): - form = AdminConcertForm - - ma = ConcertAdmin(Concert, self.site) - self.assertEqual(ma.get_form(request).base_fields.keys(), - ['extra', 'transport']) - - class ConcertInline(TabularInline): - form = AdminConcertForm - model = Concert - fk_name = 'main_band' - can_delete = True - - class BandAdmin(ModelAdmin): - inlines = [ - ConcertInline - ] - - ma = BandAdmin(Band, self.site) - self.assertEqual( - list(ma.get_formsets(request))[0]().forms[0].fields.keys(), - ['extra', 'transport', 'id', 'DELETE', 'main_band']) - - -class ValidationTests(unittest.TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_validation_only_runs_in_debug(self): - # Ensure validation only runs when DEBUG = True - try: - settings.DEBUG = True - - class ValidationTestModelAdmin(ModelAdmin): - raw_id_fields = 10 - - site = AdminSite() - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.", - site.register, - ValidationTestModel, - ValidationTestModelAdmin, - ) - finally: - settings.DEBUG = False - - site = AdminSite() - site.register(ValidationTestModel, ValidationTestModelAdmin) - - def test_raw_id_fields_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - raw_id_fields = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - raw_id_fields = ('non_existent_field',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.raw_id_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - raw_id_fields = ('name',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.raw_id_fields[0]', 'name' must be either a ForeignKey or ManyToManyField.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - raw_id_fields = ('users',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_fieldsets_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.fieldsets' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = ({},) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.fieldsets[0]' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = ((),) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.fieldsets[0]' does not have exactly two elements.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = (("General", ()),) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.fieldsets[0][1]' must be a dictionary.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = (("General", {}),) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'fields' key is required in ValidationTestModelAdmin.fieldsets[0][1] field options dict.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = (("General", {"fields": ("non_existent_field",)}),) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = (("General", {"fields": ("name",)}),) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = (("General", {"fields": ("name",)}),) - fields = ["name",] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "Both fieldsets and fields are specified in ValidationTestModelAdmin.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fieldsets = [(None, {'fields': ['name', 'name']})] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "There are duplicate field(s) in ValidationTestModelAdmin.fieldsets", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - fields = ["name", "name"] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "There are duplicate field(s) in ValidationTestModelAdmin.fields", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - def test_form_validation(self): - - class FakeForm(object): - pass - - class ValidationTestModelAdmin(ModelAdmin): - form = FakeForm - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "ValidationTestModelAdmin.form does not inherit from BaseModelForm.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - def test_fieldsets_with_custom_form_validation(self): - - class BandAdmin(ModelAdmin): - - fieldsets = ( - ('Band', { - 'fields': ('non_existent_field',) - }), - ) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'BandAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.", - validate, - BandAdmin, - Band, - ) - - class BandAdmin(ModelAdmin): - fieldsets = ( - ('Band', { - 'fields': ('name',) - }), - ) - - validate(BandAdmin, Band) - - class AdminBandForm(forms.ModelForm): - class Meta: - model = Band - - class BandAdmin(ModelAdmin): - form = AdminBandForm - - fieldsets = ( - ('Band', { - 'fields': ('non_existent_field',) - }), - ) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'BandAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.", - validate, - BandAdmin, - Band, - ) - - class AdminBandForm(forms.ModelForm): - delete = forms.BooleanField() - - class Meta: - model = Band - - class BandAdmin(ModelAdmin): - form = AdminBandForm - - fieldsets = ( - ('Band', { - 'fields': ('name', 'bio', 'sign_date', 'delete') - }), - ) - - validate(BandAdmin, Band) - - def test_filter_vertical_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - filter_vertical = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_vertical' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_vertical = ("non_existent_field",) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_vertical' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_vertical = ("name",) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_vertical[0]' must be a ManyToManyField.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_vertical = ("users",) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_filter_horizontal_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - filter_horizontal = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_horizontal' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_horizontal = ("non_existent_field",) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_horizontal' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_horizontal = ("name",) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.filter_horizontal[0]' must be a ManyToManyField.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - filter_horizontal = ("users",) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_radio_fields_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - radio_fields = () - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.radio_fields' must be a dictionary.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - radio_fields = {"non_existent_field": None} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.radio_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - radio_fields = {"name": None} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.radio_fields['name']' is neither an instance of ForeignKey nor does have choices set.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - radio_fields = {"state": None} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.radio_fields['state']' is neither admin.HORIZONTAL nor admin.VERTICAL.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - radio_fields = {"state": VERTICAL} - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_prepopulated_fields_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - prepopulated_fields = () - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.prepopulated_fields' must be a dictionary.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - prepopulated_fields = {"non_existent_field": None} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.prepopulated_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - prepopulated_fields = {"slug": ("non_existent_field",)} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.prepopulated_fields['slug'][0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - prepopulated_fields = {"users": ("name",)} - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.prepopulated_fields['users']' is either a DateTimeField, ForeignKey or ManyToManyField. This isn't allowed.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - prepopulated_fields = {"slug": ("name",)} - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_list_display_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - list_display = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_display' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display = ('non_existent_field',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "ValidationTestModelAdmin.list_display[0], 'non_existent_field' is not a callable or an attribute of 'ValidationTestModelAdmin' or found in the model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display = ('users',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_display[0]', 'users' is a ManyToManyField which is not supported.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display = ('name',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_list_display_links_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - list_display_links = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_display_links' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display_links = ('non_existent_field',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_display_links[0]' refers to 'non_existent_field' that is neither a field, method or property of model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display_links = ('name',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_display_links[0]'refers to 'name' which is not defined in 'list_display'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_display = ('name',) - list_display_links = ('name',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_list_filter_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - list_filter = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_filter' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_filter = ('non_existent_field',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_filter[0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_filter = ('is_active',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_list_per_page_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - list_per_page = 'hello' - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_per_page' should be a integer.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_per_page = 100 - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_search_fields_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - search_fields = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.search_fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - def test_date_hierarchy_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - date_hierarchy = 'non_existent_field' - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.date_hierarchy' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - date_hierarchy = 'name' - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.date_hierarchy is neither an instance of DateField nor DateTimeField.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - date_hierarchy = 'pub_date' - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_ordering_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - ordering = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.ordering' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - ordering = ('non_existent_field',) - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.ordering[0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - ordering = ('?', 'name') - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.ordering' has the random ordering marker '?', but contains other fields as well. Please either remove '?' or the other fields.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - ordering = ('?',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - class ValidationTestModelAdmin(ModelAdmin): - ordering = ('band__name',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - class ValidationTestModelAdmin(ModelAdmin): - ordering = ('name',) - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_list_select_related_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - list_select_related = 1 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.list_select_related' should be a boolean.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - list_select_related = False - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_save_as_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - save_as = 1 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.save_as' should be a boolean.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - save_as = True - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_save_on_top_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - save_on_top = 1 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.save_on_top' should be a boolean.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestModelAdmin(ModelAdmin): - save_on_top = True - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_inlines_validation(self): - - class ValidationTestModelAdmin(ModelAdmin): - inlines = 10 - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.inlines' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(object): - pass - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.inlines[0]' does not inherit from BaseModelAdmin.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - pass - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'model' is a required attribute of 'ValidationTestModelAdmin.inlines[0]'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class SomethingBad(object): - pass - - class ValidationTestInline(TabularInline): - model = SomethingBad - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestModelAdmin.inlines[0].model' does not inherit from models.Model.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_fields_validation(self): - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - fields = 10 - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - fields = ("non_existent_field",) - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.fields' refers to field 'non_existent_field' that is missing from the form.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - def test_fk_name_validation(self): - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - fk_name = "non_existent_field" - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.fk_name' refers to field 'non_existent_field' that is missing from model 'ValidationTestInlineModel'.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - fk_name = "parent" - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_extra_validation(self): - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - extra = "hello" - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.extra' should be a integer.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - extra = 2 - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_max_num_validation(self): - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - max_num = "hello" - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.max_num' should be an integer or None (default).", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - max_num = 2 - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - validate(ValidationTestModelAdmin, ValidationTestModel) - - def test_formset_validation(self): - - class FakeFormSet(object): - pass - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - formset = FakeFormSet - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - self.assertRaisesErrorWithMessage( - ImproperlyConfigured, - "'ValidationTestInline.formset' does not inherit from BaseModelFormSet.", - validate, - ValidationTestModelAdmin, - ValidationTestModel, - ) - - class RealModelFormSet(BaseModelFormSet): - pass - - class ValidationTestInline(TabularInline): - model = ValidationTestInlineModel - formset = RealModelFormSet - - class ValidationTestModelAdmin(ModelAdmin): - inlines = [ValidationTestInline] - - validate(ValidationTestModelAdmin, ValidationTestModel) diff --git a/parts/django/tests/regressiontests/multiple_database/__init__.py b/parts/django/tests/regressiontests/multiple_database/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/multiple_database/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb-common.json b/parts/django/tests/regressiontests/multiple_database/fixtures/multidb-common.json deleted file mode 100644 index 3313417..0000000 --- a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb-common.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": 1, - "model": "multiple_database.book", - "fields": { - "title": "The Definitive Guide to Django", - "published": "2009-7-8" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.default.json b/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.default.json deleted file mode 100644 index 379b18a..0000000 --- a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.default.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "pk": 1, - "model": "multiple_database.person", - "fields": { - "name": "Marty Alchin" - } - }, - { - "pk": 2, - "model": "multiple_database.person", - "fields": { - "name": "George Vilches" - } - }, - { - "pk": 2, - "model": "multiple_database.book", - "fields": { - "title": "Pro Django", - "published": "2008-12-16", - "authors": [["Marty Alchin"]], - "editor": ["George Vilches"] - } - } -] diff --git a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.other.json b/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.other.json deleted file mode 100644 index c64f490..0000000 --- a/parts/django/tests/regressiontests/multiple_database/fixtures/multidb.other.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "pk": 1, - "model": "multiple_database.person", - "fields": { - "name": "Mark Pilgrim" - } - }, - { - "pk": 2, - "model": "multiple_database.person", - "fields": { - "name": "Chris Mills" - } - }, - { - "pk": 2, - "model": "multiple_database.book", - "fields": { - "title": "Dive into Python", - "published": "2009-5-4", - "authors": [["Mark Pilgrim"]], - "editor": ["Chris Mills"] - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/multiple_database/fixtures/pets.json b/parts/django/tests/regressiontests/multiple_database/fixtures/pets.json deleted file mode 100644 index 89756a3..0000000 --- a/parts/django/tests/regressiontests/multiple_database/fixtures/pets.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "pk": 1, - "model": "multiple_database.pet", - "fields": { - "name": "Mr Bigglesworth", - "owner": 1 - } - }, - { - "pk": 2, - "model": "multiple_database.pet", - "fields": { - "name": "Spot", - "owner": 2 - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/multiple_database/models.py b/parts/django/tests/regressiontests/multiple_database/models.py deleted file mode 100644 index ce71828..0000000 --- a/parts/django/tests/regressiontests/multiple_database/models.py +++ /dev/null @@ -1,76 +0,0 @@ -from django.conf import settings -from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes import generic -from django.db import models - -class Review(models.Model): - source = models.CharField(max_length=100) - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey() - - def __unicode__(self): - return self.source - - class Meta: - ordering = ('source',) - -class PersonManager(models.Manager): - def get_by_natural_key(self, name): - return self.get(name=name) - -class Person(models.Model): - objects = PersonManager() - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - - class Meta: - ordering = ('name',) - -# This book manager doesn't do anything interesting; it just -# exists to strip out the 'extra_arg' argument to certain -# calls. This argument is used to establish that the BookManager -# is actually getting used when it should be. -class BookManager(models.Manager): - def create(self, *args, **kwargs): - kwargs.pop('extra_arg', None) - return super(BookManager, self).create(*args, **kwargs) - - def get_or_create(self, *args, **kwargs): - kwargs.pop('extra_arg', None) - return super(BookManager, self).get_or_create(*args, **kwargs) - -class Book(models.Model): - objects = BookManager() - title = models.CharField(max_length=100) - published = models.DateField() - authors = models.ManyToManyField(Person) - editor = models.ForeignKey(Person, null=True, related_name='edited') - reviews = generic.GenericRelation(Review) - pages = models.IntegerField(default=100) - - def __unicode__(self): - return self.title - - class Meta: - ordering = ('title',) - -class Pet(models.Model): - name = models.CharField(max_length=100) - owner = models.ForeignKey(Person) - - def __unicode__(self): - return self.name - - class Meta: - ordering = ('name',) - -class UserProfile(models.Model): - user = models.OneToOneField(User, null=True) - flavor = models.CharField(max_length=100) - - class Meta: - ordering = ('flavor',) diff --git a/parts/django/tests/regressiontests/multiple_database/tests.py b/parts/django/tests/regressiontests/multiple_database/tests.py deleted file mode 100644 index 05dca26..0000000 --- a/parts/django/tests/regressiontests/multiple_database/tests.py +++ /dev/null @@ -1,1681 +0,0 @@ -import datetime -import pickle -import sys -from StringIO import StringIO - -from django.conf import settings -from django.contrib.auth.models import User -from django.core import management -from django.db import connections, router, DEFAULT_DB_ALIAS -from django.db.utils import ConnectionRouter -from django.test import TestCase - -from models import Book, Person, Pet, Review, UserProfile - -try: - # we only have these models if the user is using multi-db, it's safe the - # run the tests without them though. - from models import Article, article_using -except ImportError: - pass - -class QueryTestCase(TestCase): - multi_db = True - - def test_db_selection(self): - "Check that querysets will use the default databse by default" - self.assertEquals(Book.objects.db, DEFAULT_DB_ALIAS) - self.assertEquals(Book.objects.all().db, DEFAULT_DB_ALIAS) - - self.assertEquals(Book.objects.using('other').db, 'other') - - self.assertEquals(Book.objects.db_manager('other').db, 'other') - self.assertEquals(Book.objects.db_manager('other').all().db, 'other') - - def test_default_creation(self): - "Objects created on the default database don't leak onto other databases" - # Create a book on the default database using create() - Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - # Create a book on the default database using a save - dive = Book() - dive.title="Dive into Python" - dive.published = datetime.date(2009, 5, 4) - dive.save() - - # Check that book exists on the default database, but not on other database - try: - Book.objects.get(title="Pro Django") - Book.objects.using('default').get(title="Pro Django") - except Book.DoesNotExist: - self.fail('"Dive Into Python" should exist on default database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.using('other').get, - title="Pro Django" - ) - - try: - Book.objects.get(title="Dive into Python") - Book.objects.using('default').get(title="Dive into Python") - except Book.DoesNotExist: - self.fail('"Dive into Python" should exist on default database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.using('other').get, - title="Dive into Python" - ) - - - def test_other_creation(self): - "Objects created on another database don't leak onto the default database" - # Create a book on the second database - Book.objects.using('other').create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - # Create a book on the default database using a save - dive = Book() - dive.title="Dive into Python" - dive.published = datetime.date(2009, 5, 4) - dive.save(using='other') - - # Check that book exists on the default database, but not on other database - try: - Book.objects.using('other').get(title="Pro Django") - except Book.DoesNotExist: - self.fail('"Dive Into Python" should exist on other database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.get, - title="Pro Django" - ) - self.assertRaises(Book.DoesNotExist, - Book.objects.using('default').get, - title="Pro Django" - ) - - try: - Book.objects.using('other').get(title="Dive into Python") - except Book.DoesNotExist: - self.fail('"Dive into Python" should exist on other database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.get, - title="Dive into Python" - ) - self.assertRaises(Book.DoesNotExist, - Book.objects.using('default').get, - title="Dive into Python" - ) - - def test_basic_queries(self): - "Queries are constrained to a single database" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - dive = Book.objects.using('other').get(published=datetime.date(2009, 5, 4)) - self.assertEqual(dive.title, "Dive into Python") - self.assertRaises(Book.DoesNotExist, Book.objects.using('default').get, published=datetime.date(2009, 5, 4)) - - dive = Book.objects.using('other').get(title__icontains="dive") - self.assertEqual(dive.title, "Dive into Python") - self.assertRaises(Book.DoesNotExist, Book.objects.using('default').get, title__icontains="dive") - - dive = Book.objects.using('other').get(title__iexact="dive INTO python") - self.assertEqual(dive.title, "Dive into Python") - self.assertRaises(Book.DoesNotExist, Book.objects.using('default').get, title__iexact="dive INTO python") - - dive = Book.objects.using('other').get(published__year=2009) - self.assertEqual(dive.title, "Dive into Python") - self.assertEqual(dive.published, datetime.date(2009, 5, 4)) - self.assertRaises(Book.DoesNotExist, Book.objects.using('default').get, published__year=2009) - - years = Book.objects.using('other').dates('published', 'year') - self.assertEqual([o.year for o in years], [2009]) - years = Book.objects.using('default').dates('published', 'year') - self.assertEqual([o.year for o in years], []) - - months = Book.objects.using('other').dates('published', 'month') - self.assertEqual([o.month for o in months], [5]) - months = Book.objects.using('default').dates('published', 'month') - self.assertEqual([o.month for o in months], []) - - def test_m2m_separation(self): - "M2M fields are constrained to a single database" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.create(name="Marty Alchin") - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # Save the author relations - pro.authors = [marty] - dive.authors = [mark] - - # Inspect the m2m tables directly. - # There should be 1 entry in each database - self.assertEquals(Book.authors.through.objects.using('default').count(), 1) - self.assertEquals(Book.authors.through.objects.using('other').count(), 1) - - # Check that queries work across m2m joins - self.assertEquals(list(Book.objects.using('default').filter(authors__name='Marty Alchin').values_list('title', flat=True)), - [u'Pro Django']) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Marty Alchin').values_list('title', flat=True)), - []) - - self.assertEquals(list(Book.objects.using('default').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - []) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - [u'Dive into Python']) - - # Reget the objects to clear caches - dive = Book.objects.using('other').get(title="Dive into Python") - mark = Person.objects.using('other').get(name="Mark Pilgrim") - - # Retrive related object by descriptor. Related objects should be database-baound - self.assertEquals(list(dive.authors.all().values_list('name', flat=True)), - [u'Mark Pilgrim']) - - self.assertEquals(list(mark.book_set.all().values_list('title', flat=True)), - [u'Dive into Python']) - - def test_m2m_forward_operations(self): - "M2M forward manipulations are all constrained to a single DB" - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # Save the author relations - dive.authors = [mark] - - # Add a second author - john = Person.objects.using('other').create(name="John Smith") - self.assertEquals(list(Book.objects.using('other').filter(authors__name='John Smith').values_list('title', flat=True)), - []) - - - dive.authors.add(john) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - [u'Dive into Python']) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='John Smith').values_list('title', flat=True)), - [u'Dive into Python']) - - # Remove the second author - dive.authors.remove(john) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - [u'Dive into Python']) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='John Smith').values_list('title', flat=True)), - []) - - # Clear all authors - dive.authors.clear() - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - []) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='John Smith').values_list('title', flat=True)), - []) - - # Create an author through the m2m interface - dive.authors.create(name='Jane Brown') - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), - []) - self.assertEquals(list(Book.objects.using('other').filter(authors__name='Jane Brown').values_list('title', flat=True)), - [u'Dive into Python']) - - def test_m2m_reverse_operations(self): - "M2M reverse manipulations are all constrained to a single DB" - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # Save the author relations - dive.authors = [mark] - - # Create a second book on the other database - grease = Book.objects.using('other').create(title="Greasemonkey Hacks", - published=datetime.date(2005, 11, 1)) - - # Add a books to the m2m - mark.book_set.add(grease) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Dive into Python').values_list('name', flat=True)), - [u'Mark Pilgrim']) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Greasemonkey Hacks').values_list('name', flat=True)), - [u'Mark Pilgrim']) - - # Remove a book from the m2m - mark.book_set.remove(grease) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Dive into Python').values_list('name', flat=True)), - [u'Mark Pilgrim']) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Greasemonkey Hacks').values_list('name', flat=True)), - []) - - # Clear the books associated with mark - mark.book_set.clear() - self.assertEquals(list(Person.objects.using('other').filter(book__title='Dive into Python').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Greasemonkey Hacks').values_list('name', flat=True)), - []) - - # Create a book through the m2m interface - mark.book_set.create(title="Dive into HTML5", published=datetime.date(2020, 1, 1)) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Dive into Python').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(book__title='Dive into HTML5').values_list('name', flat=True)), - [u'Mark Pilgrim']) - - def test_m2m_cross_database_protection(self): - "Operations that involve sharing M2M objects across databases raise an error" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.create(name="Marty Alchin") - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - # Set a foreign key set with an object from a different database - try: - marty.book_set = [pro, dive] - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Add to an m2m with an object from a different database - try: - marty.book_set.add(dive) - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Set a m2m with an object from a different database - try: - marty.book_set = [pro, dive] - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Add to a reverse m2m with an object from a different database - try: - dive.authors.add(marty) - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Set a reverse m2m with an object from a different database - try: - dive.authors = [mark, marty] - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - def test_m2m_deletion(self): - "Cascaded deletions of m2m relations issue queries on the right database" - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - dive.authors = [mark] - - # Check the initial state - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Book.authors.through.objects.using('default').count(), 0) - - self.assertEquals(Person.objects.using('other').count(), 1) - self.assertEquals(Book.objects.using('other').count(), 1) - self.assertEquals(Book.authors.through.objects.using('other').count(), 1) - - # Delete the object on the other database - dive.delete(using='other') - - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Book.authors.through.objects.using('default').count(), 0) - - # The person still exists ... - self.assertEquals(Person.objects.using('other').count(), 1) - # ... but the book has been deleted - self.assertEquals(Book.objects.using('other').count(), 0) - # ... and the relationship object has also been deleted. - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # Now try deletion in the reverse direction. Set up the relation again - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - dive.authors = [mark] - - # Check the initial state - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Book.authors.through.objects.using('default').count(), 0) - - self.assertEquals(Person.objects.using('other').count(), 1) - self.assertEquals(Book.objects.using('other').count(), 1) - self.assertEquals(Book.authors.through.objects.using('other').count(), 1) - - # Delete the object on the other database - mark.delete(using='other') - - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Book.authors.through.objects.using('default').count(), 0) - - # The person has been deleted ... - self.assertEquals(Person.objects.using('other').count(), 0) - # ... but the book still exists - self.assertEquals(Book.objects.using('other').count(), 1) - # ... and the relationship object has been deleted. - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - def test_foreign_key_separation(self): - "FK fields are constrained to a single database" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.create(name="Marty Alchin") - george = Person.objects.create(name="George Vilches") - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - chris = Person.objects.using('other').create(name="Chris Mills") - - # Save the author's favourite books - pro.editor = george - pro.save() - - dive.editor = chris - dive.save() - - pro = Book.objects.using('default').get(title="Pro Django") - self.assertEquals(pro.editor.name, "George Vilches") - - dive = Book.objects.using('other').get(title="Dive into Python") - self.assertEquals(dive.editor.name, "Chris Mills") - - # Check that queries work across foreign key joins - self.assertEquals(list(Person.objects.using('default').filter(edited__title='Pro Django').values_list('name', flat=True)), - [u'George Vilches']) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Pro Django').values_list('name', flat=True)), - []) - - self.assertEquals(list(Person.objects.using('default').filter(edited__title='Dive into Python').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Python').values_list('name', flat=True)), - [u'Chris Mills']) - - # Reget the objects to clear caches - chris = Person.objects.using('other').get(name="Chris Mills") - dive = Book.objects.using('other').get(title="Dive into Python") - - # Retrive related object by descriptor. Related objects should be database-baound - self.assertEquals(list(chris.edited.values_list('title', flat=True)), - [u'Dive into Python']) - - def test_foreign_key_reverse_operations(self): - "FK reverse manipulations are all constrained to a single DB" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - chris = Person.objects.using('other').create(name="Chris Mills") - - # Save the author relations - dive.editor = chris - dive.save() - - # Add a second book edited by chris - html5 = Book.objects.using('other').create(title="Dive into HTML5", published=datetime.date(2010, 3, 15)) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into HTML5').values_list('name', flat=True)), - []) - - chris.edited.add(html5) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into HTML5').values_list('name', flat=True)), - [u'Chris Mills']) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Python').values_list('name', flat=True)), - [u'Chris Mills']) - - # Remove the second editor - chris.edited.remove(html5) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into HTML5').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Python').values_list('name', flat=True)), - [u'Chris Mills']) - - # Clear all edited books - chris.edited.clear() - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into HTML5').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Python').values_list('name', flat=True)), - []) - - # Create an author through the m2m interface - chris.edited.create(title='Dive into Water', published=datetime.date(2010, 3, 15)) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into HTML5').values_list('name', flat=True)), - []) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Water').values_list('name', flat=True)), - [u'Chris Mills']) - self.assertEquals(list(Person.objects.using('other').filter(edited__title='Dive into Python').values_list('name', flat=True)), - []) - - def test_foreign_key_cross_database_protection(self): - "Operations that involve sharing FK objects across databases raise an error" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.create(name="Marty Alchin") - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # Set a foreign key with an object from a different database - try: - dive.editor = marty - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Set a foreign key set with an object from a different database - try: - marty.edited = [pro, dive] - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Add to a foreign key set with an object from a different database - try: - marty.edited.add(dive) - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # BUT! if you assign a FK object when the base object hasn't - # been saved yet, you implicitly assign the database for the - # base object. - chris = Person(name="Chris Mills") - html5 = Book(title="Dive into HTML5", published=datetime.date(2010, 3, 15)) - # initially, no db assigned - self.assertEquals(chris._state.db, None) - self.assertEquals(html5._state.db, None) - - # old object comes from 'other', so the new object is set to use 'other'... - dive.editor = chris - html5.editor = mark - self.assertEquals(chris._state.db, 'other') - self.assertEquals(html5._state.db, 'other') - # ... but it isn't saved yet - self.assertEquals(list(Person.objects.using('other').values_list('name',flat=True)), - [u'Mark Pilgrim']) - self.assertEquals(list(Book.objects.using('other').values_list('title',flat=True)), - [u'Dive into Python']) - - # When saved (no using required), new objects goes to 'other' - chris.save() - html5.save() - self.assertEquals(list(Person.objects.using('default').values_list('name',flat=True)), - [u'Marty Alchin']) - self.assertEquals(list(Person.objects.using('other').values_list('name',flat=True)), - [u'Chris Mills', u'Mark Pilgrim']) - self.assertEquals(list(Book.objects.using('default').values_list('title',flat=True)), - [u'Pro Django']) - self.assertEquals(list(Book.objects.using('other').values_list('title',flat=True)), - [u'Dive into HTML5', u'Dive into Python']) - - # This also works if you assign the FK in the constructor - water = Book(title="Dive into Water", published=datetime.date(2001, 1, 1), editor=mark) - self.assertEquals(water._state.db, 'other') - # ... but it isn't saved yet - self.assertEquals(list(Book.objects.using('default').values_list('title',flat=True)), - [u'Pro Django']) - self.assertEquals(list(Book.objects.using('other').values_list('title',flat=True)), - [u'Dive into HTML5', u'Dive into Python']) - - # When saved, the new book goes to 'other' - water.save() - self.assertEquals(list(Book.objects.using('default').values_list('title',flat=True)), - [u'Pro Django']) - self.assertEquals(list(Book.objects.using('other').values_list('title',flat=True)), - [u'Dive into HTML5', u'Dive into Python', u'Dive into Water']) - - def test_foreign_key_deletion(self): - "Cascaded deletions of Foreign Key relations issue queries on the right database" - mark = Person.objects.using('other').create(name="Mark Pilgrim") - fido = Pet.objects.using('other').create(name="Fido", owner=mark) - - # Check the initial state - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Pet.objects.using('default').count(), 0) - - self.assertEquals(Person.objects.using('other').count(), 1) - self.assertEquals(Pet.objects.using('other').count(), 1) - - # Delete the person object, which will cascade onto the pet - mark.delete(using='other') - - self.assertEquals(Person.objects.using('default').count(), 0) - self.assertEquals(Pet.objects.using('default').count(), 0) - - # Both the pet and the person have been deleted from the right database - self.assertEquals(Person.objects.using('other').count(), 0) - self.assertEquals(Pet.objects.using('other').count(), 0) - - def test_foreign_key_validation(self): - "ForeignKey.validate() uses the correct database" - mickey = Person.objects.using('other').create(name="Mickey") - pluto = Pet.objects.using('other').create(name="Pluto", owner=mickey) - self.assertEquals(None, pluto.full_clean()) - - def test_o2o_separation(self): - "OneToOne fields are constrained to a single database" - # Create a user and profile on the default database - alice = User.objects.db_manager('default').create_user('alice', 'alice@example.com') - alice_profile = UserProfile.objects.using('default').create(user=alice, flavor='chocolate') - - # Create a user and profile on the other database - bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com') - bob_profile = UserProfile.objects.using('other').create(user=bob, flavor='crunchy frog') - - # Retrieve related objects; queries should be database constrained - alice = User.objects.using('default').get(username="alice") - self.assertEquals(alice.userprofile.flavor, "chocolate") - - bob = User.objects.using('other').get(username="bob") - self.assertEquals(bob.userprofile.flavor, "crunchy frog") - - # Check that queries work across joins - self.assertEquals(list(User.objects.using('default').filter(userprofile__flavor='chocolate').values_list('username', flat=True)), - [u'alice']) - self.assertEquals(list(User.objects.using('other').filter(userprofile__flavor='chocolate').values_list('username', flat=True)), - []) - - self.assertEquals(list(User.objects.using('default').filter(userprofile__flavor='crunchy frog').values_list('username', flat=True)), - []) - self.assertEquals(list(User.objects.using('other').filter(userprofile__flavor='crunchy frog').values_list('username', flat=True)), - [u'bob']) - - # Reget the objects to clear caches - alice_profile = UserProfile.objects.using('default').get(flavor='chocolate') - bob_profile = UserProfile.objects.using('other').get(flavor='crunchy frog') - - # Retrive related object by descriptor. Related objects should be database-baound - self.assertEquals(alice_profile.user.username, 'alice') - self.assertEquals(bob_profile.user.username, 'bob') - - def test_o2o_cross_database_protection(self): - "Operations that involve sharing FK objects across databases raise an error" - # Create a user and profile on the default database - alice = User.objects.db_manager('default').create_user('alice', 'alice@example.com') - - # Create a user and profile on the other database - bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com') - - # Set a one-to-one relation with an object from a different database - alice_profile = UserProfile.objects.using('default').create(user=alice, flavor='chocolate') - try: - bob.userprofile = alice_profile - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # BUT! if you assign a FK object when the base object hasn't - # been saved yet, you implicitly assign the database for the - # base object. - bob_profile = UserProfile.objects.using('other').create(user=bob, flavor='crunchy frog') - - new_bob_profile = UserProfile(flavor="spring surprise") - - charlie = User(username='charlie',email='charlie@example.com') - charlie.set_unusable_password() - - # initially, no db assigned - self.assertEquals(new_bob_profile._state.db, None) - self.assertEquals(charlie._state.db, None) - - # old object comes from 'other', so the new object is set to use 'other'... - new_bob_profile.user = bob - charlie.userprofile = bob_profile - self.assertEquals(new_bob_profile._state.db, 'other') - self.assertEquals(charlie._state.db, 'other') - - # ... but it isn't saved yet - self.assertEquals(list(User.objects.using('other').values_list('username',flat=True)), - [u'bob']) - self.assertEquals(list(UserProfile.objects.using('other').values_list('flavor',flat=True)), - [u'crunchy frog']) - - # When saved (no using required), new objects goes to 'other' - charlie.save() - bob_profile.save() - new_bob_profile.save() - self.assertEquals(list(User.objects.using('default').values_list('username',flat=True)), - [u'alice']) - self.assertEquals(list(User.objects.using('other').values_list('username',flat=True)), - [u'bob', u'charlie']) - self.assertEquals(list(UserProfile.objects.using('default').values_list('flavor',flat=True)), - [u'chocolate']) - self.assertEquals(list(UserProfile.objects.using('other').values_list('flavor',flat=True)), - [u'crunchy frog', u'spring surprise']) - - # This also works if you assign the O2O relation in the constructor - denise = User.objects.db_manager('other').create_user('denise','denise@example.com') - denise_profile = UserProfile(flavor="tofu", user=denise) - - self.assertEquals(denise_profile._state.db, 'other') - # ... but it isn't saved yet - self.assertEquals(list(UserProfile.objects.using('default').values_list('flavor',flat=True)), - [u'chocolate']) - self.assertEquals(list(UserProfile.objects.using('other').values_list('flavor',flat=True)), - [u'crunchy frog', u'spring surprise']) - - # When saved, the new profile goes to 'other' - denise_profile.save() - self.assertEquals(list(UserProfile.objects.using('default').values_list('flavor',flat=True)), - [u'chocolate']) - self.assertEquals(list(UserProfile.objects.using('other').values_list('flavor',flat=True)), - [u'crunchy frog', u'spring surprise', u'tofu']) - - def test_generic_key_separation(self): - "Generic fields are constrained to a single database" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - review1 = Review.objects.create(source="Python Monthly", content_object=pro) - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - review2 = Review.objects.using('other').create(source="Python Weekly", content_object=dive) - - review1 = Review.objects.using('default').get(source="Python Monthly") - self.assertEquals(review1.content_object.title, "Pro Django") - - review2 = Review.objects.using('other').get(source="Python Weekly") - self.assertEquals(review2.content_object.title, "Dive into Python") - - # Reget the objects to clear caches - dive = Book.objects.using('other').get(title="Dive into Python") - - # Retrive related object by descriptor. Related objects should be database-bound - self.assertEquals(list(dive.reviews.all().values_list('source', flat=True)), - [u'Python Weekly']) - - def test_generic_key_reverse_operations(self): - "Generic reverse manipulations are all constrained to a single DB" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - temp = Book.objects.using('other').create(title="Temp", - published=datetime.date(2009, 5, 4)) - - review1 = Review.objects.using('other').create(source="Python Weekly", content_object=dive) - review2 = Review.objects.using('other').create(source="Python Monthly", content_object=temp) - - self.assertEquals(list(Review.objects.using('default').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source', flat=True)), - [u'Python Weekly']) - - # Add a second review - dive.reviews.add(review2) - self.assertEquals(list(Review.objects.using('default').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source', flat=True)), - [u'Python Monthly', u'Python Weekly']) - - # Remove the second author - dive.reviews.remove(review1) - self.assertEquals(list(Review.objects.using('default').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source', flat=True)), - [u'Python Monthly']) - - # Clear all reviews - dive.reviews.clear() - self.assertEquals(list(Review.objects.using('default').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - - # Create an author through the generic interface - dive.reviews.create(source='Python Daily') - self.assertEquals(list(Review.objects.using('default').filter(object_id=dive.pk).values_list('source', flat=True)), - []) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source', flat=True)), - [u'Python Daily']) - - def test_generic_key_cross_database_protection(self): - "Operations that involve sharing generic key objects across databases raise an error" - # Create a book and author on the default database - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - review1 = Review.objects.create(source="Python Monthly", content_object=pro) - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - review2 = Review.objects.using('other').create(source="Python Weekly", content_object=dive) - - # Set a foreign key with an object from a different database - try: - review1.content_object = dive - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # Add to a foreign key set with an object from a different database - try: - dive.reviews.add(review1) - self.fail("Shouldn't be able to assign across databases") - except ValueError: - pass - - # BUT! if you assign a FK object when the base object hasn't - # been saved yet, you implicitly assign the database for the - # base object. - review3 = Review(source="Python Daily") - # initially, no db assigned - self.assertEquals(review3._state.db, None) - - # Dive comes from 'other', so review3 is set to use 'other'... - review3.content_object = dive - self.assertEquals(review3._state.db, 'other') - # ... but it isn't saved yet - self.assertEquals(list(Review.objects.using('default').filter(object_id=pro.pk).values_list('source', flat=True)), - [u'Python Monthly']) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source',flat=True)), - [u'Python Weekly']) - - # When saved, John goes to 'other' - review3.save() - self.assertEquals(list(Review.objects.using('default').filter(object_id=pro.pk).values_list('source', flat=True)), - [u'Python Monthly']) - self.assertEquals(list(Review.objects.using('other').filter(object_id=dive.pk).values_list('source',flat=True)), - [u'Python Daily', u'Python Weekly']) - - def test_generic_key_deletion(self): - "Cascaded deletions of Generic Key relations issue queries on the right database" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - review = Review.objects.using('other').create(source="Python Weekly", content_object=dive) - - # Check the initial state - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Review.objects.using('default').count(), 0) - - self.assertEquals(Book.objects.using('other').count(), 1) - self.assertEquals(Review.objects.using('other').count(), 1) - - # Delete the Book object, which will cascade onto the pet - dive.delete(using='other') - - self.assertEquals(Book.objects.using('default').count(), 0) - self.assertEquals(Review.objects.using('default').count(), 0) - - # Both the pet and the person have been deleted from the right database - self.assertEquals(Book.objects.using('other').count(), 0) - self.assertEquals(Review.objects.using('other').count(), 0) - - def test_ordering(self): - "get_next_by_XXX commands stick to a single database" - pro = Book.objects.create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - learn = Book.objects.using('other').create(title="Learning Python", - published=datetime.date(2008, 7, 16)) - - self.assertEquals(learn.get_next_by_published().title, "Dive into Python") - self.assertEquals(dive.get_previous_by_published().title, "Learning Python") - - def test_raw(self): - "test the raw() method across databases" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - val = Book.objects.db_manager("other").raw('SELECT id FROM multiple_database_book') - self.assertEqual(map(lambda o: o.pk, val), [dive.pk]) - - val = Book.objects.raw('SELECT id FROM multiple_database_book').using('other') - self.assertEqual(map(lambda o: o.pk, val), [dive.pk]) - - def test_select_related(self): - "Database assignment is retained if an object is retrieved with select_related()" - # Create a book and author on the other database - mark = Person.objects.using('other').create(name="Mark Pilgrim") - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4), - editor=mark) - - # Retrieve the Person using select_related() - book = Book.objects.using('other').select_related('editor').get(title="Dive into Python") - - # The editor instance should have a db state - self.assertEqual(book.editor._state.db, 'other') - - def test_subquery(self): - """Make sure as_sql works with subqueries and master/slave.""" - sub = Person.objects.using('other').filter(name='fff') - qs = Book.objects.filter(editor__in=sub) - - # When you call __str__ on the query object, it doesn't know about using - # so it falls back to the default. If the subquery explicitly uses a - # different database, an error should be raised. - self.assertRaises(ValueError, str, qs.query) - - # Evaluating the query shouldn't work, either - try: - for obj in qs: - pass - self.fail('Iterating over query should raise ValueError') - except ValueError: - pass - - def test_related_manager(self): - "Related managers return managers, not querysets" - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # extra_arg is removed by the BookManager's implementation of - # create(); but the BookManager's implementation won't get called - # unless edited returns a Manager, not a queryset - mark.book_set.create(title="Dive into Python", - published=datetime.date(2009, 5, 4), - extra_arg=True) - - mark.book_set.get_or_create(title="Dive into Python", - published=datetime.date(2009, 5, 4), - extra_arg=True) - - mark.edited.create(title="Dive into Water", - published=datetime.date(2009, 5, 4), - extra_arg=True) - - mark.edited.get_or_create(title="Dive into Water", - published=datetime.date(2009, 5, 4), - extra_arg=True) - -class TestRouter(object): - # A test router. The behaviour is vaguely master/slave, but the - # databases aren't assumed to propagate changes. - def db_for_read(self, model, instance=None, **hints): - if instance: - return instance._state.db or 'other' - return 'other' - - def db_for_write(self, model, **hints): - return DEFAULT_DB_ALIAS - - def allow_relation(self, obj1, obj2, **hints): - return obj1._state.db in ('default', 'other') and obj2._state.db in ('default', 'other') - - def allow_syncdb(self, db, model): - return True - -class AuthRouter(object): - """A router to control all database operations on models in - the contrib.auth application""" - - def db_for_read(self, model, **hints): - "Point all read operations on auth models to 'default'" - if model._meta.app_label == 'auth': - # We use default here to ensure we can tell the difference - # between a read request and a write request for Auth objects - return 'default' - return None - - def db_for_write(self, model, **hints): - "Point all operations on auth models to 'other'" - if model._meta.app_label == 'auth': - return 'other' - return None - - def allow_relation(self, obj1, obj2, **hints): - "Allow any relation if a model in Auth is involved" - if obj1._meta.app_label == 'auth' or obj2._meta.app_label == 'auth': - return True - return None - - def allow_syncdb(self, db, model): - "Make sure the auth app only appears on the 'other' db" - if db == 'other': - return model._meta.app_label == 'auth' - elif model._meta.app_label == 'auth': - return False - return None - -class WriteRouter(object): - # A router that only expresses an opinion on writes - def db_for_write(self, model, **hints): - return 'writer' - -class RouterTestCase(TestCase): - multi_db = True - - def setUp(self): - # Make the 'other' database appear to be a slave of the 'default' - self.old_routers = router.routers - router.routers = [TestRouter()] - - def tearDown(self): - # Restore the 'other' database as an independent database - router.routers = self.old_routers - - def test_db_selection(self): - "Check that querysets obey the router for db suggestions" - self.assertEquals(Book.objects.db, 'other') - self.assertEquals(Book.objects.all().db, 'other') - - self.assertEquals(Book.objects.using('default').db, 'default') - - self.assertEquals(Book.objects.db_manager('default').db, 'default') - self.assertEquals(Book.objects.db_manager('default').all().db, 'default') - - def test_syncdb_selection(self): - "Synchronization behaviour is predicatable" - - self.assertTrue(router.allow_syncdb('default', User)) - self.assertTrue(router.allow_syncdb('default', Book)) - - self.assertTrue(router.allow_syncdb('other', User)) - self.assertTrue(router.allow_syncdb('other', Book)) - - # Add the auth router to the chain. - # TestRouter is a universal synchronizer, so it should have no effect. - router.routers = [TestRouter(), AuthRouter()] - - self.assertTrue(router.allow_syncdb('default', User)) - self.assertTrue(router.allow_syncdb('default', Book)) - - self.assertTrue(router.allow_syncdb('other', User)) - self.assertTrue(router.allow_syncdb('other', Book)) - - # Now check what happens if the router order is the other way around - router.routers = [AuthRouter(), TestRouter()] - - self.assertFalse(router.allow_syncdb('default', User)) - self.assertTrue(router.allow_syncdb('default', Book)) - - self.assertTrue(router.allow_syncdb('other', User)) - self.assertFalse(router.allow_syncdb('other', Book)) - - def test_partial_router(self): - "A router can choose to implement a subset of methods" - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - # First check the baseline behaviour - - self.assertEquals(router.db_for_read(User), 'other') - self.assertEquals(router.db_for_read(Book), 'other') - - self.assertEquals(router.db_for_write(User), 'default') - self.assertEquals(router.db_for_write(Book), 'default') - - self.assertTrue(router.allow_relation(dive, dive)) - - self.assertTrue(router.allow_syncdb('default', User)) - self.assertTrue(router.allow_syncdb('default', Book)) - - router.routers = [WriteRouter(), AuthRouter(), TestRouter()] - - self.assertEquals(router.db_for_read(User), 'default') - self.assertEquals(router.db_for_read(Book), 'other') - - self.assertEquals(router.db_for_write(User), 'writer') - self.assertEquals(router.db_for_write(Book), 'writer') - - self.assertTrue(router.allow_relation(dive, dive)) - - self.assertFalse(router.allow_syncdb('default', User)) - self.assertTrue(router.allow_syncdb('default', Book)) - - - def test_database_routing(self): - marty = Person.objects.using('default').create(name="Marty Alchin") - pro = Book.objects.using('default').create(title="Pro Django", - published=datetime.date(2008, 12, 16), - editor=marty) - pro.authors = [marty] - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - # An update query will be routed to the default database - Book.objects.filter(title='Pro Django').update(pages=200) - - try: - # By default, the get query will be directed to 'other' - Book.objects.get(title='Pro Django') - self.fail("Shouldn't be able to find the book") - except Book.DoesNotExist: - pass - - # But the same query issued explicitly at a database will work. - pro = Book.objects.using('default').get(title='Pro Django') - - # Check that the update worked. - self.assertEquals(pro.pages, 200) - - # An update query with an explicit using clause will be routed - # to the requested database. - Book.objects.using('other').filter(title='Dive into Python').update(pages=300) - self.assertEquals(Book.objects.get(title='Dive into Python').pages, 300) - - # Related object queries stick to the same database - # as the original object, regardless of the router - self.assertEquals(list(pro.authors.values_list('name', flat=True)), [u'Marty Alchin']) - self.assertEquals(pro.editor.name, u'Marty Alchin') - - # get_or_create is a special case. The get needs to be targetted at - # the write database in order to avoid potential transaction - # consistency problems - book, created = Book.objects.get_or_create(title="Pro Django") - self.assertFalse(created) - - book, created = Book.objects.get_or_create(title="Dive Into Python", - defaults={'published':datetime.date(2009, 5, 4)}) - self.assertTrue(created) - - # Check the head count of objects - self.assertEquals(Book.objects.using('default').count(), 2) - self.assertEquals(Book.objects.using('other').count(), 1) - # If a database isn't specified, the read database is used - self.assertEquals(Book.objects.count(), 1) - - # A delete query will also be routed to the default database - Book.objects.filter(pages__gt=150).delete() - - # The default database has lost the book. - self.assertEquals(Book.objects.using('default').count(), 1) - self.assertEquals(Book.objects.using('other').count(), 1) - - def test_foreign_key_cross_database_protection(self): - "Foreign keys can cross databases if they two databases have a common source" - # Create a book and author on the default database - pro = Book.objects.using('default').create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.using('default').create(name="Marty Alchin") - - # Create a book and author on the other database - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - - # Set a foreign key with an object from a different database - try: - dive.editor = marty - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments of original objects haven't changed... - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - - # ... but they will when the affected object is saved. - dive.save() - self.assertEquals(dive._state.db, 'default') - - # ...and the source database now has a copy of any object saved - try: - Book.objects.using('default').get(title='Dive into Python').delete() - except Book.DoesNotExist: - self.fail('Source database should have a copy of saved object') - - # This isn't a real master-slave database, so restore the original from other - dive = Book.objects.using('other').get(title='Dive into Python') - self.assertEquals(dive._state.db, 'other') - - # Set a foreign key set with an object from a different database - try: - marty.edited = [pro, dive] - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Assignment implies a save, so database assignments of original objects have changed... - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'default') - self.assertEquals(mark._state.db, 'other') - - # ...and the source database now has a copy of any object saved - try: - Book.objects.using('default').get(title='Dive into Python').delete() - except Book.DoesNotExist: - self.fail('Source database should have a copy of saved object') - - # This isn't a real master-slave database, so restore the original from other - dive = Book.objects.using('other').get(title='Dive into Python') - self.assertEquals(dive._state.db, 'other') - - # Add to a foreign key set with an object from a different database - try: - marty.edited.add(dive) - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Add implies a save, so database assignments of original objects have changed... - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'default') - self.assertEquals(mark._state.db, 'other') - - # ...and the source database now has a copy of any object saved - try: - Book.objects.using('default').get(title='Dive into Python').delete() - except Book.DoesNotExist: - self.fail('Source database should have a copy of saved object') - - # This isn't a real master-slave database, so restore the original from other - dive = Book.objects.using('other').get(title='Dive into Python') - - # If you assign a FK object when the base object hasn't - # been saved yet, you implicitly assign the database for the - # base object. - chris = Person(name="Chris Mills") - html5 = Book(title="Dive into HTML5", published=datetime.date(2010, 3, 15)) - # initially, no db assigned - self.assertEquals(chris._state.db, None) - self.assertEquals(html5._state.db, None) - - # old object comes from 'other', so the new object is set to use the - # source of 'other'... - self.assertEquals(dive._state.db, 'other') - dive.editor = chris - html5.editor = mark - - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - self.assertEquals(chris._state.db, 'default') - self.assertEquals(html5._state.db, 'default') - - # This also works if you assign the FK in the constructor - water = Book(title="Dive into Water", published=datetime.date(2001, 1, 1), editor=mark) - self.assertEquals(water._state.db, 'default') - - # If you create an object through a FK relation, it will be - # written to the write database, even if the original object - # was on the read database - cheesecake = mark.edited.create(title='Dive into Cheesecake', published=datetime.date(2010, 3, 15)) - self.assertEquals(cheesecake._state.db, 'default') - - # Same goes for get_or_create, regardless of whether getting or creating - cheesecake, created = mark.edited.get_or_create(title='Dive into Cheesecake', published=datetime.date(2010, 3, 15)) - self.assertEquals(cheesecake._state.db, 'default') - - puddles, created = mark.edited.get_or_create(title='Dive into Puddles', published=datetime.date(2010, 3, 15)) - self.assertEquals(puddles._state.db, 'default') - - def test_m2m_cross_database_protection(self): - "M2M relations can cross databases if the database share a source" - # Create books and authors on the inverse to the usual database - pro = Book.objects.using('other').create(pk=1, title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.using('other').create(pk=1, name="Marty Alchin") - - dive = Book.objects.using('default').create(pk=2, title="Dive into Python", - published=datetime.date(2009, 5, 4)) - - mark = Person.objects.using('default').create(pk=2, name="Mark Pilgrim") - - # Now save back onto the usual databse. - # This simulates master/slave - the objects exist on both database, - # but the _state.db is as it is for all other tests. - pro.save(using='default') - marty.save(using='default') - dive.save(using='other') - mark.save(using='other') - - # Check that we have 2 of both types of object on both databases - self.assertEquals(Book.objects.using('default').count(), 2) - self.assertEquals(Book.objects.using('other').count(), 2) - self.assertEquals(Person.objects.using('default').count(), 2) - self.assertEquals(Person.objects.using('other').count(), 2) - - # Set a m2m set with an object from a different database - try: - marty.book_set = [pro, dive] - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments don't change - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - - # All m2m relations should be saved on the default database - self.assertEquals(Book.authors.through.objects.using('default').count(), 2) - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # Reset relations - Book.authors.through.objects.using('default').delete() - - # Add to an m2m with an object from a different database - try: - marty.book_set.add(dive) - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments don't change - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - - # All m2m relations should be saved on the default database - self.assertEquals(Book.authors.through.objects.using('default').count(), 1) - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # Reset relations - Book.authors.through.objects.using('default').delete() - - # Set a reverse m2m with an object from a different database - try: - dive.authors = [mark, marty] - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments don't change - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - - # All m2m relations should be saved on the default database - self.assertEquals(Book.authors.through.objects.using('default').count(), 2) - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # Reset relations - Book.authors.through.objects.using('default').delete() - - self.assertEquals(Book.authors.through.objects.using('default').count(), 0) - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # Add to a reverse m2m with an object from a different database - try: - dive.authors.add(marty) - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments don't change - self.assertEquals(marty._state.db, 'default') - self.assertEquals(pro._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(mark._state.db, 'other') - - # All m2m relations should be saved on the default database - self.assertEquals(Book.authors.through.objects.using('default').count(), 1) - self.assertEquals(Book.authors.through.objects.using('other').count(), 0) - - # If you create an object through a M2M relation, it will be - # written to the write database, even if the original object - # was on the read database - alice = dive.authors.create(name='Alice') - self.assertEquals(alice._state.db, 'default') - - # Same goes for get_or_create, regardless of whether getting or creating - alice, created = dive.authors.get_or_create(name='Alice') - self.assertEquals(alice._state.db, 'default') - - bob, created = dive.authors.get_or_create(name='Bob') - self.assertEquals(bob._state.db, 'default') - - def test_o2o_cross_database_protection(self): - "Operations that involve sharing FK objects across databases raise an error" - # Create a user and profile on the default database - alice = User.objects.db_manager('default').create_user('alice', 'alice@example.com') - - # Create a user and profile on the other database - bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com') - - # Set a one-to-one relation with an object from a different database - alice_profile = UserProfile.objects.create(user=alice, flavor='chocolate') - try: - bob.userprofile = alice_profile - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments of original objects haven't changed... - self.assertEquals(alice._state.db, 'default') - self.assertEquals(alice_profile._state.db, 'default') - self.assertEquals(bob._state.db, 'other') - - # ... but they will when the affected object is saved. - bob.save() - self.assertEquals(bob._state.db, 'default') - - def test_generic_key_cross_database_protection(self): - "Generic Key operations can span databases if they share a source" - # Create a book and author on the default database - pro = Book.objects.using('default' - ).create(title="Pro Django", published=datetime.date(2008, 12, 16)) - - review1 = Review.objects.using('default' - ).create(source="Python Monthly", content_object=pro) - - # Create a book and author on the other database - dive = Book.objects.using('other' - ).create(title="Dive into Python", published=datetime.date(2009, 5, 4)) - - review2 = Review.objects.using('other' - ).create(source="Python Weekly", content_object=dive) - - # Set a generic foreign key with an object from a different database - try: - review1.content_object = dive - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments of original objects haven't changed... - self.assertEquals(pro._state.db, 'default') - self.assertEquals(review1._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(review2._state.db, 'other') - - # ... but they will when the affected object is saved. - dive.save() - self.assertEquals(review1._state.db, 'default') - self.assertEquals(dive._state.db, 'default') - - # ...and the source database now has a copy of any object saved - try: - Book.objects.using('default').get(title='Dive into Python').delete() - except Book.DoesNotExist: - self.fail('Source database should have a copy of saved object') - - # This isn't a real master-slave database, so restore the original from other - dive = Book.objects.using('other').get(title='Dive into Python') - self.assertEquals(dive._state.db, 'other') - - # Add to a generic foreign key set with an object from a different database - try: - dive.reviews.add(review1) - except ValueError: - self.fail("Assignment across master/slave databases with a common source should be ok") - - # Database assignments of original objects haven't changed... - self.assertEquals(pro._state.db, 'default') - self.assertEquals(review1._state.db, 'default') - self.assertEquals(dive._state.db, 'other') - self.assertEquals(review2._state.db, 'other') - - # ... but they will when the affected object is saved. - dive.save() - self.assertEquals(dive._state.db, 'default') - - # ...and the source database now has a copy of any object saved - try: - Book.objects.using('default').get(title='Dive into Python').delete() - except Book.DoesNotExist: - self.fail('Source database should have a copy of saved object') - - # BUT! if you assign a FK object when the base object hasn't - # been saved yet, you implicitly assign the database for the - # base object. - review3 = Review(source="Python Daily") - # initially, no db assigned - self.assertEquals(review3._state.db, None) - - # Dive comes from 'other', so review3 is set to use the source of 'other'... - review3.content_object = dive - self.assertEquals(review3._state.db, 'default') - - # If you create an object through a M2M relation, it will be - # written to the write database, even if the original object - # was on the read database - dive = Book.objects.using('other').get(title='Dive into Python') - nyt = dive.reviews.create(source="New York Times", content_object=dive) - self.assertEquals(nyt._state.db, 'default') - - def test_m2m_managers(self): - "M2M relations are represented by managers, and can be controlled like managers" - pro = Book.objects.using('other').create(pk=1, title="Pro Django", - published=datetime.date(2008, 12, 16)) - - marty = Person.objects.using('other').create(pk=1, name="Marty Alchin") - pro.authors = [marty] - - self.assertEquals(pro.authors.db, 'other') - self.assertEquals(pro.authors.db_manager('default').db, 'default') - self.assertEquals(pro.authors.db_manager('default').all().db, 'default') - - self.assertEquals(marty.book_set.db, 'other') - self.assertEquals(marty.book_set.db_manager('default').db, 'default') - self.assertEquals(marty.book_set.db_manager('default').all().db, 'default') - - def test_foreign_key_managers(self): - "FK reverse relations are represented by managers, and can be controlled like managers" - marty = Person.objects.using('other').create(pk=1, name="Marty Alchin") - pro = Book.objects.using('other').create(pk=1, title="Pro Django", - published=datetime.date(2008, 12, 16), - editor=marty) - - self.assertEquals(marty.edited.db, 'other') - self.assertEquals(marty.edited.db_manager('default').db, 'default') - self.assertEquals(marty.edited.db_manager('default').all().db, 'default') - - def test_generic_key_managers(self): - "Generic key relations are represented by managers, and can be controlled like managers" - pro = Book.objects.using('other').create(title="Pro Django", - published=datetime.date(2008, 12, 16)) - - review1 = Review.objects.using('other').create(source="Python Monthly", - content_object=pro) - - self.assertEquals(pro.reviews.db, 'other') - self.assertEquals(pro.reviews.db_manager('default').db, 'default') - self.assertEquals(pro.reviews.db_manager('default').all().db, 'default') - - def test_subquery(self): - """Make sure as_sql works with subqueries and master/slave.""" - # Create a book and author on the other database - - mark = Person.objects.using('other').create(name="Mark Pilgrim") - dive = Book.objects.using('other').create(title="Dive into Python", - published=datetime.date(2009, 5, 4), - editor=mark) - - sub = Person.objects.filter(name='Mark Pilgrim') - qs = Book.objects.filter(editor__in=sub) - - # When you call __str__ on the query object, it doesn't know about using - # so it falls back to the default. Don't let routing instructions - # force the subquery to an incompatible database. - str(qs.query) - - # If you evaluate the query, it should work, running on 'other' - self.assertEquals(list(qs.values_list('title', flat=True)), [u'Dive into Python']) - -class AuthTestCase(TestCase): - multi_db = True - - def setUp(self): - # Make the 'other' database appear to be a slave of the 'default' - self.old_routers = router.routers - router.routers = [AuthRouter()] - - def tearDown(self): - # Restore the 'other' database as an independent database - router.routers = self.old_routers - - def test_auth_manager(self): - "The methods on the auth manager obey database hints" - # Create one user using default allocation policy - User.objects.create_user('alice', 'alice@example.com') - - # Create another user, explicitly specifying the database - User.objects.db_manager('default').create_user('bob', 'bob@example.com') - - # The second user only exists on the other database - alice = User.objects.using('other').get(username='alice') - - self.assertEquals(alice.username, 'alice') - self.assertEquals(alice._state.db, 'other') - - self.assertRaises(User.DoesNotExist, User.objects.using('default').get, username='alice') - - # The second user only exists on the default database - bob = User.objects.using('default').get(username='bob') - - self.assertEquals(bob.username, 'bob') - self.assertEquals(bob._state.db, 'default') - - self.assertRaises(User.DoesNotExist, User.objects.using('other').get, username='bob') - - # That is... there is one user on each database - self.assertEquals(User.objects.using('default').count(), 1) - self.assertEquals(User.objects.using('other').count(), 1) - - def test_dumpdata(self): - "Check that dumpdata honors allow_syncdb restrictions on the router" - User.objects.create_user('alice', 'alice@example.com') - User.objects.db_manager('default').create_user('bob', 'bob@example.com') - - # Check that dumping the default database doesn't try to include auth - # because allow_syncdb prohibits auth on default - new_io = StringIO() - management.call_command('dumpdata', 'auth', format='json', database='default', stdout=new_io) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, '[]') - - # Check that dumping the other database does include auth - new_io = StringIO() - management.call_command('dumpdata', 'auth', format='json', database='other', stdout=new_io) - command_output = new_io.getvalue().strip() - self.assertTrue('"email": "alice@example.com",' in command_output) - -_missing = object() -class UserProfileTestCase(TestCase): - def setUp(self): - self.old_auth_profile_module = getattr(settings, 'AUTH_PROFILE_MODULE', _missing) - settings.AUTH_PROFILE_MODULE = 'multiple_database.UserProfile' - - def tearDown(self): - if self.old_auth_profile_module is _missing: - del settings.AUTH_PROFILE_MODULE - else: - settings.AUTH_PROFILE_MODULE = self.old_auth_profile_module - - def test_user_profiles(self): - - alice = User.objects.create_user('alice', 'alice@example.com') - bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com') - - alice_profile = UserProfile(user=alice, flavor='chocolate') - alice_profile.save() - - bob_profile = UserProfile(user=bob, flavor='crunchy frog') - bob_profile.save() - - self.assertEquals(alice.get_profile().flavor, 'chocolate') - self.assertEquals(bob.get_profile().flavor, 'crunchy frog') - -class AntiPetRouter(object): - # A router that only expresses an opinion on syncdb, - # passing pets to the 'other' database - - def allow_syncdb(self, db, model): - "Make sure the auth app only appears on the 'other' db" - if db == 'other': - return model._meta.object_name == 'Pet' - else: - return model._meta.object_name != 'Pet' - return None - -class FixtureTestCase(TestCase): - multi_db = True - fixtures = ['multidb-common', 'multidb'] - - def setUp(self): - # Install the anti-pet router - self.old_routers = router.routers - router.routers = [AntiPetRouter()] - - def tearDown(self): - # Restore the 'other' database as an independent database - router.routers = self.old_routers - - def test_fixture_loading(self): - "Multi-db fixtures are loaded correctly" - # Check that "Pro Django" exists on the default database, but not on other database - try: - Book.objects.get(title="Pro Django") - Book.objects.using('default').get(title="Pro Django") - except Book.DoesNotExist: - self.fail('"Pro Django" should exist on default database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.using('other').get, - title="Pro Django" - ) - - # Check that "Dive into Python" exists on the default database, but not on other database - try: - Book.objects.using('other').get(title="Dive into Python") - except Book.DoesNotExist: - self.fail('"Dive into Python" should exist on other database') - - self.assertRaises(Book.DoesNotExist, - Book.objects.get, - title="Dive into Python" - ) - self.assertRaises(Book.DoesNotExist, - Book.objects.using('default').get, - title="Dive into Python" - ) - - # Check that "Definitive Guide" exists on the both databases - try: - Book.objects.get(title="The Definitive Guide to Django") - Book.objects.using('default').get(title="The Definitive Guide to Django") - Book.objects.using('other').get(title="The Definitive Guide to Django") - except Book.DoesNotExist: - self.fail('"The Definitive Guide to Django" should exist on both databases') - - def test_pseudo_empty_fixtures(self): - "A fixture can contain entries, but lead to nothing in the database; this shouldn't raise an error (ref #14068)" - new_io = StringIO() - management.call_command('loaddata', 'pets', stdout=new_io, stderr=new_io) - command_output = new_io.getvalue().strip() - # No objects will actually be loaded - self.assertTrue("Installed 0 object(s) (of 2) from 1 fixture(s)" in command_output) - -class PickleQuerySetTestCase(TestCase): - multi_db = True - - def test_pickling(self): - for db in connections: - Book.objects.using(db).create(title='Dive into Python', published=datetime.date(2009, 5, 4)) - qs = Book.objects.all() - self.assertEqual(qs.db, pickle.loads(pickle.dumps(qs)).db) diff --git a/parts/django/tests/regressiontests/null_fk/__init__.py b/parts/django/tests/regressiontests/null_fk/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/null_fk/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/null_fk/models.py b/parts/django/tests/regressiontests/null_fk/models.py deleted file mode 100644 index 3cce319..0000000 --- a/parts/django/tests/regressiontests/null_fk/models.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -Regression tests for proper working of ForeignKey(null=True). -""" - -from django.db import models - -class SystemDetails(models.Model): - details = models.TextField() - -class SystemInfo(models.Model): - system_details = models.ForeignKey(SystemDetails) - system_name = models.CharField(max_length=32) - -class Forum(models.Model): - system_info = models.ForeignKey(SystemInfo) - forum_name = models.CharField(max_length=32) - -class Post(models.Model): - forum = models.ForeignKey(Forum, null=True) - title = models.CharField(max_length=32) - - def __unicode__(self): - return self.title - -class Comment(models.Model): - post = models.ForeignKey(Post, null=True) - comment_text = models.CharField(max_length=250) - - class Meta: - ordering = ('comment_text',) - - def __unicode__(self): - return self.comment_text diff --git a/parts/django/tests/regressiontests/null_fk/tests.py b/parts/django/tests/regressiontests/null_fk/tests.py deleted file mode 100644 index 449f343..0000000 --- a/parts/django/tests/regressiontests/null_fk/tests.py +++ /dev/null @@ -1,42 +0,0 @@ -from django.test import TestCase - -from regressiontests.null_fk.models import * - -class NullFkTests(TestCase): - - def test_null_fk(self): - d = SystemDetails.objects.create(details='First details') - s = SystemInfo.objects.create(system_name='First forum', system_details=d) - f = Forum.objects.create(system_info=s, forum_name='First forum') - p = Post.objects.create(forum=f, title='First Post') - c1 = Comment.objects.create(post=p, comment_text='My first comment') - c2 = Comment.objects.create(comment_text='My second comment') - - # Starting from comment, make sure that a .select_related(...) with a specified - # set of fields will properly LEFT JOIN multiple levels of NULLs (and the things - # that come after the NULLs, or else data that should exist won't). Regression - # test for #7369. - c = Comment.objects.select_related().get(id=1) - self.assertEquals(c.post, p) - self.assertEquals(Comment.objects.select_related().get(id=2).post, None) - - self.assertQuerysetEqual( - Comment.objects.select_related('post__forum__system_info').all(), - [ - (1, u'My first comment', '<Post: First Post>'), - (2, u'My second comment', 'None') - ], - transform = lambda c: (c.id, c.comment_text, repr(c.post)) - ) - - # Regression test for #7530, #7716. - self.assertTrue(Comment.objects.select_related('post').filter(post__isnull=True)[0].post is None) - - self.assertQuerysetEqual( - Comment.objects.select_related('post__forum__system_info__system_details'), - [ - (1, u'My first comment', '<Post: First Post>'), - (2, u'My second comment', 'None') - ], - transform = lambda c: (c.id, c.comment_text, repr(c.post)) - ) diff --git a/parts/django/tests/regressiontests/null_fk_ordering/__init__.py b/parts/django/tests/regressiontests/null_fk_ordering/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/null_fk_ordering/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/null_fk_ordering/models.py b/parts/django/tests/regressiontests/null_fk_ordering/models.py deleted file mode 100644 index d0635e8..0000000 --- a/parts/django/tests/regressiontests/null_fk_ordering/models.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Regression tests for proper working of ForeignKey(null=True). Tests these bugs: - - * #7512: including a nullable foreign key reference in Meta ordering has un -xpected results - -""" - -from django.db import models - -# The first two models represent a very simple null FK ordering case. -class Author(models.Model): - name = models.CharField(max_length=150) - -class Article(models.Model): - title = models.CharField(max_length=150) - author = models.ForeignKey(Author, null=True) - - def __unicode__(self): - return u'Article titled: %s' % (self.title, ) - - class Meta: - ordering = ['author__name', ] - - -# These following 4 models represent a far more complex ordering case. -class SystemInfo(models.Model): - system_name = models.CharField(max_length=32) - -class Forum(models.Model): - system_info = models.ForeignKey(SystemInfo) - forum_name = models.CharField(max_length=32) - -class Post(models.Model): - forum = models.ForeignKey(Forum, null=True) - title = models.CharField(max_length=32) - - def __unicode__(self): - return self.title - -class Comment(models.Model): - post = models.ForeignKey(Post, null=True) - comment_text = models.CharField(max_length=250) - - class Meta: - ordering = ['post__forum__system_info__system_name', 'comment_text'] - - def __unicode__(self): - return self.comment_text diff --git a/parts/django/tests/regressiontests/null_fk_ordering/tests.py b/parts/django/tests/regressiontests/null_fk_ordering/tests.py deleted file mode 100644 index c9ee4f7..0000000 --- a/parts/django/tests/regressiontests/null_fk_ordering/tests.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.test import TestCase - -from regressiontests.null_fk_ordering.models import * - -class NullFkOrderingTests(TestCase): - - def test_ordering_across_null_fk(self): - """ - Regression test for #7512 - - ordering across nullable Foreign Keys shouldn't exclude results - """ - author_1 = Author.objects.create(name='Tom Jones') - author_2 = Author.objects.create(name='Bob Smith') - article_1 = Article.objects.create(title='No author on this article') - article_2 = Article.objects.create(author=author_1, title='This article written by Tom Jones') - article_3 = Article.objects.create(author=author_2, title='This article written by Bob Smith') - - # We can't compare results directly (since different databases sort NULLs to - # different ends of the ordering), but we can check that all results are - # returned. - self.assertTrue(len(list(Article.objects.all())) == 3) - - s = SystemInfo.objects.create(system_name='System Info') - f = Forum.objects.create(system_info=s, forum_name='First forum') - p = Post.objects.create(forum=f, title='First Post') - c1 = Comment.objects.create(post=p, comment_text='My first comment') - c2 = Comment.objects.create(comment_text='My second comment') - s2 = SystemInfo.objects.create(system_name='More System Info') - f2 = Forum.objects.create(system_info=s2, forum_name='Second forum') - p2 = Post.objects.create(forum=f2, title='Second Post') - c3 = Comment.objects.create(comment_text='Another first comment') - c4 = Comment.objects.create(post=p2, comment_text='Another second comment') - - # We have to test this carefully. Some databases sort NULL values before - # everything else, some sort them afterwards. So we extract the ordered list - # and check the length. Before the fix, this list was too short (some values - # were omitted). - self.assertTrue(len(list(Comment.objects.all())) == 4) diff --git a/parts/django/tests/regressiontests/null_queries/__init__.py b/parts/django/tests/regressiontests/null_queries/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/null_queries/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/null_queries/models.py b/parts/django/tests/regressiontests/null_queries/models.py deleted file mode 100644 index 442535c..0000000 --- a/parts/django/tests/regressiontests/null_queries/models.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.db import models - -class Poll(models.Model): - question = models.CharField(max_length=200) - - def __unicode__(self): - return u"Q: %s " % self.question - -class Choice(models.Model): - poll = models.ForeignKey(Poll) - choice = models.CharField(max_length=200) - - def __unicode__(self): - return u"Choice: %s in poll %s" % (self.choice, self.poll) - -# A set of models with an inner one pointing to two outer ones. -class OuterA(models.Model): - pass - -class OuterB(models.Model): - data = models.CharField(max_length=10) - -class Inner(models.Model): - first = models.ForeignKey(OuterA) - second = models.ForeignKey(OuterB, null=True) diff --git a/parts/django/tests/regressiontests/null_queries/tests.py b/parts/django/tests/regressiontests/null_queries/tests.py deleted file mode 100644 index 72dcd51..0000000 --- a/parts/django/tests/regressiontests/null_queries/tests.py +++ /dev/null @@ -1,69 +0,0 @@ -from django.test import TestCase -from django.core.exceptions import FieldError - -from regressiontests.null_queries.models import * - - -class NullQueriesTests(TestCase): - - def test_none_as_null(self): - """ - Regression test for the use of None as a query value. - - None is interpreted as an SQL NULL, but only in __exact queries. - Set up some initial polls and choices - """ - p1 = Poll(question='Why?') - p1.save() - c1 = Choice(poll=p1, choice='Because.') - c1.save() - c2 = Choice(poll=p1, choice='Why Not?') - c2.save() - - # Exact query with value None returns nothing ("is NULL" in sql, - # but every 'id' field has a value). - self.assertQuerysetEqual(Choice.objects.filter(choice__exact=None), []) - - # Excluding the previous result returns everything. - self.assertQuerysetEqual( - Choice.objects.exclude(choice=None).order_by('id'), - [ - '<Choice: Choice: Because. in poll Q: Why? >', - '<Choice: Choice: Why Not? in poll Q: Why? >' - ] - ) - - # Valid query, but fails because foo isn't a keyword - self.assertRaises(FieldError, Choice.objects.filter, foo__exact=None) - - # Can't use None on anything other than __exact - self.assertRaises(ValueError, Choice.objects.filter, id__gt=None) - - # Can't use None on anything other than __exact - self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None) - - # Related managers use __exact=None implicitly if the object hasn't been saved. - p2 = Poll(question="How?") - self.assertEquals(repr(p2.choice_set.all()), '[]') - - def test_reverse_relations(self): - """ - Querying across reverse relations and then another relation should - insert outer joins correctly so as not to exclude results. - """ - obj = OuterA.objects.create() - self.assertQuerysetEqual( - OuterA.objects.filter(inner__second=None), - ['<OuterA: OuterA object>'] - ) - self.assertQuerysetEqual( - OuterA.objects.filter(inner__second__data=None), - ['<OuterA: OuterA object>'] - ) - - inner_obj = Inner.objects.create(first=obj) - self.assertQuerysetEqual( - Inner.objects.filter(first__inner__second=None), - ['<Inner: Inner object>'] - ) - diff --git a/parts/django/tests/regressiontests/one_to_one_regress/__init__.py b/parts/django/tests/regressiontests/one_to_one_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/one_to_one_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/one_to_one_regress/models.py b/parts/django/tests/regressiontests/one_to_one_regress/models.py deleted file mode 100644 index a7edbc0..0000000 --- a/parts/django/tests/regressiontests/one_to_one_regress/models.py +++ /dev/null @@ -1,43 +0,0 @@ -from django.db import models - -class Place(models.Model): - name = models.CharField(max_length=50) - address = models.CharField(max_length=80) - - 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 __unicode__(self): - return u"%s the restaurant" % self.place.name - -class Bar(models.Model): - place = models.OneToOneField(Place) - serves_cocktails = models.BooleanField() - - def __unicode__(self): - return u"%s the bar" % self.place.name - -class UndergroundBar(models.Model): - place = models.OneToOneField(Place, null=True) - serves_cocktails = models.BooleanField() - -class Favorites(models.Model): - name = models.CharField(max_length = 50) - restaurants = models.ManyToManyField(Restaurant) - - def __unicode__(self): - return u"Favorites for %s" % self.name - -class Target(models.Model): - pass - -class Pointer(models.Model): - other = models.OneToOneField(Target, primary_key=True) - -class Pointer2(models.Model): - other = models.OneToOneField(Target) diff --git a/parts/django/tests/regressiontests/one_to_one_regress/tests.py b/parts/django/tests/regressiontests/one_to_one_regress/tests.py deleted file mode 100644 index 8787575..0000000 --- a/parts/django/tests/regressiontests/one_to_one_regress/tests.py +++ /dev/null @@ -1,130 +0,0 @@ -from django.test import TestCase -from regressiontests.one_to_one_regress.models import * - -class OneToOneRegressionTests(TestCase): - - def setUp(self): - self.p1 = Place(name='Demon Dogs', address='944 W. Fullerton') - self.p1.save() - self.r1 = Restaurant(place=self.p1, serves_hot_dogs=True, serves_pizza=False) - self.r1.save() - self.b1 = Bar(place=self.p1, serves_cocktails=False) - self.b1.save() - - def test_reverse_relationship_cache_cascade(self): - """ - Regression test for #9023: accessing the reverse relationship shouldn't - result in a cascading delete(). - """ - bar = UndergroundBar.objects.create(place=self.p1, serves_cocktails=False) - - # The bug in #9023: if you access the one-to-one relation *before* - # setting to None and deleting, the cascade happens anyway. - self.p1.undergroundbar - bar.place.name='foo' - bar.place = None - bar.save() - self.p1.delete() - - self.assertEqual(Place.objects.all().count(), 0) - self.assertEqual(UndergroundBar.objects.all().count(), 1) - - def test_create_models_m2m(self): - """ - Regression test for #1064 and #1506 - - Check that we create models via the m2m relation if the remote model - has a OneToOneField. - """ - f = Favorites(name = 'Fred') - f.save() - f.restaurants = [self.r1] - self.assertQuerysetEqual( - f.restaurants.all(), - ['<Restaurant: Demon Dogs the restaurant>'] - ) - - def test_reverse_object_cache(self): - """ - Regression test for #7173 - - Check that the name of the cache for the reverse object is correct. - """ - self.assertEquals(self.p1.restaurant, self.r1) - self.assertEquals(self.p1.bar, self.b1) - - def test_related_object_cache(self): - """ Regression test for #6886 (the related-object cache) """ - - # Look up the objects again so that we get "fresh" objects - p = Place.objects.get(name="Demon Dogs") - r = p.restaurant - - # Accessing the related object again returns the exactly same object - self.assertTrue(p.restaurant is r) - - # But if we kill the cache, we get a new object - del p._restaurant_cache - self.assertFalse(p.restaurant is r) - - # Reassigning the Restaurant object results in an immediate cache update - # We can't use a new Restaurant because that'll violate one-to-one, but - # with a new *instance* the is test below will fail if #6886 regresses. - r2 = Restaurant.objects.get(pk=r.pk) - p.restaurant = r2 - self.assertTrue(p.restaurant is r2) - - # Assigning None succeeds if field is null=True. - ug_bar = UndergroundBar.objects.create(place=p, serves_cocktails=False) - ug_bar.place = None - self.assertTrue(ug_bar.place is None) - - # Assigning None fails: Place.restaurant is null=False - self.assertRaises(ValueError, setattr, p, 'restaurant', None) - - # You also can't assign an object of the wrong type here - self.assertRaises(ValueError, setattr, p, 'restaurant', p) - - # Creation using keyword argument should cache the related object. - p = Place.objects.get(name="Demon Dogs") - r = Restaurant(place=p) - self.assertTrue(r.place is p) - - # Creation using keyword argument and unsaved related instance (#8070). - p = Place() - r = Restaurant(place=p) - self.assertTrue(r.place is p) - - # Creation using attname keyword argument and an id will cause the related - # object to be fetched. - p = Place.objects.get(name="Demon Dogs") - r = Restaurant(place_id=p.id) - self.assertFalse(r.place is p) - self.assertEqual(r.place, p) - - def test_filter_one_to_one_relations(self): - """ - Regression test for #9968 - - filtering reverse one-to-one relations with primary_key=True was - misbehaving. We test both (primary_key=True & False) cases here to - prevent any reappearance of the problem. - """ - t = Target.objects.create() - - self.assertQuerysetEqual( - Target.objects.filter(pointer=None), - ['<Target: Target object>'] - ) - self.assertQuerysetEqual( - Target.objects.exclude(pointer=None), - [] - ) - self.assertQuerysetEqual( - Target.objects.filter(pointer2=None), - ['<Target: Target object>'] - ) - self.assertQuerysetEqual( - Target.objects.exclude(pointer2=None), - [] - ) diff --git a/parts/django/tests/regressiontests/pagination_regress/__init__.py b/parts/django/tests/regressiontests/pagination_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/pagination_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/pagination_regress/models.py b/parts/django/tests/regressiontests/pagination_regress/models.py deleted file mode 100644 index cde172d..0000000 --- a/parts/django/tests/regressiontests/pagination_regress/models.py +++ /dev/null @@ -1 +0,0 @@ -# Models file for tests to run. diff --git a/parts/django/tests/regressiontests/pagination_regress/tests.py b/parts/django/tests/regressiontests/pagination_regress/tests.py deleted file mode 100644 index 08436df..0000000 --- a/parts/django/tests/regressiontests/pagination_regress/tests.py +++ /dev/null @@ -1,157 +0,0 @@ -from unittest import TestCase - -from django.core.paginator import Paginator, EmptyPage - -class PaginatorTests(TestCase): - """ - Tests for the Paginator and Page classes. - """ - - def check_paginator(self, params, output): - """ - Helper method that instantiates a Paginator object from the passed - params and then checks that its attributes match the passed output. - """ - count, num_pages, page_range = output - paginator = Paginator(*params) - self.check_attribute('count', paginator, count, params) - self.check_attribute('num_pages', paginator, num_pages, params) - self.check_attribute('page_range', paginator, page_range, params) - - def check_attribute(self, name, paginator, expected, params): - """ - Helper method that checks a single attribute and gives a nice error - message upon test failure. - """ - got = getattr(paginator, name) - self.assertEqual(expected, got, - "For '%s', expected %s but got %s. Paginator parameters were: %s" - % (name, expected, got, params)) - - def test_paginator(self): - """ - Tests the paginator attributes using varying inputs. - """ - nine = [1, 2, 3, 4, 5, 6, 7, 8, 9] - ten = nine + [10] - eleven = ten + [11] - tests = ( - # Each item is two tuples: - # First tuple is Paginator parameters - object_list, per_page, - # orphans, and allow_empty_first_page. - # Second tuple is resulting Paginator attributes - count, - # num_pages, and page_range. - # Ten items, varying orphans, no empty first page. - ((ten, 4, 0, False), (10, 3, [1, 2, 3])), - ((ten, 4, 1, False), (10, 3, [1, 2, 3])), - ((ten, 4, 2, False), (10, 2, [1, 2])), - ((ten, 4, 5, False), (10, 2, [1, 2])), - ((ten, 4, 6, False), (10, 1, [1])), - # Ten items, varying orphans, allow empty first page. - ((ten, 4, 0, True), (10, 3, [1, 2, 3])), - ((ten, 4, 1, True), (10, 3, [1, 2, 3])), - ((ten, 4, 2, True), (10, 2, [1, 2])), - ((ten, 4, 5, True), (10, 2, [1, 2])), - ((ten, 4, 6, True), (10, 1, [1])), - # One item, varying orphans, no empty first page. - (([1], 4, 0, False), (1, 1, [1])), - (([1], 4, 1, False), (1, 1, [1])), - (([1], 4, 2, False), (1, 1, [1])), - # One item, varying orphans, allow empty first page. - (([1], 4, 0, True), (1, 1, [1])), - (([1], 4, 1, True), (1, 1, [1])), - (([1], 4, 2, True), (1, 1, [1])), - # Zero items, varying orphans, no empty first page. - (([], 4, 0, False), (0, 0, [])), - (([], 4, 1, False), (0, 0, [])), - (([], 4, 2, False), (0, 0, [])), - # Zero items, varying orphans, allow empty first page. - (([], 4, 0, True), (0, 1, [1])), - (([], 4, 1, True), (0, 1, [1])), - (([], 4, 2, True), (0, 1, [1])), - # Number if items one less than per_page. - (([], 1, 0, True), (0, 1, [1])), - (([], 1, 0, False), (0, 0, [])), - (([1], 2, 0, True), (1, 1, [1])), - ((nine, 10, 0, True), (9, 1, [1])), - # Number if items equal to per_page. - (([1], 1, 0, True), (1, 1, [1])), - (([1, 2], 2, 0, True), (2, 1, [1])), - ((ten, 10, 0, True), (10, 1, [1])), - # Number if items one more than per_page. - (([1, 2], 1, 0, True), (2, 2, [1, 2])), - (([1, 2, 3], 2, 0, True), (3, 2, [1, 2])), - ((eleven, 10, 0, True), (11, 2, [1, 2])), - # Number if items one more than per_page with one orphan. - (([1, 2], 1, 1, True), (2, 1, [1])), - (([1, 2, 3], 2, 1, True), (3, 1, [1])), - ((eleven, 10, 1, True), (11, 1, [1])), - ) - for params, output in tests: - self.check_paginator(params, output) - - def check_indexes(self, params, page_num, indexes): - """ - Helper method that instantiates a Paginator object from the passed - params and then checks that the start and end indexes of the passed - page_num match those given as a 2-tuple in indexes. - """ - paginator = Paginator(*params) - if page_num == 'first': - page_num = 1 - elif page_num == 'last': - page_num = paginator.num_pages - page = paginator.page(page_num) - start, end = indexes - msg = ("For %s of page %s, expected %s but got %s." - " Paginator parameters were: %s") - self.assertEqual(start, page.start_index(), - msg % ('start index', page_num, start, page.start_index(), params)) - self.assertEqual(end, page.end_index(), - msg % ('end index', page_num, end, page.end_index(), params)) - - def test_page_indexes(self): - """ - Tests that paginator pages have the correct start and end indexes. - """ - ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - tests = ( - # Each item is three tuples: - # First tuple is Paginator parameters - object_list, per_page, - # orphans, and allow_empty_first_page. - # Second tuple is the start and end indexes of the first page. - # Third tuple is the start and end indexes of the last page. - # Ten items, varying per_page, no orphans. - ((ten, 1, 0, True), (1, 1), (10, 10)), - ((ten, 2, 0, True), (1, 2), (9, 10)), - ((ten, 3, 0, True), (1, 3), (10, 10)), - ((ten, 5, 0, True), (1, 5), (6, 10)), - # Ten items, varying per_page, with orphans. - ((ten, 1, 1, True), (1, 1), (9, 10)), - ((ten, 1, 2, True), (1, 1), (8, 10)), - ((ten, 3, 1, True), (1, 3), (7, 10)), - ((ten, 3, 2, True), (1, 3), (7, 10)), - ((ten, 3, 4, True), (1, 3), (4, 10)), - ((ten, 5, 1, True), (1, 5), (6, 10)), - ((ten, 5, 2, True), (1, 5), (6, 10)), - ((ten, 5, 5, True), (1, 10), (1, 10)), - # One item, varying orphans, no empty first page. - (([1], 4, 0, False), (1, 1), (1, 1)), - (([1], 4, 1, False), (1, 1), (1, 1)), - (([1], 4, 2, False), (1, 1), (1, 1)), - # One item, varying orphans, allow empty first page. - (([1], 4, 0, True), (1, 1), (1, 1)), - (([1], 4, 1, True), (1, 1), (1, 1)), - (([1], 4, 2, True), (1, 1), (1, 1)), - # Zero items, varying orphans, allow empty first page. - (([], 4, 0, True), (0, 0), (0, 0)), - (([], 4, 1, True), (0, 0), (0, 0)), - (([], 4, 2, True), (0, 0), (0, 0)), - ) - for params, first, last in tests: - self.check_indexes(params, 'first', first) - self.check_indexes(params, 'last', last) - # When no items and no empty first page, we should get EmptyPage error. - self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 0, False), 1, None) - self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 1, False), 1, None) - self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 2, False), 1, None) diff --git a/parts/django/tests/regressiontests/queries/__init__.py b/parts/django/tests/regressiontests/queries/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/queries/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/queries/models.py b/parts/django/tests/regressiontests/queries/models.py deleted file mode 100644 index 5247ef9..0000000 --- a/parts/django/tests/regressiontests/queries/models.py +++ /dev/null @@ -1,276 +0,0 @@ -""" -Various complex queries that have been problematic in the past. -""" - -import threading - -from django.db import models - -class DumbCategory(models.Model): - pass - -class NamedCategory(DumbCategory): - name = models.CharField(max_length=10) - -class Tag(models.Model): - name = models.CharField(max_length=10) - parent = models.ForeignKey('self', blank=True, null=True, - related_name='children') - category = models.ForeignKey(NamedCategory, null=True, default=None) - - class Meta: - ordering = ['name'] - - def __unicode__(self): - return self.name - -class Note(models.Model): - note = models.CharField(max_length=100) - misc = models.CharField(max_length=10) - - class Meta: - ordering = ['note'] - - def __unicode__(self): - return self.note - - def __init__(self, *args, **kwargs): - super(Note, self).__init__(*args, **kwargs) - # Regression for #13227 -- having an attribute that - # is unpickleable doesn't stop you from cloning queries - # that use objects of that type as an argument. - self.lock = threading.Lock() - -class Annotation(models.Model): - name = models.CharField(max_length=10) - tag = models.ForeignKey(Tag) - notes = models.ManyToManyField(Note) - - def __unicode__(self): - return self.name - -class ExtraInfo(models.Model): - info = models.CharField(max_length=100) - note = models.ForeignKey(Note) - - class Meta: - ordering = ['info'] - - def __unicode__(self): - return self.info - -class Author(models.Model): - name = models.CharField(max_length=10) - num = models.IntegerField(unique=True) - extra = models.ForeignKey(ExtraInfo) - - class Meta: - ordering = ['name'] - - def __unicode__(self): - return self.name - -class Item(models.Model): - name = models.CharField(max_length=10) - created = models.DateTimeField() - modified = models.DateTimeField(blank=True, null=True) - tags = models.ManyToManyField(Tag, blank=True, null=True) - creator = models.ForeignKey(Author) - note = models.ForeignKey(Note) - - class Meta: - ordering = ['-note', 'name'] - - def __unicode__(self): - return self.name - -class Report(models.Model): - name = models.CharField(max_length=10) - creator = models.ForeignKey(Author, to_field='num', null=True) - - def __unicode__(self): - return self.name - -class Ranking(models.Model): - rank = models.IntegerField() - author = models.ForeignKey(Author) - - class Meta: - # A complex ordering specification. Should stress the system a bit. - ordering = ('author__extra__note', 'author__name', 'rank') - - def __unicode__(self): - return '%d: %s' % (self.rank, self.author.name) - -class Cover(models.Model): - title = models.CharField(max_length=50) - item = models.ForeignKey(Item) - - class Meta: - ordering = ['item'] - - def __unicode__(self): - return self.title - -class Number(models.Model): - num = models.IntegerField() - - def __unicode__(self): - return unicode(self.num) - -# Symmetrical m2m field with a normal field using the reverse accesor name -# ("valid"). -class Valid(models.Model): - valid = models.CharField(max_length=10) - parent = models.ManyToManyField('self') - - class Meta: - ordering = ['valid'] - -# Some funky cross-linked models for testing a couple of infinite recursion -# cases. -class X(models.Model): - y = models.ForeignKey('Y') - -class Y(models.Model): - x1 = models.ForeignKey(X, related_name='y1') - -# Some models with a cycle in the default ordering. This would be bad if we -# didn't catch the infinite loop. -class LoopX(models.Model): - y = models.ForeignKey('LoopY') - - class Meta: - ordering = ['y'] - -class LoopY(models.Model): - x = models.ForeignKey(LoopX) - - class Meta: - ordering = ['x'] - -class LoopZ(models.Model): - z = models.ForeignKey('self') - - class Meta: - ordering = ['z'] - -# A model and custom default manager combination. -class CustomManager(models.Manager): - def get_query_set(self): - qs = super(CustomManager, self).get_query_set() - return qs.filter(public=True, tag__name='t1') - -class ManagedModel(models.Model): - data = models.CharField(max_length=10) - tag = models.ForeignKey(Tag) - public = models.BooleanField(default=True) - - objects = CustomManager() - normal_manager = models.Manager() - - def __unicode__(self): - return self.data - -# An inter-related setup with multiple paths from Child to Detail. -class Detail(models.Model): - data = models.CharField(max_length=10) - -class MemberManager(models.Manager): - def get_query_set(self): - return super(MemberManager, self).get_query_set().select_related("details") - -class Member(models.Model): - name = models.CharField(max_length=10) - details = models.OneToOneField(Detail, primary_key=True) - - objects = MemberManager() - -class Child(models.Model): - person = models.OneToOneField(Member, primary_key=True) - parent = models.ForeignKey(Member, related_name="children") - -# Custom primary keys interfered with ordering in the past. -class CustomPk(models.Model): - name = models.CharField(max_length=10, primary_key=True) - extra = models.CharField(max_length=10) - - class Meta: - ordering = ['name', 'extra'] - -class Related(models.Model): - custom = models.ForeignKey(CustomPk) - -# An inter-related setup with a model subclass that has a nullable -# path to another model, and a return path from that model. - -class Celebrity(models.Model): - name = models.CharField("Name", max_length=20) - greatest_fan = models.ForeignKey("Fan", null=True, unique=True) - -class TvChef(Celebrity): - pass - -class Fan(models.Model): - fan_of = models.ForeignKey(Celebrity) - -# Multiple foreign keys -class LeafA(models.Model): - data = models.CharField(max_length=10) - - def __unicode__(self): - return self.data - -class LeafB(models.Model): - data = models.CharField(max_length=10) - -class Join(models.Model): - a = models.ForeignKey(LeafA) - b = models.ForeignKey(LeafB) - -class ReservedName(models.Model): - name = models.CharField(max_length=20) - order = models.IntegerField() - - def __unicode__(self): - return self.name - -# A simpler shared-foreign-key setup that can expose some problems. -class SharedConnection(models.Model): - data = models.CharField(max_length=10) - -class PointerA(models.Model): - connection = models.ForeignKey(SharedConnection) - -class PointerB(models.Model): - connection = models.ForeignKey(SharedConnection) - -# Multi-layer ordering -class SingleObject(models.Model): - name = models.CharField(max_length=10) - - class Meta: - ordering = ['name'] - - def __unicode__(self): - return self.name - -class RelatedObject(models.Model): - single = models.ForeignKey(SingleObject) - - class Meta: - ordering = ['single'] - -class Plaything(models.Model): - name = models.CharField(max_length=10) - others = models.ForeignKey(RelatedObject, null=True) - - class Meta: - ordering = ['others'] - - def __unicode__(self): - return self.name - -class Article(models.Model): - name = models.CharField(max_length=20) - created = models.DateTimeField() diff --git a/parts/django/tests/regressiontests/queries/tests.py b/parts/django/tests/regressiontests/queries/tests.py deleted file mode 100644 index 741b33c..0000000 --- a/parts/django/tests/regressiontests/queries/tests.py +++ /dev/null @@ -1,1586 +0,0 @@ -import datetime -import pickle -import sys -import unittest - -from django.conf import settings -from django.core.exceptions import FieldError -from django.db import DatabaseError, connection, connections, DEFAULT_DB_ALIAS -from django.db.models import Count -from django.db.models.query import Q, ITER_CHUNK_SIZE, EmptyQuerySet -from django.test import TestCase -from django.utils.datastructures import SortedDict - -from models import (Annotation, Article, Author, Celebrity, Child, Cover, Detail, - DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ, ManagedModel, - Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related, - Report, ReservedName, Tag, TvChef, Valid, X) - - -class BaseQuerysetTest(TestCase): - def assertValueQuerysetEqual(self, qs, values): - return self.assertQuerysetEqual(qs, values, transform=lambda x: x) - - def assertRaisesMessage(self, exc, msg, func, *args, **kwargs): - try: - func(*args, **kwargs) - except Exception, e: - self.assertEqual(msg, str(e)) - self.assertTrue(isinstance(e, exc), "Expected %s, got %s" % (exc, type(e))) - else: - if hasattr(exc, '__name__'): - excName = exc.__name__ - else: - excName = str(exc) - raise AssertionError, "%s not raised" % excName - - -class Queries1Tests(BaseQuerysetTest): - def setUp(self): - generic = NamedCategory.objects.create(name="Generic") - self.t1 = Tag.objects.create(name='t1', category=generic) - self.t2 = Tag.objects.create(name='t2', parent=self.t1, category=generic) - self.t3 = Tag.objects.create(name='t3', parent=self.t1) - t4 = Tag.objects.create(name='t4', parent=self.t3) - self.t5 = Tag.objects.create(name='t5', parent=self.t3) - - self.n1 = Note.objects.create(note='n1', misc='foo', id=1) - n2 = Note.objects.create(note='n2', misc='bar', id=2) - self.n3 = Note.objects.create(note='n3', misc='foo', id=3) - - ann1 = Annotation.objects.create(name='a1', tag=self.t1) - ann1.notes.add(self.n1) - ann2 = Annotation.objects.create(name='a2', tag=t4) - ann2.notes.add(n2, self.n3) - - # Create these out of order so that sorting by 'id' will be different to sorting - # by 'info'. Helps detect some problems later. - self.e2 = ExtraInfo.objects.create(info='e2', note=n2) - e1 = ExtraInfo.objects.create(info='e1', note=self.n1) - - self.a1 = Author.objects.create(name='a1', num=1001, extra=e1) - self.a2 = Author.objects.create(name='a2', num=2002, extra=e1) - a3 = Author.objects.create(name='a3', num=3003, extra=self.e2) - self.a4 = Author.objects.create(name='a4', num=4004, extra=self.e2) - - self.time1 = datetime.datetime(2007, 12, 19, 22, 25, 0) - self.time2 = datetime.datetime(2007, 12, 19, 21, 0, 0) - time3 = datetime.datetime(2007, 12, 20, 22, 25, 0) - time4 = datetime.datetime(2007, 12, 20, 21, 0, 0) - self.i1 = Item.objects.create(name='one', created=self.time1, modified=self.time1, creator=self.a1, note=self.n3) - self.i1.tags = [self.t1, self.t2] - self.i2 = Item.objects.create(name='two', created=self.time2, creator=self.a2, note=n2) - self.i2.tags = [self.t1, self.t3] - self.i3 = Item.objects.create(name='three', created=time3, creator=self.a2, note=self.n3) - i4 = Item.objects.create(name='four', created=time4, creator=self.a4, note=self.n3) - i4.tags = [t4] - - self.r1 = Report.objects.create(name='r1', creator=self.a1) - Report.objects.create(name='r2', creator=a3) - Report.objects.create(name='r3') - - # Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering - # will be rank3, rank2, rank1. - self.rank1 = Ranking.objects.create(rank=2, author=self.a2) - - Cover.objects.create(title="first", item=i4) - Cover.objects.create(title="second", item=self.i2) - - def test_ticket1050(self): - self.assertQuerysetEqual( - Item.objects.filter(tags__isnull=True), - ['<Item: three>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(tags__id__isnull=True), - ['<Item: three>'] - ) - - def test_ticket1801(self): - self.assertQuerysetEqual( - Author.objects.filter(item=self.i2), - ['<Author: a2>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(item=self.i3), - ['<Author: a2>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(item=self.i2) & Author.objects.filter(item=self.i3), - ['<Author: a2>'] - ) - - def test_ticket2306(self): - # Checking that no join types are "left outer" joins. - query = Item.objects.filter(tags=self.t2).query - self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()]) - - self.assertQuerysetEqual( - Item.objects.filter(Q(tags=self.t1)).order_by('name'), - ['<Item: one>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(Q(tags=self.t1)).filter(Q(tags=self.t2)), - ['<Item: one>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(Q(tags=self.t1)).filter(Q(creator__name='fred')|Q(tags=self.t2)), - ['<Item: one>'] - ) - - # Each filter call is processed "at once" against a single table, so this is - # different from the previous example as it tries to find tags that are two - # things at once (rather than two tags). - self.assertQuerysetEqual( - Item.objects.filter(Q(tags=self.t1) & Q(tags=self.t2)), - [] - ) - self.assertQuerysetEqual( - Item.objects.filter(Q(tags=self.t1), Q(creator__name='fred')|Q(tags=self.t2)), - [] - ) - - qs = Author.objects.filter(ranking__rank=2, ranking__id=self.rank1.id) - self.assertQuerysetEqual(list(qs), ['<Author: a2>']) - self.assertEqual(2, qs.query.count_active_tables(), 2) - qs = Author.objects.filter(ranking__rank=2).filter(ranking__id=self.rank1.id) - self.assertEqual(qs.query.count_active_tables(), 3) - - def test_ticket4464(self): - self.assertQuerysetEqual( - Item.objects.filter(tags=self.t1).filter(tags=self.t2), - ['<Item: one>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name'), - ['<Item: one>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(tags__in=[self.t1, self.t2]).filter(tags=self.t3), - ['<Item: two>'] - ) - - # Make sure .distinct() works with slicing (this was broken in Oracle). - self.assertQuerysetEqual( - Item.objects.filter(tags__in=[self.t1, self.t2]).order_by('name')[:3], - ['<Item: one>', '<Item: one>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name')[:3], - ['<Item: one>', '<Item: two>'] - ) - - def test_tickets_2080_3592(self): - self.assertQuerysetEqual( - Author.objects.filter(item__name='one') | Author.objects.filter(name='a3'), - ['<Author: a1>', '<Author: a3>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(Q(item__name='one') | Q(name='a3')), - ['<Author: a1>', '<Author: a3>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(Q(name='a3') | Q(item__name='one')), - ['<Author: a1>', '<Author: a3>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(Q(item__name='three') | Q(report__name='r3')), - ['<Author: a2>'] - ) - - def test_ticket6074(self): - # Merging two empty result sets shouldn't leave a queryset with no constraints - # (which would match everything). - self.assertQuerysetEqual(Author.objects.filter(Q(id__in=[])), []) - self.assertQuerysetEqual( - Author.objects.filter(Q(id__in=[])|Q(id__in=[])), - [] - ) - - def test_tickets_1878_2939(self): - self.assertEqual(Item.objects.values('creator').distinct().count(), 3) - - # Create something with a duplicate 'name' so that we can test multi-column - # cases (which require some tricky SQL transformations under the covers). - xx = Item(name='four', created=self.time1, creator=self.a2, note=self.n1) - xx.save() - self.assertEqual( - Item.objects.exclude(name='two').values('creator', 'name').distinct().count(), - 4 - ) - self.assertEqual( - Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name', 'foo').distinct().count(), - 4 - ) - self.assertEqual( - Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name').distinct().count(), - 4 - ) - xx.delete() - - def test_ticket7323(self): - self.assertEqual(Item.objects.values('creator', 'name').count(), 4) - - def test_ticket2253(self): - q1 = Item.objects.order_by('name') - q2 = Item.objects.filter(id=self.i1.id) - self.assertQuerysetEqual( - q1, - ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>'] - ) - self.assertQuerysetEqual(q2, ['<Item: one>']) - self.assertQuerysetEqual( - (q1 | q2).order_by('name'), - ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>'] - ) - self.assertQuerysetEqual((q1 & q2).order_by('name'), ['<Item: one>']) - - # FIXME: This is difficult to fix and very much an edge case, so punt for now. - # This is related to the order_by() tests, below, but the old bug exhibited - # itself here (q2 was pulling too many tables into the combined query with the - # new ordering, but only because we have evaluated q2 already). - # - #self.assertEqual(len((q1 & q2).order_by('name').query.tables), 1) - - q1 = Item.objects.filter(tags=self.t1) - q2 = Item.objects.filter(note=self.n3, tags=self.t2) - q3 = Item.objects.filter(creator=self.a4) - self.assertQuerysetEqual( - ((q1 & q2) | q3).order_by('name'), - ['<Item: four>', '<Item: one>'] - ) - - def test_tickets_4088_4306(self): - self.assertQuerysetEqual( - Report.objects.filter(creator=1001), - ['<Report: r1>'] - ) - self.assertQuerysetEqual( - Report.objects.filter(creator__num=1001), - ['<Report: r1>'] - ) - self.assertQuerysetEqual(Report.objects.filter(creator__id=1001), []) - self.assertQuerysetEqual( - Report.objects.filter(creator__id=self.a1.id), - ['<Report: r1>'] - ) - self.assertQuerysetEqual( - Report.objects.filter(creator__name='a1'), - ['<Report: r1>'] - ) - - def test_ticket4510(self): - self.assertQuerysetEqual( - Author.objects.filter(report__name='r1'), - ['<Author: a1>'] - ) - - def test_ticket7378(self): - self.assertQuerysetEqual(self.a1.report_set.all(), ['<Report: r1>']) - - def test_tickets_5324_6704(self): - self.assertQuerysetEqual( - Item.objects.filter(tags__name='t4'), - ['<Item: four>'] - ) - self.assertQuerysetEqual( - Item.objects.exclude(tags__name='t4').order_by('name').distinct(), - ['<Item: one>', '<Item: three>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.exclude(tags__name='t4').order_by('name').distinct().reverse(), - ['<Item: two>', '<Item: three>', '<Item: one>'] - ) - self.assertQuerysetEqual( - Author.objects.exclude(item__name='one').distinct().order_by('name'), - ['<Author: a2>', '<Author: a3>', '<Author: a4>'] - ) - - # Excluding across a m2m relation when there is more than one related - # object associated was problematic. - self.assertQuerysetEqual( - Item.objects.exclude(tags__name='t1').order_by('name'), - ['<Item: four>', '<Item: three>'] - ) - self.assertQuerysetEqual( - Item.objects.exclude(tags__name='t1').exclude(tags__name='t4'), - ['<Item: three>'] - ) - - # Excluding from a relation that cannot be NULL should not use outer joins. - query = Item.objects.exclude(creator__in=[self.a1, self.a2]).query - self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()]) - - # Similarly, when one of the joins cannot possibly, ever, involve NULL - # values (Author -> ExtraInfo, in the following), it should never be - # promoted to a left outer join. So the following query should only - # involve one "left outer" join (Author -> Item is 0-to-many). - qs = Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3)) - self.assertEqual( - len([x[2] for x in qs.query.alias_map.values() if x[2] == query.LOUTER and qs.query.alias_refcount[x[1]]]), - 1 - ) - - # The previous changes shouldn't affect nullable foreign key joins. - self.assertQuerysetEqual( - Tag.objects.filter(parent__isnull=True).order_by('name'), - ['<Tag: t1>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(parent__isnull=True).order_by('name'), - ['<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(Q(parent__name='t1') | Q(parent__isnull=True)).order_by('name'), - ['<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(Q(parent__isnull=True) | Q(parent__name='t1')).order_by('name'), - ['<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(Q(parent__parent__isnull=True)).order_by('name'), - ['<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Tag.objects.filter(~Q(parent__parent__isnull=True)).order_by('name'), - ['<Tag: t4>', '<Tag: t5>'] - ) - - def test_ticket2091(self): - t = Tag.objects.get(name='t4') - self.assertQuerysetEqual( - Item.objects.filter(tags__in=[t]), - ['<Item: four>'] - ) - - def test_heterogeneous_qs_combination(self): - # Combining querysets built on different models should behave in a well-defined - # fashion. We raise an error. - self.assertRaisesMessage( - AssertionError, - 'Cannot combine queries on two different base models.', - lambda: Author.objects.all() & Tag.objects.all() - ) - self.assertRaisesMessage( - AssertionError, - 'Cannot combine queries on two different base models.', - lambda: Author.objects.all() | Tag.objects.all() - ) - - def test_ticket3141(self): - self.assertEqual(Author.objects.extra(select={'foo': '1'}).count(), 4) - self.assertEqual( - Author.objects.extra(select={'foo': '%s'}, select_params=(1,)).count(), - 4 - ) - - def test_ticket2400(self): - self.assertQuerysetEqual( - Author.objects.filter(item__isnull=True), - ['<Author: a3>'] - ) - self.assertQuerysetEqual( - Tag.objects.filter(item__isnull=True), - ['<Tag: t5>'] - ) - - def test_ticket2496(self): - self.assertQuerysetEqual( - Item.objects.extra(tables=['queries_author']).select_related().order_by('name')[:1], - ['<Item: four>'] - ) - - def test_tickets_2076_7256(self): - # Ordering on related tables should be possible, even if the table is - # not otherwise involved. - self.assertQuerysetEqual( - Item.objects.order_by('note__note', 'name'), - ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>'] - ) - - # Ordering on a related field should use the remote model's default - # ordering as a final step. - self.assertQuerysetEqual( - Author.objects.order_by('extra', '-name'), - ['<Author: a2>', '<Author: a1>', '<Author: a4>', '<Author: a3>'] - ) - - # Using remote model default ordering can span multiple models (in this - # case, Cover is ordered by Item's default, which uses Note's default). - self.assertQuerysetEqual( - Cover.objects.all(), - ['<Cover: first>', '<Cover: second>'] - ) - - # If the remote model does not have a default ordering, we order by its 'id' - # field. - self.assertQuerysetEqual( - Item.objects.order_by('creator', 'name'), - ['<Item: one>', '<Item: three>', '<Item: two>', '<Item: four>'] - ) - - # Ordering by a many-valued attribute (e.g. a many-to-many or reverse - # ForeignKey) is legal, but the results might not make sense. That - # isn't Django's problem. Garbage in, garbage out. - self.assertQuerysetEqual( - Item.objects.filter(tags__isnull=False).order_by('tags', 'id'), - ['<Item: one>', '<Item: two>', '<Item: one>', '<Item: two>', '<Item: four>'] - ) - - # If we replace the default ordering, Django adjusts the required - # tables automatically. Item normally requires a join with Note to do - # the default ordering, but that isn't needed here. - qs = Item.objects.order_by('name') - self.assertQuerysetEqual( - qs, - ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>'] - ) - self.assertEqual(len(qs.query.tables), 1) - - def test_tickets_2874_3002(self): - qs = Item.objects.select_related().order_by('note__note', 'name') - self.assertQuerysetEqual( - qs, - ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>'] - ) - - # This is also a good select_related() test because there are multiple - # Note entries in the SQL. The two Note items should be different. - self.assertTrue(repr(qs[0].note), '<Note: n2>') - self.assertEqual(repr(qs[0].creator.extra.note), '<Note: n1>') - - def test_ticket3037(self): - self.assertQuerysetEqual( - Item.objects.filter(Q(creator__name='a3', name='two')|Q(creator__name='a4', name='four')), - ['<Item: four>'] - ) - - def test_tickets_5321_7070(self): - # Ordering columns must be included in the output columns. Note that - # this means results that might otherwise be distinct are not (if there - # are multiple values in the ordering cols), as in this example. This - # isn't a bug; it's a warning to be careful with the selection of - # ordering columns. - self.assertValueQuerysetEqual( - Note.objects.values('misc').distinct().order_by('note', '-misc'), - [{'misc': u'foo'}, {'misc': u'bar'}, {'misc': u'foo'}] - ) - - def test_ticket4358(self): - # If you don't pass any fields to values(), relation fields are - # returned as "foo_id" keys, not "foo". For consistency, you should be - # able to pass "foo_id" in the fields list and have it work, too. We - # actually allow both "foo" and "foo_id". - - # The *_id version is returned by default. - self.assertTrue('note_id' in ExtraInfo.objects.values()[0]) - - # You can also pass it in explicitly. - self.assertValueQuerysetEqual( - ExtraInfo.objects.values('note_id'), - [{'note_id': 1}, {'note_id': 2}] - ) - - # ...or use the field name. - self.assertValueQuerysetEqual( - ExtraInfo.objects.values('note'), - [{'note': 1}, {'note': 2}] - ) - - def test_ticket2902(self): - # Parameters can be given to extra_select, *if* you use a SortedDict. - - # (First we need to know which order the keys fall in "naturally" on - # your system, so we can put things in the wrong way around from - # normal. A normal dict would thus fail.) - s = [('a', '%s'), ('b', '%s')] - params = ['one', 'two'] - if {'a': 1, 'b': 2}.keys() == ['a', 'b']: - s.reverse() - params.reverse() - - # This slightly odd comparison works around the fact that PostgreSQL will - # return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of - # using constants here and not a real concern. - d = Item.objects.extra(select=SortedDict(s), select_params=params).values('a', 'b')[0] - self.assertEqual(d, {'a': u'one', 'b': u'two'}) - - # Order by the number of tags attached to an item. - l = Item.objects.extra(select={'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'}).order_by('-count') - self.assertEqual([o.count for o in l], [2, 2, 1, 0]) - - def test_ticket6154(self): - # Multiple filter statements are joined using "AND" all the time. - - self.assertQuerysetEqual( - Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3)), - ['<Author: a1>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(Q(extra__note=self.n1)|Q(item__note=self.n3)).filter(id=self.a1.id), - ['<Author: a1>'] - ) - - def test_ticket6981(self): - self.assertQuerysetEqual( - Tag.objects.select_related('parent').order_by('name'), - ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'] - ) - - def test_ticket9926(self): - self.assertQuerysetEqual( - Tag.objects.select_related("parent", "category").order_by('name'), - ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Tag.objects.select_related('parent', "parent__category").order_by('name'), - ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'] - ) - - def test_tickets_6180_6203(self): - # Dates with limits and/or counts - self.assertEqual(Item.objects.count(), 4) - self.assertEqual(Item.objects.dates('created', 'month').count(), 1) - self.assertEqual(Item.objects.dates('created', 'day').count(), 2) - self.assertEqual(len(Item.objects.dates('created', 'day')), 2) - self.assertEqual(Item.objects.dates('created', 'day')[0], datetime.datetime(2007, 12, 19, 0, 0)) - - def test_tickets_7087_12242(self): - # Dates with extra select columns - self.assertQuerysetEqual( - Item.objects.dates('created', 'day').extra(select={'a': 1}), - ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)'] - ) - self.assertQuerysetEqual( - Item.objects.extra(select={'a': 1}).dates('created', 'day'), - ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)'] - ) - - name="one" - self.assertQuerysetEqual( - Item.objects.dates('created', 'day').extra(where=['name=%s'], params=[name]), - ['datetime.datetime(2007, 12, 19, 0, 0)'] - ) - - self.assertQuerysetEqual( - Item.objects.extra(where=['name=%s'], params=[name]).dates('created', 'day'), - ['datetime.datetime(2007, 12, 19, 0, 0)'] - ) - - def test_ticket7155(self): - # Nullable dates - self.assertQuerysetEqual( - Item.objects.dates('modified', 'day'), - ['datetime.datetime(2007, 12, 19, 0, 0)'] - ) - - def test_ticket7098(self): - # Make sure semi-deprecated ordering by related models syntax still - # works. - self.assertValueQuerysetEqual( - Item.objects.values('note__note').order_by('queries_note.note', 'id'), - [{'note__note': u'n2'}, {'note__note': u'n3'}, {'note__note': u'n3'}, {'note__note': u'n3'}] - ) - - def test_ticket7096(self): - # Make sure exclude() with multiple conditions continues to work. - self.assertQuerysetEqual( - Tag.objects.filter(parent=self.t1, name='t3').order_by('name'), - ['<Tag: t3>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(parent=self.t1, name='t3').order_by('name'), - ['<Tag: t1>', '<Tag: t2>', '<Tag: t4>', '<Tag: t5>'] - ) - self.assertQuerysetEqual( - Item.objects.exclude(tags__name='t1', name='one').order_by('name').distinct(), - ['<Item: four>', '<Item: three>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(name__in=['three', 'four']).exclude(tags__name='t1').order_by('name'), - ['<Item: four>', '<Item: three>'] - ) - - # More twisted cases, involving nested negations. - self.assertQuerysetEqual( - Item.objects.exclude(~Q(tags__name='t1', name='one')), - ['<Item: one>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(~Q(tags__name='t1', name='one'), name='two'), - ['<Item: two>'] - ) - self.assertQuerysetEqual( - Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two'), - ['<Item: four>', '<Item: one>', '<Item: three>'] - ) - - def test_tickets_7204_7506(self): - # Make sure querysets with related fields can be pickled. If this - # doesn't crash, it's a Good Thing. - pickle.dumps(Item.objects.all()) - - def test_ticket7813(self): - # We should also be able to pickle things that use select_related(). - # The only tricky thing here is to ensure that we do the related - # selections properly after unpickling. - qs = Item.objects.select_related() - query = qs.query.get_compiler(qs.db).as_sql()[0] - query2 = pickle.loads(pickle.dumps(qs.query)) - self.assertEqual( - query2.get_compiler(qs.db).as_sql()[0], - query - ) - - def test_deferred_load_qs_pickling(self): - # Check pickling of deferred-loading querysets - qs = Item.objects.defer('name', 'creator') - q2 = pickle.loads(pickle.dumps(qs)) - self.assertEqual(list(qs), list(q2)) - q3 = pickle.loads(pickle.dumps(qs, pickle.HIGHEST_PROTOCOL)) - self.assertEqual(list(qs), list(q3)) - - def test_ticket7277(self): - self.assertQuerysetEqual( - self.n1.annotation_set.filter(Q(tag=self.t5) | Q(tag__children=self.t5) | Q(tag__children__children=self.t5)), - ['<Annotation: a1>'] - ) - - def test_tickets_7448_7707(self): - # Complex objects should be converted to strings before being used in - # lookups. - self.assertQuerysetEqual( - Item.objects.filter(created__in=[self.time1, self.time2]), - ['<Item: one>', '<Item: two>'] - ) - - def test_ticket7235(self): - # An EmptyQuerySet should not raise exceptions if it is filtered. - q = EmptyQuerySet() - self.assertQuerysetEqual(q.all(), []) - self.assertQuerysetEqual(q.filter(x=10), []) - self.assertQuerysetEqual(q.exclude(y=3), []) - self.assertQuerysetEqual(q.complex_filter({'pk': 1}), []) - self.assertQuerysetEqual(q.select_related('spam', 'eggs'), []) - self.assertQuerysetEqual(q.annotate(Count('eggs')), []) - self.assertQuerysetEqual(q.order_by('-pub_date', 'headline'), []) - self.assertQuerysetEqual(q.distinct(), []) - self.assertQuerysetEqual( - q.extra(select={'is_recent': "pub_date > '2006-01-01'"}), - [] - ) - q.query.low_mark = 1 - self.assertRaisesMessage( - AssertionError, - 'Cannot change a query once a slice has been taken', - q.extra, select={'is_recent': "pub_date > '2006-01-01'"} - ) - self.assertQuerysetEqual(q.reverse(), []) - self.assertQuerysetEqual(q.defer('spam', 'eggs'), []) - self.assertQuerysetEqual(q.only('spam', 'eggs'), []) - - def test_ticket7791(self): - # There were "issues" when ordering and distinct-ing on fields related - # via ForeignKeys. - self.assertEqual( - len(Note.objects.order_by('extrainfo__info').distinct()), - 3 - ) - - # Pickling of DateQuerySets used to fail - qs = Item.objects.dates('created', 'month') - _ = pickle.loads(pickle.dumps(qs)) - - def test_ticket9997(self): - # If a ValuesList or Values queryset is passed as an inner query, we - # make sure it's only requesting a single value and use that as the - # thing to select. - self.assertQuerysetEqual( - Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name')), - ['<Tag: t2>', '<Tag: t3>'] - ) - - # Multi-valued values() and values_list() querysets should raise errors. - self.assertRaisesMessage( - TypeError, - 'Cannot use a multi-field ValuesQuerySet as a filter value.', - lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name', 'id')) - ) - self.assertRaisesMessage( - TypeError, - 'Cannot use a multi-field ValuesListQuerySet as a filter value.', - lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values_list('name', 'id')) - ) - - def test_ticket9985(self): - # qs.values_list(...).values(...) combinations should work. - self.assertValueQuerysetEqual( - Note.objects.values_list("note", flat=True).values("id").order_by("id"), - [{'id': 1}, {'id': 2}, {'id': 3}] - ) - self.assertQuerysetEqual( - Annotation.objects.filter(notes__in=Note.objects.filter(note="n1").values_list('note').values('id')), - ['<Annotation: a1>'] - ) - - def test_ticket10205(self): - # When bailing out early because of an empty "__in" filter, we need - # to set things up correctly internally so that subqueries can continue properly. - self.assertEqual(Tag.objects.filter(name__in=()).update(name="foo"), 0) - - def test_ticket10432(self): - # Testing an empty "__in" filter with a generator as the value. - def f(): - return iter([]) - n_obj = Note.objects.all()[0] - def g(): - for i in [n_obj.pk]: - yield i - self.assertQuerysetEqual(Note.objects.filter(pk__in=f()), []) - self.assertEqual(list(Note.objects.filter(pk__in=g())), [n_obj]) - - def test_ticket10742(self): - # Queries used in an __in clause don't execute subqueries - - subq = Author.objects.filter(num__lt=3000) - qs = Author.objects.filter(pk__in=subq) - self.assertQuerysetEqual(qs, ['<Author: a1>', '<Author: a2>']) - - # The subquery result cache should not be populated - self.assertTrue(subq._result_cache is None) - - subq = Author.objects.filter(num__lt=3000) - qs = Author.objects.exclude(pk__in=subq) - self.assertQuerysetEqual(qs, ['<Author: a3>', '<Author: a4>']) - - # The subquery result cache should not be populated - self.assertTrue(subq._result_cache is None) - - subq = Author.objects.filter(num__lt=3000) - self.assertQuerysetEqual( - Author.objects.filter(Q(pk__in=subq) & Q(name='a1')), - ['<Author: a1>'] - ) - - # The subquery result cache should not be populated - self.assertTrue(subq._result_cache is None) - - def test_ticket7076(self): - # Excluding shouldn't eliminate NULL entries. - self.assertQuerysetEqual( - Item.objects.exclude(modified=self.time1).order_by('name'), - ['<Item: four>', '<Item: three>', '<Item: two>'] - ) - self.assertQuerysetEqual( - Tag.objects.exclude(parent__name=self.t1.name), - ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>'] - ) - - def test_ticket7181(self): - # Ordering by related tables should accomodate nullable fields (this - # test is a little tricky, since NULL ordering is database dependent. - # Instead, we just count the number of results). - self.assertEqual(len(Tag.objects.order_by('parent__name')), 5) - - # Empty querysets can be merged with others. - self.assertQuerysetEqual( - Note.objects.none() | Note.objects.all(), - ['<Note: n1>', '<Note: n2>', '<Note: n3>'] - ) - self.assertQuerysetEqual( - Note.objects.all() | Note.objects.none(), - ['<Note: n1>', '<Note: n2>', '<Note: n3>'] - ) - self.assertQuerysetEqual(Note.objects.none() & Note.objects.all(), []) - self.assertQuerysetEqual(Note.objects.all() & Note.objects.none(), []) - - def test_ticket9411(self): - # Make sure bump_prefix() (an internal Query method) doesn't (re-)break. It's - # sufficient that this query runs without error. - qs = Tag.objects.values_list('id', flat=True).order_by('id') - qs.query.bump_prefix() - first = qs[0] - self.assertEqual(list(qs), range(first, first+5)) - - def test_ticket8439(self): - # Complex combinations of conjunctions, disjunctions and nullable - # relations. - self.assertQuerysetEqual( - Author.objects.filter(Q(item__note__extrainfo=self.e2)|Q(report=self.r1, name='xyz')), - ['<Author: a2>'] - ) - self.assertQuerysetEqual( - Author.objects.filter(Q(report=self.r1, name='xyz')|Q(item__note__extrainfo=self.e2)), - ['<Author: a2>'] - ) - self.assertQuerysetEqual( - Annotation.objects.filter(Q(tag__parent=self.t1)|Q(notes__note='n1', name='a1')), - ['<Annotation: a1>'] - ) - xx = ExtraInfo.objects.create(info='xx', note=self.n3) - self.assertQuerysetEqual( - Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)), - ['<Note: n1>', '<Note: n3>'] - ) - xx.delete() - q = Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)).query - self.assertEqual( - len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]]), - 1 - ) - - -class Queries2Tests(TestCase): - def setUp(self): - Number.objects.create(num=4) - Number.objects.create(num=8) - Number.objects.create(num=12) - - def test_ticket4289(self): - # A slight variation on the restricting the filtering choices by the - # lookup constraints. - self.assertQuerysetEqual(Number.objects.filter(num__lt=4), []) - self.assertQuerysetEqual(Number.objects.filter(num__gt=8, num__lt=12), []) - self.assertQuerysetEqual( - Number.objects.filter(num__gt=8, num__lt=13), - ['<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(Q(num__lt=4) | Q(num__gt=8, num__lt=12)), - [] - ) - self.assertQuerysetEqual( - Number.objects.filter(Q(num__gt=8, num__lt=12) | Q(num__lt=4)), - [] - ) - self.assertQuerysetEqual( - Number.objects.filter(Q(num__gt=8) & Q(num__lt=12) | Q(num__lt=4)), - [] - ) - self.assertQuerysetEqual( - Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4)), - ['<Number: 8>'] - ) - - def test_ticket12239(self): - # Float was being rounded to integer on gte queries on integer field. Tests - # show that gt, lt, gte, and lte work as desired. Note that the fix changes - # get_prep_lookup for gte and lt queries only. - self.assertQuerysetEqual( - Number.objects.filter(num__gt=11.9), - ['<Number: 12>'] - ) - self.assertQuerysetEqual(Number.objects.filter(num__gt=12), []) - self.assertQuerysetEqual(Number.objects.filter(num__gt=12.0), []) - self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), []) - self.assertQuerysetEqual( - Number.objects.filter(num__lt=12), - ['<Number: 4>', '<Number: 8>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lt=12.0), - ['<Number: 4>', '<Number: 8>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lt=12.1), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__gte=11.9), - ['<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__gte=12), - ['<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__gte=12.0), - ['<Number: 12>'] - ) - self.assertQuerysetEqual(Number.objects.filter(num__gte=12.1), []) - self.assertQuerysetEqual(Number.objects.filter(num__gte=12.9), []) - self.assertQuerysetEqual( - Number.objects.filter(num__lte=11.9), - ['<Number: 4>', '<Number: 8>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lte=12), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lte=12.0), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lte=12.1), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] - ) - self.assertQuerysetEqual( - Number.objects.filter(num__lte=12.9), - ['<Number: 4>', '<Number: 8>', '<Number: 12>'] - ) - - def test_ticket7411(self): - # Saving to db must work even with partially read result set in another - # cursor. - for num in range(2 * ITER_CHUNK_SIZE + 1): - _ = Number.objects.create(num=num) - - for i, obj in enumerate(Number.objects.all()): - obj.save() - if i > 10: break - - def test_ticket7759(self): - # Count should work with a partially read result set. - count = Number.objects.count() - qs = Number.objects.all() - def run(): - for obj in qs: - return qs.count() == count - self.assertTrue(run()) - - -class Queries3Tests(BaseQuerysetTest): - def test_ticket7107(self): - # This shouldn't create an infinite loop. - self.assertQuerysetEqual(Valid.objects.all(), []) - - def test_ticket8683(self): - # Raise proper error when a DateQuerySet gets passed a wrong type of - # field - self.assertRaisesMessage( - AssertionError, - "'name' isn't a DateField.", - Item.objects.dates, 'name', 'month' - ) - -class Queries4Tests(BaseQuerysetTest): - def setUp(self): - generic = NamedCategory.objects.create(name="Generic") - self.t1 = Tag.objects.create(name='t1', category=generic) - - n1 = Note.objects.create(note='n1', misc='foo', id=1) - n2 = Note.objects.create(note='n2', misc='bar', id=2) - - e1 = ExtraInfo.objects.create(info='e1', note=n1) - e2 = ExtraInfo.objects.create(info='e2', note=n2) - - a1 = Author.objects.create(name='a1', num=1001, extra=e1) - a3 = Author.objects.create(name='a3', num=3003, extra=e2) - - Report.objects.create(name='r1', creator=a1) - Report.objects.create(name='r2', creator=a3) - Report.objects.create(name='r3') - - def test_ticket7095(self): - # Updates that are filtered on the model being updated are somewhat - # tricky in MySQL. This exercises that case. - ManagedModel.objects.create(data='mm1', tag=self.t1, public=True) - self.assertEqual(ManagedModel.objects.update(data='mm'), 1) - - # A values() or values_list() query across joined models must use outer - # joins appropriately. - # Note: In Oracle, we expect a null CharField to return u'' instead of - # None. - if connection.features.interprets_empty_strings_as_nulls: - expected_null_charfield_repr = u'' - else: - expected_null_charfield_repr = None - self.assertValueQuerysetEqual( - Report.objects.values_list("creator__extra__info", flat=True).order_by("name"), - [u'e1', u'e2', expected_null_charfield_repr], - ) - - # Similarly for select_related(), joins beyond an initial nullable join - # must use outer joins so that all results are included. - self.assertQuerysetEqual( - Report.objects.select_related("creator", "creator__extra").order_by("name"), - ['<Report: r1>', '<Report: r2>', '<Report: r3>'] - ) - - # When there are multiple paths to a table from another table, we have - # to be careful not to accidentally reuse an inappropriate join when - # using select_related(). We used to return the parent's Detail record - # here by mistake. - - d1 = Detail.objects.create(data="d1") - d2 = Detail.objects.create(data="d2") - m1 = Member.objects.create(name="m1", details=d1) - m2 = Member.objects.create(name="m2", details=d2) - Child.objects.create(person=m2, parent=m1) - obj = m1.children.select_related("person__details")[0] - self.assertEqual(obj.person.details.data, u'd2') - - def test_order_by_resetting(self): - # Calling order_by() with no parameters removes any existing ordering on the - # model. But it should still be possible to add new ordering after that. - qs = Author.objects.order_by().order_by('name') - self.assertTrue('ORDER BY' in qs.query.get_compiler(qs.db).as_sql()[0]) - - def test_ticket10181(self): - # Avoid raising an EmptyResultSet if an inner query is probably - # empty (and hence, not executed). - self.assertQuerysetEqual( - Tag.objects.filter(id__in=Tag.objects.filter(id__in=[])), - [] - ) - - -class Queries5Tests(TestCase): - def setUp(self): - # Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering - # will be rank3, rank2, rank1. - n1 = Note.objects.create(note='n1', misc='foo', id=1) - n2 = Note.objects.create(note='n2', misc='bar', id=2) - e1 = ExtraInfo.objects.create(info='e1', note=n1) - e2 = ExtraInfo.objects.create(info='e2', note=n2) - a1 = Author.objects.create(name='a1', num=1001, extra=e1) - a2 = Author.objects.create(name='a2', num=2002, extra=e1) - a3 = Author.objects.create(name='a3', num=3003, extra=e2) - self.rank1 = Ranking.objects.create(rank=2, author=a2) - Ranking.objects.create(rank=1, author=a3) - Ranking.objects.create(rank=3, author=a1) - - def test_ordering(self): - # Cross model ordering is possible in Meta, too. - self.assertQuerysetEqual( - Ranking.objects.all(), - ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>'] - ) - self.assertQuerysetEqual( - Ranking.objects.all().order_by('rank'), - ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>'] - ) - - - # Ordering of extra() pieces is possible, too and you can mix extra - # fields and model fields in the ordering. - self.assertQuerysetEqual( - Ranking.objects.extra(tables=['django_site'], order_by=['-django_site.id', 'rank']), - ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>'] - ) - - qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'}) - self.assertEqual( - [o.good for o in qs.extra(order_by=('-good',))], - [True, False, False] - ) - self.assertQuerysetEqual( - qs.extra(order_by=('-good', 'id')), - ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>'] - ) - - # Despite having some extra aliases in the query, we can still omit - # them in a values() query. - dicts = qs.values('id', 'rank').order_by('id') - self.assertEqual( - [d.items()[1] for d in dicts], - [('rank', 2), ('rank', 1), ('rank', 3)] - ) - - def test_ticket7256(self): - # An empty values() call includes all aliases, including those from an - # extra() - qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'}) - dicts = qs.values().order_by('id') - for d in dicts: del d['id']; del d['author_id'] - self.assertEqual( - [sorted(d.items()) for d in dicts], - [[('good', 0), ('rank', 2)], [('good', 0), ('rank', 1)], [('good', 1), ('rank', 3)]] - ) - - def test_ticket7045(self): - # Extra tables used to crash SQL construction on the second use. - qs = Ranking.objects.extra(tables=['django_site']) - qs.query.get_compiler(qs.db).as_sql() - # test passes if this doesn't raise an exception. - qs.query.get_compiler(qs.db).as_sql() - - def test_ticket9848(self): - # Make sure that updates which only filter on sub-tables don't - # inadvertently update the wrong records (bug #9848). - - # Make sure that the IDs from different tables don't happen to match. - self.assertQuerysetEqual( - Ranking.objects.filter(author__name='a1'), - ['<Ranking: 3: a1>'] - ) - self.assertEqual( - Ranking.objects.filter(author__name='a1').update(rank='4'), - 1 - ) - r = Ranking.objects.filter(author__name='a1')[0] - self.assertNotEqual(r.id, r.author.id) - self.assertEqual(r.rank, 4) - r.rank = 3 - r.save() - self.assertQuerysetEqual( - Ranking.objects.all(), - ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>'] - ) - - def test_ticket5261(self): - self.assertQuerysetEqual( - Note.objects.exclude(Q()), - ['<Note: n1>', '<Note: n2>'] - ) - - -class SelectRelatedTests(TestCase): - def test_tickets_3045_3288(self): - # Once upon a time, select_related() with circular relations would loop - # infinitely if you forgot to specify "depth". Now we set an arbitrary - # default upper bound. - self.assertQuerysetEqual(X.objects.all(), []) - self.assertQuerysetEqual(X.objects.select_related(), []) - - -class SubclassFKTests(TestCase): - def test_ticket7778(self): - # Model subclasses could not be deleted if a nullable foreign key - # relates to a model that relates back. - - num_celebs = Celebrity.objects.count() - tvc = TvChef.objects.create(name="Huey") - self.assertEqual(Celebrity.objects.count(), num_celebs + 1) - Fan.objects.create(fan_of=tvc) - Fan.objects.create(fan_of=tvc) - tvc.delete() - - # The parent object should have been deleted as well. - self.assertEqual(Celebrity.objects.count(), num_celebs) - - -class CustomPkTests(TestCase): - def test_ticket7371(self): - self.assertQuerysetEqual(Related.objects.order_by('custom'), []) - - -class NullableRelOrderingTests(TestCase): - def test_ticket10028(self): - # Ordering by model related to nullable relations(!) should use outer - # joins, so that all results are included. - _ = Plaything.objects.create(name="p1") - self.assertQuerysetEqual( - Plaything.objects.all(), - ['<Plaything: p1>'] - ) - - -class DisjunctiveFilterTests(TestCase): - def setUp(self): - self.n1 = Note.objects.create(note='n1', misc='foo', id=1) - ExtraInfo.objects.create(info='e1', note=self.n1) - - def test_ticket7872(self): - # Another variation on the disjunctive filtering theme. - - # For the purposes of this regression test, it's important that there is no - # Join object releated to the LeafA we create. - LeafA.objects.create(data='first') - self.assertQuerysetEqual(LeafA.objects.all(), ['<LeafA: first>']) - self.assertQuerysetEqual( - LeafA.objects.filter(Q(data='first')|Q(join__b__data='second')), - ['<LeafA: first>'] - ) - - def test_ticket8283(self): - # Checking that applying filters after a disjunction works correctly. - self.assertQuerysetEqual( - (ExtraInfo.objects.filter(note=self.n1)|ExtraInfo.objects.filter(info='e2')).filter(note=self.n1), - ['<ExtraInfo: e1>'] - ) - self.assertQuerysetEqual( - (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=self.n1)).filter(note=self.n1), - ['<ExtraInfo: e1>'] - ) - - -class Queries6Tests(TestCase): - def setUp(self): - generic = NamedCategory.objects.create(name="Generic") - t1 = Tag.objects.create(name='t1', category=generic) - t2 = Tag.objects.create(name='t2', parent=t1, category=generic) - t3 = Tag.objects.create(name='t3', parent=t1) - t4 = Tag.objects.create(name='t4', parent=t3) - t5 = Tag.objects.create(name='t5', parent=t3) - n1 = Note.objects.create(note='n1', misc='foo', id=1) - ann1 = Annotation.objects.create(name='a1', tag=t1) - ann1.notes.add(n1) - ann2 = Annotation.objects.create(name='a2', tag=t4) - - # FIXME!! This next test causes really weird PostgreSQL behaviour, but it's - # only apparent much later when the full test suite runs. I don't understand - # what's going on here yet. - ##def test_slicing_and_cache_interaction(self): - ## # We can do slicing beyond what is currently in the result cache, - ## # too. - ## - ## # We need to mess with the implementation internals a bit here to decrease the - ## # cache fill size so that we don't read all the results at once. - ## from django.db.models import query - ## query.ITER_CHUNK_SIZE = 2 - ## qs = Tag.objects.all() - ## - ## # Fill the cache with the first chunk. - ## self.assertTrue(bool(qs)) - ## self.assertEqual(len(qs._result_cache), 2) - ## - ## # Query beyond the end of the cache and check that it is filled out as required. - ## self.assertEqual(repr(qs[4]), '<Tag: t5>') - ## self.assertEqual(len(qs._result_cache), 5) - ## - ## # But querying beyond the end of the result set will fail. - ## self.assertRaises(IndexError, lambda: qs[100]) - - def test_parallel_iterators(self): - # Test that parallel iterators work. - qs = Tag.objects.all() - i1, i2 = iter(qs), iter(qs) - self.assertEqual(repr(i1.next()), '<Tag: t1>') - self.assertEqual(repr(i1.next()), '<Tag: t2>') - self.assertEqual(repr(i2.next()), '<Tag: t1>') - self.assertEqual(repr(i2.next()), '<Tag: t2>') - self.assertEqual(repr(i2.next()), '<Tag: t3>') - self.assertEqual(repr(i1.next()), '<Tag: t3>') - - qs = X.objects.all() - self.assertEqual(bool(qs), False) - self.assertEqual(bool(qs), False) - - def test_nested_queries_sql(self): - # Nested queries should not evaluate the inner query as part of constructing the - # SQL (so we should see a nested query here, indicated by two "SELECT" calls). - qs = Annotation.objects.filter(notes__in=Note.objects.filter(note="xyzzy")) - self.assertEqual( - qs.query.get_compiler(qs.db).as_sql()[0].count('SELECT'), - 2 - ) - - def test_tickets_8921_9188(self): - # Incorrect SQL was being generated for certain types of exclude() - # queries that crossed multi-valued relations (#8921, #9188 and some - # pre-emptively discovered cases). - - self.assertQuerysetEqual( - PointerA.objects.filter(connection__pointerb__id=1), - [] - ) - self.assertQuerysetEqual( - PointerA.objects.exclude(connection__pointerb__id=1), - [] - ) - - self.assertQuerysetEqual( - Tag.objects.exclude(children=None), - ['<Tag: t1>', '<Tag: t3>'] - ) - - # This example is tricky because the parent could be NULL, so only checking - # parents with annotations omits some results (tag t1, in this case). - self.assertQuerysetEqual( - Tag.objects.exclude(parent__annotation__name="a1"), - ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>'] - ) - - # The annotation->tag link is single values and tag->children links is - # multi-valued. So we have to split the exclude filter in the middle - # and then optimise the inner query without losing results. - self.assertQuerysetEqual( - Annotation.objects.exclude(tag__children__name="t2"), - ['<Annotation: a2>'] - ) - - # Nested queries are possible (although should be used with care, since - # they have performance problems on backends like MySQL. - - self.assertQuerysetEqual( - Annotation.objects.filter(notes__in=Note.objects.filter(note="n1")), - ['<Annotation: a1>'] - ) - - def test_ticket3739(self): - # The all() method on querysets returns a copy of the queryset. - q1 = Tag.objects.order_by('name') - self.assertTrue(q1 is not q1.all()) - - -class GeneratorExpressionTests(TestCase): - def test_ticket10432(self): - # Using an empty generator expression as the rvalue for an "__in" - # lookup is legal. - self.assertQuerysetEqual( - Note.objects.filter(pk__in=(x for x in ())), - [] - ) - - -class ComparisonTests(TestCase): - def setUp(self): - self.n1 = Note.objects.create(note='n1', misc='foo', id=1) - e1 = ExtraInfo.objects.create(info='e1', note=self.n1) - self.a2 = Author.objects.create(name='a2', num=2002, extra=e1) - - def test_ticket8597(self): - # Regression tests for case-insensitive comparisons - _ = Item.objects.create(name="a_b", created=datetime.datetime.now(), creator=self.a2, note=self.n1) - _ = Item.objects.create(name="x%y", created=datetime.datetime.now(), creator=self.a2, note=self.n1) - self.assertQuerysetEqual( - Item.objects.filter(name__iexact="A_b"), - ['<Item: a_b>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(name__iexact="x%Y"), - ['<Item: x%y>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(name__istartswith="A_b"), - ['<Item: a_b>'] - ) - self.assertQuerysetEqual( - Item.objects.filter(name__iendswith="A_b"), - ['<Item: a_b>'] - ) - - -class ExistsSql(TestCase): - def setUp(self): - settings.DEBUG = True - - def test_exists(self): - self.assertFalse(Tag.objects.exists()) - # Ok - so the exist query worked - but did it include too many columns? - self.assertTrue("id" not in connection.queries[-1]['sql'] and "name" not in connection.queries[-1]['sql']) - - def tearDown(self): - settings.DEBUG = False - - -class QuerysetOrderedTests(unittest.TestCase): - """ - Tests for the Queryset.ordered attribute. - """ - - def test_no_default_or_explicit_ordering(self): - self.assertEqual(Annotation.objects.all().ordered, False) - - def test_cleared_default_ordering(self): - self.assertEqual(Tag.objects.all().ordered, True) - self.assertEqual(Tag.objects.all().order_by().ordered, False) - - def test_explicit_ordering(self): - self.assertEqual(Annotation.objects.all().order_by('id').ordered, True) - - def test_order_by_extra(self): - self.assertEqual(Annotation.objects.all().extra(order_by=['id']).ordered, True) - - def test_annotated_ordering(self): - qs = Annotation.objects.annotate(num_notes=Count('notes')) - self.assertEqual(qs.ordered, False) - self.assertEqual(qs.order_by('num_notes').ordered, True) - - -class SubqueryTests(TestCase): - def setUp(self): - DumbCategory.objects.create(id=1) - DumbCategory.objects.create(id=2) - DumbCategory.objects.create(id=3) - - def test_ordered_subselect(self): - "Subselects honor any manual ordering" - try: - query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:2]) - self.assertEquals(set(query.values_list('id', flat=True)), set([2,3])) - - query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[:2]) - self.assertEquals(set(query.values_list('id', flat=True)), set([2,3])) - - query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[2:]) - self.assertEquals(set(query.values_list('id', flat=True)), set([1])) - except DatabaseError: - # Oracle and MySQL both have problems with sliced subselects. - # This prevents us from even evaluating this test case at all. - # Refs #10099 - self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries) - - def test_sliced_delete(self): - "Delete queries can safely contain sliced subqueries" - try: - DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:1]).delete() - self.assertEquals(set(DumbCategory.objects.values_list('id', flat=True)), set([1,2])) - except DatabaseError: - # Oracle and MySQL both have problems with sliced subselects. - # This prevents us from even evaluating this test case at all. - # Refs #10099 - self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries) - - -class CloneTests(TestCase): - def test_evaluated_queryset_as_argument(self): - "#13227 -- If a queryset is already evaluated, it can still be used as a query arg" - n = Note(note='Test1', misc='misc') - n.save() - e = ExtraInfo(info='good', note=n) - e.save() - - n_list = Note.objects.all() - # Evaluate the Note queryset, populating the query cache - list(n_list) - # Use the note queryset in a query, and evalute - # that query in a way that involves cloning. - try: - self.assertEquals(ExtraInfo.objects.filter(note__in=n_list)[0].info, 'good') - except: - self.fail('Query should be clonable') - - -class EmptyQuerySetTests(TestCase): - def test_emptyqueryset_values(self): - # #14366 -- Calling .values() on an EmptyQuerySet and then cloning that - # should not cause an error" - self.assertQuerysetEqual( - Number.objects.none().values('num').order_by('num'), [] - ) - - def test_values_subquery(self): - self.assertQuerysetEqual( - Number.objects.filter(pk__in=Number.objects.none().values("pk")), - [] - ) - self.assertQuerysetEqual( - Number.objects.filter(pk__in=Number.objects.none().values_list("pk")), - [] - ) - - -class ValuesQuerysetTests(BaseQuerysetTest): - def test_flat_values_lits(self): - Number.objects.create(num=72) - qs = Number.objects.values_list("num") - qs = qs.values_list("num", flat=True) - self.assertValueQuerysetEqual( - qs, [72] - ) - - -class WeirdQuerysetSlicingTests(BaseQuerysetTest): - def setUp(self): - Number.objects.create(num=1) - Number.objects.create(num=2) - - Article.objects.create(name='one', created=datetime.datetime.now()) - Article.objects.create(name='two', created=datetime.datetime.now()) - Article.objects.create(name='three', created=datetime.datetime.now()) - Article.objects.create(name='four', created=datetime.datetime.now()) - - def test_tickets_7698_10202(self): - # People like to slice with '0' as the high-water mark. - self.assertQuerysetEqual(Article.objects.all()[0:0], []) - self.assertQuerysetEqual(Article.objects.all()[0:0][:10], []) - self.assertEqual(Article.objects.all()[:0].count(), 0) - self.assertRaisesMessage( - AssertionError, - 'Cannot change a query once a slice has been taken.', - Article.objects.all()[:0].latest, 'created' - ) - - -class EscapingTests(TestCase): - def test_ticket_7302(self): - # Reserved names are appropriately escaped - _ = ReservedName.objects.create(name='a', order=42) - ReservedName.objects.create(name='b', order=37) - self.assertQuerysetEqual( - ReservedName.objects.all().order_by('order'), - ['<ReservedName: b>', '<ReservedName: a>'] - ) - self.assertQuerysetEqual( - ReservedName.objects.extra(select={'stuff':'name'}, order_by=('order','stuff')), - ['<ReservedName: b>', '<ReservedName: a>'] - ) - - -# In Python 2.6 beta releases, exceptions raised in __len__ are swallowed -# (Python issue 1242657), so these cases return an empty list, rather than -# raising an exception. Not a lot we can do about that, unfortunately, due to -# the way Python handles list() calls internally. Thus, we skip the tests for -# Python 2.6. -if sys.version_info[:2] != (2, 6): - class OrderingLoopTests(BaseQuerysetTest): - def setUp(self): - generic = NamedCategory.objects.create(name="Generic") - t1 = Tag.objects.create(name='t1', category=generic) - t2 = Tag.objects.create(name='t2', parent=t1, category=generic) - t3 = Tag.objects.create(name='t3', parent=t1) - t4 = Tag.objects.create(name='t4', parent=t3) - t5 = Tag.objects.create(name='t5', parent=t3) - - def test_infinite_loop(self): - # If you're not careful, it's possible to introduce infinite loops via - # default ordering on foreign keys in a cycle. We detect that. - self.assertRaisesMessage( - FieldError, - 'Infinite loop caused by ordering.', - lambda: list(LoopX.objects.all()) # Force queryset evaluation with list() - ) - self.assertRaisesMessage( - FieldError, - 'Infinite loop caused by ordering.', - lambda: list(LoopZ.objects.all()) # Force queryset evaluation with list() - ) - - # Note that this doesn't cause an infinite loop, since the default - # ordering on the Tag model is empty (and thus defaults to using "id" - # for the related field). - self.assertEqual(len(Tag.objects.order_by('parent')), 5) - - # ... but you can still order in a non-recursive fashion amongst linked - # fields (the previous test failed because the default ordering was - # recursive). - self.assertQuerysetEqual( - LoopX.objects.all().order_by('y__x__y__x__id'), - [] - ) - - -# When grouping without specifying ordering, we add an explicit "ORDER BY NULL" -# portion in MySQL to prevent unnecessary sorting. -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.mysql": - class GroupingTests(TestCase): - def test_null_ordering_added(self): - query = Tag.objects.values_list('parent_id', flat=True).order_by().query - query.group_by = ['parent_id'] - sql = query.get_compiler(DEFAULT_DB_ALIAS).as_sql()[0] - fragment = "ORDER BY " - pos = sql.find(fragment) - self.assertEqual(sql.find(fragment, pos + 1), -1) - self.assertEqual(sql.find("NULL", pos + len(fragment)), pos + len(fragment)) - - -# Sqlite 3 does not support passing in more than 1000 parameters except by -# changing a parameter at compilation time. -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != "django.db.backends.sqlite3": - class InLookupTests(TestCase): - def test_ticket14244(self): - # Test that the "in" lookup works with lists of 1000 items or more. - Number.objects.all().delete() - numbers = range(2500) - for num in numbers: - _ = Number.objects.create(num=num) - self.assertEqual( - Number.objects.filter(num__in=numbers[:1000]).count(), - 1000 - ) - self.assertEqual( - Number.objects.filter(num__in=numbers[:1001]).count(), - 1001 - ) - self.assertEqual( - Number.objects.filter(num__in=numbers[:2000]).count(), - 2000 - ) - self.assertEqual( - Number.objects.filter(num__in=numbers).count(), - 2500 - ) diff --git a/parts/django/tests/regressiontests/queryset_pickle/__init__.py b/parts/django/tests/regressiontests/queryset_pickle/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/queryset_pickle/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/queryset_pickle/models.py b/parts/django/tests/regressiontests/queryset_pickle/models.py deleted file mode 100644 index df0a6e6..0000000 --- a/parts/django/tests/regressiontests/queryset_pickle/models.py +++ /dev/null @@ -1,34 +0,0 @@ -import datetime -from django.db import models -from django.utils.translation import ugettext_lazy as _ - -def standalone_number(self): - return 1 - -class Numbers(object): - @staticmethod - def get_static_number(self): - return 2 - - @classmethod - def get_class_number(self): - return 3 - - def get_member_number(self): - return 4 - -nn = Numbers() - -class Group(models.Model): - name = models.CharField(_('name'), max_length=100) - -class Event(models.Model): - group = models.ForeignKey(Group) - -class Happening(models.Model): - when = models.DateTimeField(blank=True, default=datetime.datetime.now) - name = models.CharField(blank=True, max_length=100, default=lambda:"test") - number1 = models.IntegerField(blank=True, default=standalone_number) - number2 = models.IntegerField(blank=True, default=Numbers.get_static_number) - number3 = models.IntegerField(blank=True, default=Numbers.get_class_number) - number4 = models.IntegerField(blank=True, default=nn.get_member_number) diff --git a/parts/django/tests/regressiontests/queryset_pickle/tests.py b/parts/django/tests/regressiontests/queryset_pickle/tests.py deleted file mode 100644 index 5c64687..0000000 --- a/parts/django/tests/regressiontests/queryset_pickle/tests.py +++ /dev/null @@ -1,36 +0,0 @@ -import pickle -import datetime - -from django.test import TestCase - -from models import Group, Event, Happening - - -class PickleabilityTestCase(TestCase): - def assert_pickles(self, qs): - self.assertEqual(list(pickle.loads(pickle.dumps(qs))), list(qs)) - - def test_related_field(self): - g = Group.objects.create(name="Ponies Who Own Maybachs") - self.assert_pickles(Event.objects.filter(group=g.id)) - - def test_datetime_callable_default_all(self): - self.assert_pickles(Happening.objects.all()) - - def test_datetime_callable_default_filter(self): - self.assert_pickles(Happening.objects.filter(when=datetime.datetime.now())) - - def test_lambda_as_default(self): - self.assert_pickles(Happening.objects.filter(name="test")) - - def test_standalone_method_as_default(self): - self.assert_pickles(Happening.objects.filter(number1=1)) - - def test_staticmethod_as_default(self): - self.assert_pickles(Happening.objects.filter(number2=1)) - - def test_classmethod_as_default(self): - self.assert_pickles(Happening.objects.filter(number3=1)) - - def test_membermethod_as_default(self): - self.assert_pickles(Happening.objects.filter(number4=1)) diff --git a/parts/django/tests/regressiontests/requests/__init__.py b/parts/django/tests/regressiontests/requests/__init__.py deleted file mode 100644 index 3a32885..0000000 --- a/parts/django/tests/regressiontests/requests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Tests for Django's various Request objects. -""" diff --git a/parts/django/tests/regressiontests/requests/models.py b/parts/django/tests/regressiontests/requests/models.py deleted file mode 100644 index 19f81d6..0000000 --- a/parts/django/tests/regressiontests/requests/models.py +++ /dev/null @@ -1 +0,0 @@ -# Need a models module for the test runner. diff --git a/parts/django/tests/regressiontests/requests/tests.py b/parts/django/tests/regressiontests/requests/tests.py deleted file mode 100644 index 556d61e..0000000 --- a/parts/django/tests/regressiontests/requests/tests.py +++ /dev/null @@ -1,59 +0,0 @@ -from datetime import datetime, timedelta -import time -import unittest - -from django.http import HttpRequest, HttpResponse, parse_cookie -from django.core.handlers.wsgi import WSGIRequest -from django.core.handlers.modpython import ModPythonRequest -from django.utils.http import cookie_date - -class RequestsTests(unittest.TestCase): - - def test_httprequest(self): - request = HttpRequest() - self.assertEqual(request.GET.keys(), []) - self.assertEqual(request.POST.keys(), []) - self.assertEqual(request.COOKIES.keys(), []) - self.assertEqual(request.META.keys(), []) - - def test_wsgirequest(self): - request = WSGIRequest({'PATH_INFO': 'bogus', 'REQUEST_METHOD': 'bogus'}) - self.assertEqual(request.GET.keys(), []) - self.assertEqual(request.POST.keys(), []) - self.assertEqual(request.COOKIES.keys(), []) - self.assertEqual(set(request.META.keys()), set(['PATH_INFO', 'REQUEST_METHOD', 'SCRIPT_NAME'])) - self.assertEqual(request.META['PATH_INFO'], 'bogus') - self.assertEqual(request.META['REQUEST_METHOD'], 'bogus') - self.assertEqual(request.META['SCRIPT_NAME'], '') - - def test_modpythonrequest(self): - class FakeModPythonRequest(ModPythonRequest): - def __init__(self, *args, **kwargs): - super(FakeModPythonRequest, self).__init__(*args, **kwargs) - self._get = self._post = self._meta = self._cookies = {} - - class Dummy: - def get_options(self): - return {} - - req = Dummy() - req.uri = 'bogus' - request = FakeModPythonRequest(req) - self.assertEqual(request.path, 'bogus') - self.assertEqual(request.GET.keys(), []) - self.assertEqual(request.POST.keys(), []) - self.assertEqual(request.COOKIES.keys(), []) - self.assertEqual(request.META.keys(), []) - - def test_parse_cookie(self): - self.assertEqual(parse_cookie('invalid:key=true'), {}) - - def test_httprequest_location(self): - request = HttpRequest() - self.assertEqual(request.build_absolute_uri(location="https://www.example.com/asdf"), - 'https://www.example.com/asdf') - - request.get_host = lambda: 'www.example.com' - request.path = '' - self.assertEqual(request.build_absolute_uri(location="/path/with:colons"), - 'http://www.example.com/path/with:colons') diff --git a/parts/django/tests/regressiontests/reverse_single_related/__init__.py b/parts/django/tests/regressiontests/reverse_single_related/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/reverse_single_related/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/reverse_single_related/models.py b/parts/django/tests/regressiontests/reverse_single_related/models.py deleted file mode 100644 index a2d8fb0..0000000 --- a/parts/django/tests/regressiontests/reverse_single_related/models.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.db import models - -class SourceManager(models.Manager): - def get_query_set(self): - return super(SourceManager, self).get_query_set().filter(is_public=True) - -class Source(models.Model): - is_public = models.BooleanField() - objects = SourceManager() - -class Item(models.Model): - source = models.ForeignKey(Source) diff --git a/parts/django/tests/regressiontests/reverse_single_related/tests.py b/parts/django/tests/regressiontests/reverse_single_related/tests.py deleted file mode 100644 index 14f3a66..0000000 --- a/parts/django/tests/regressiontests/reverse_single_related/tests.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.test import TestCase - -from regressiontests.reverse_single_related.models import * - -class ReverseSingleRelatedTests(TestCase): - """ - Regression tests for an object that cannot access a single related - object due to a restrictive default manager. - """ - - def test_reverse_single_related(self): - - public_source = Source.objects.create(is_public=True) - public_item = Item.objects.create(source=public_source) - - private_source = Source.objects.create(is_public=False) - private_item = Item.objects.create(source=private_source) - - # Only one source is available via all() due to the custom default manager. - self.assertQuerysetEqual( - Source.objects.all(), - ["<Source: Source object>"] - ) - - self.assertEquals(public_item.source, public_source) - - # Make sure that an item can still access its related source even if the default - # manager doesn't normally allow it. - self.assertEquals(private_item.source, private_source) - - # If the manager is marked "use_for_related_fields", it'll get used instead - # of the "bare" queryset. Usually you'd define this as a property on the class, - # but this approximates that in a way that's easier in tests. - Source.objects.use_for_related_fields = True - private_item = Item.objects.get(pk=private_item.pk) - self.assertRaises(Source.DoesNotExist, lambda: private_item.source) diff --git a/parts/django/tests/regressiontests/select_related_onetoone/__init__.py b/parts/django/tests/regressiontests/select_related_onetoone/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/select_related_onetoone/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/select_related_onetoone/models.py b/parts/django/tests/regressiontests/select_related_onetoone/models.py deleted file mode 100644 index 3d6da9b..0000000 --- a/parts/django/tests/regressiontests/select_related_onetoone/models.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.db import models - - -class User(models.Model): - username = models.CharField(max_length=100) - email = models.EmailField() - - def __unicode__(self): - return self.username - - -class UserProfile(models.Model): - user = models.OneToOneField(User) - city = models.CharField(max_length=100) - state = models.CharField(max_length=2) - - def __unicode__(self): - return "%s, %s" % (self.city, self.state) - - -class UserStatResult(models.Model): - results = models.CharField(max_length=50) - - def __unicode__(self): - return 'UserStatResults, results = %s' % (self.results,) - - -class UserStat(models.Model): - user = models.OneToOneField(User, primary_key=True) - posts = models.IntegerField() - results = models.ForeignKey(UserStatResult) - - def __unicode__(self): - return 'UserStat, posts = %s' % (self.posts,) - - -class StatDetails(models.Model): - base_stats = models.OneToOneField(UserStat) - comments = models.IntegerField() - - def __unicode__(self): - return 'StatDetails, comments = %s' % (self.comments,) - - -class AdvancedUserStat(UserStat): - karma = models.IntegerField() - -class Image(models.Model): - name = models.CharField(max_length=100) - - -class Product(models.Model): - name = models.CharField(max_length=100) - image = models.OneToOneField(Image, null=True) diff --git a/parts/django/tests/regressiontests/select_related_onetoone/tests.py b/parts/django/tests/regressiontests/select_related_onetoone/tests.py deleted file mode 100644 index 4ccb584..0000000 --- a/parts/django/tests/regressiontests/select_related_onetoone/tests.py +++ /dev/null @@ -1,94 +0,0 @@ -from django import db -from django.conf import settings -from django.test import TestCase - -from models import (User, UserProfile, UserStat, UserStatResult, StatDetails, - AdvancedUserStat, Image, Product) - -class ReverseSelectRelatedTestCase(TestCase): - def setUp(self): - # Explicitly enable debug for these tests - we need to count - # the queries that have been issued. - self.old_debug = settings.DEBUG - settings.DEBUG = True - - user = User.objects.create(username="test") - userprofile = UserProfile.objects.create(user=user, state="KS", - city="Lawrence") - results = UserStatResult.objects.create(results='first results') - userstat = UserStat.objects.create(user=user, posts=150, - results=results) - details = StatDetails.objects.create(base_stats=userstat, comments=259) - - user2 = User.objects.create(username="bob") - results2 = UserStatResult.objects.create(results='moar results') - advstat = AdvancedUserStat.objects.create(user=user2, posts=200, karma=5, - results=results2) - StatDetails.objects.create(base_stats=advstat, comments=250) - - db.reset_queries() - - def assertQueries(self, queries): - self.assertEqual(len(db.connection.queries), queries) - - def tearDown(self): - settings.DEBUG = self.old_debug - - def test_basic(self): - u = User.objects.select_related("userprofile").get(username="test") - self.assertEqual(u.userprofile.state, "KS") - self.assertQueries(1) - - def test_follow_next_level(self): - u = User.objects.select_related("userstat__results").get(username="test") - self.assertEqual(u.userstat.posts, 150) - self.assertEqual(u.userstat.results.results, 'first results') - self.assertQueries(1) - - def test_follow_two(self): - u = User.objects.select_related("userprofile", "userstat").get(username="test") - self.assertEqual(u.userprofile.state, "KS") - self.assertEqual(u.userstat.posts, 150) - self.assertQueries(1) - - def test_follow_two_next_level(self): - u = User.objects.select_related("userstat__results", "userstat__statdetails").get(username="test") - self.assertEqual(u.userstat.results.results, 'first results') - self.assertEqual(u.userstat.statdetails.comments, 259) - self.assertQueries(1) - - def test_forward_and_back(self): - stat = UserStat.objects.select_related("user__userprofile").get(user__username="test") - self.assertEqual(stat.user.userprofile.state, 'KS') - self.assertEqual(stat.user.userstat.posts, 150) - self.assertQueries(1) - - def test_back_and_forward(self): - u = User.objects.select_related("userstat").get(username="test") - self.assertEqual(u.userstat.user.username, 'test') - self.assertQueries(1) - - def test_not_followed_by_default(self): - u = User.objects.select_related().get(username="test") - self.assertEqual(u.userstat.posts, 150) - self.assertQueries(2) - - def test_follow_from_child_class(self): - stat = AdvancedUserStat.objects.select_related('user', 'statdetails').get(posts=200) - self.assertEqual(stat.statdetails.comments, 250) - self.assertEqual(stat.user.username, 'bob') - self.assertQueries(1) - - def test_follow_inheritance(self): - stat = UserStat.objects.select_related('user', 'advanceduserstat').get(posts=200) - self.assertEqual(stat.advanceduserstat.posts, 200) - self.assertEqual(stat.user.username, 'bob') - self.assertEqual(stat.advanceduserstat.user.username, 'bob') - self.assertQueries(1) - - def test_nullable_relation(self): - im = Image.objects.create(name="imag1") - p1 = Product.objects.create(name="Django Plushie", image=im) - p2 = Product.objects.create(name="Talking Django Plushie") - - self.assertEqual(len(Product.objects.select_related("image")), 2) diff --git a/parts/django/tests/regressiontests/select_related_regress/__init__.py b/parts/django/tests/regressiontests/select_related_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/select_related_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/select_related_regress/models.py b/parts/django/tests/regressiontests/select_related_regress/models.py deleted file mode 100644 index 3efb19e..0000000 --- a/parts/django/tests/regressiontests/select_related_regress/models.py +++ /dev/null @@ -1,86 +0,0 @@ -from django.db import models - -class Building(models.Model): - name = models.CharField(max_length=10) - - def __unicode__(self): - return u"Building: %s" % self.name - -class Device(models.Model): - building = models.ForeignKey('Building') - name = models.CharField(max_length=10) - - def __unicode__(self): - return u"device '%s' in building %s" % (self.name, self.building) - -class Port(models.Model): - device = models.ForeignKey('Device') - port_number = models.CharField(max_length=10) - - def __unicode__(self): - return u"%s/%s" % (self.device.name, self.port_number) - -class Connection(models.Model): - start = models.ForeignKey(Port, related_name='connection_start', - unique=True) - end = models.ForeignKey(Port, related_name='connection_end', unique=True) - - def __unicode__(self): - return u"%s to %s" % (self.start, self.end) - -# Another non-tree hierarchy that exercises code paths similar to the above -# example, but in a slightly different configuration. -class TUser(models.Model): - name = models.CharField(max_length=200) - -class Person(models.Model): - user = models.ForeignKey(TUser, unique=True) - -class Organizer(models.Model): - person = models.ForeignKey(Person) - -class Student(models.Model): - person = models.ForeignKey(Person) - -class Class(models.Model): - org = models.ForeignKey(Organizer) - -class Enrollment(models.Model): - std = models.ForeignKey(Student) - cls = models.ForeignKey(Class) - -# Models for testing bug #8036. -class Country(models.Model): - name = models.CharField(max_length=50) - -class State(models.Model): - name = models.CharField(max_length=50) - country = models.ForeignKey(Country) - -class ClientStatus(models.Model): - name = models.CharField(max_length=50) - -class Client(models.Model): - name = models.CharField(max_length=50) - state = models.ForeignKey(State, null=True) - status = models.ForeignKey(ClientStatus) - -class SpecialClient(Client): - value = models.IntegerField() - -# Some model inheritance exercises -class Parent(models.Model): - name = models.CharField(max_length=10) - - def __unicode__(self): - return self.name - -class Child(Parent): - value = models.IntegerField() - -class Item(models.Model): - name = models.CharField(max_length=10) - child = models.ForeignKey(Child, null=True) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/regressiontests/select_related_regress/tests.py b/parts/django/tests/regressiontests/select_related_regress/tests.py deleted file mode 100644 index bfa1e21..0000000 --- a/parts/django/tests/regressiontests/select_related_regress/tests.py +++ /dev/null @@ -1,134 +0,0 @@ -from django.test import TestCase -from regressiontests.select_related_regress.models import * - -class SelectRelatedRegressTests(TestCase): - - def test_regression_7110(self): - """ - Regression test for bug #7110. - - When using select_related(), we must query the - Device and Building tables using two different aliases (each) in order to - differentiate the start and end Connection fields. The net result is that - both the "connections = ..." queries here should give the same results - without pulling in more than the absolute minimum number of tables - (history has shown that it's easy to make a mistake in the implementation - and include some unnecessary bonus joins). - """ - - b=Building.objects.create(name='101') - dev1=Device.objects.create(name="router", building=b) - dev2=Device.objects.create(name="switch", building=b) - dev3=Device.objects.create(name="server", building=b) - port1=Port.objects.create(port_number='4',device=dev1) - port2=Port.objects.create(port_number='7',device=dev2) - port3=Port.objects.create(port_number='1',device=dev3) - c1=Connection.objects.create(start=port1, end=port2) - c2=Connection.objects.create(start=port2, end=port3) - - connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id') - self.assertEquals([(c.id, unicode(c.start), unicode(c.end)) for c in connections], - [(1, u'router/4', u'switch/7'), (2, u'switch/7', u'server/1')]) - - connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id') - self.assertEquals([(c.id, unicode(c.start), unicode(c.end)) for c in connections], - [(1, u'router/4', u'switch/7'), (2, u'switch/7', u'server/1')]) - - # This final query should only join seven tables (port, device and building - # twice each, plus connection once). - self.assertEquals(connections.query.count_active_tables(), 7) - - - def test_regression_8106(self): - """ - Regression test for bug #8106. - - Same sort of problem as the previous test, but this time there are - more extra tables to pull in as part of the select_related() and some - of them could potentially clash (so need to be kept separate). - """ - - us = TUser.objects.create(name="std") - usp = Person.objects.create(user=us) - uo = TUser.objects.create(name="org") - uop = Person.objects.create(user=uo) - s = Student.objects.create(person = usp) - o = Organizer.objects.create(person = uop) - c = Class.objects.create(org=o) - e = Enrollment.objects.create(std=s, cls=c) - - e_related = Enrollment.objects.all().select_related()[0] - self.assertEquals(e_related.std.person.user.name, u"std") - self.assertEquals(e_related.cls.org.person.user.name, u"org") - - def test_regression_8036(self): - """ - Regression test for bug #8036 - - the first related model in the tests below - ("state") is empty and we try to select the more remotely related - state__country. The regression here was not skipping the empty column results - for country before getting status. - """ - - australia = Country.objects.create(name='Australia') - active = ClientStatus.objects.create(name='active') - client = Client.objects.create(name='client', status=active) - - self.assertEquals(client.status, active) - self.assertEquals(Client.objects.select_related()[0].status, active) - self.assertEquals(Client.objects.select_related('state')[0].status, active) - self.assertEquals(Client.objects.select_related('state', 'status')[0].status, active) - self.assertEquals(Client.objects.select_related('state__country')[0].status, active) - self.assertEquals(Client.objects.select_related('state__country', 'status')[0].status, active) - self.assertEquals(Client.objects.select_related('status')[0].status, active) - - def test_multi_table_inheritance(self): - """ Exercising select_related() with multi-table model inheritance. """ - c1 = Child.objects.create(name="child1", value=42) - i1 = Item.objects.create(name="item1", child=c1) - i2 = Item.objects.create(name="item2") - - self.assertQuerysetEqual( - Item.objects.select_related("child").order_by("name"), - ["<Item: item1>", "<Item: item2>"] - ) - - def test_regression_12851(self): - """ - Regression for #12851 - - Deferred fields are used correctly if you select_related a subset - of fields. - """ - australia = Country.objects.create(name='Australia') - active = ClientStatus.objects.create(name='active') - - wa = State.objects.create(name="Western Australia", country=australia) - c1 = Client.objects.create(name='Brian Burke', state=wa, status=active) - burke = Client.objects.select_related('state').defer('state__name').get(name='Brian Burke') - - self.assertEquals(burke.name, u'Brian Burke') - self.assertEquals(burke.state.name, u'Western Australia') - - # Still works if we're dealing with an inherited class - sc1 = SpecialClient.objects.create(name='Troy Buswell', state=wa, status=active, value=42) - troy = SpecialClient.objects.select_related('state').defer('state__name').get(name='Troy Buswell') - - self.assertEquals(troy.name, u'Troy Buswell') - self.assertEquals(troy.value, 42) - self.assertEquals(troy.state.name, u'Western Australia') - - # Still works if we defer an attribute on the inherited class - troy = SpecialClient.objects.select_related('state').defer('value', 'state__name').get(name='Troy Buswell') - - self.assertEquals(troy.name, u'Troy Buswell') - self.assertEquals(troy.value, 42) - self.assertEquals(troy.state.name, u'Western Australia') - - # Also works if you use only, rather than defer - troy = SpecialClient.objects.select_related('state').only('name').get(name='Troy Buswell') - - self.assertEquals(troy.name, u'Troy Buswell') - self.assertEquals(troy.value, 42) - self.assertEquals(troy.state.name, u'Western Australia') diff --git a/parts/django/tests/regressiontests/serializers_regress/__init__.py b/parts/django/tests/regressiontests/serializers_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/serializers_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/serializers_regress/models.py b/parts/django/tests/regressiontests/serializers_regress/models.py deleted file mode 100644 index bec0a98..0000000 --- a/parts/django/tests/regressiontests/serializers_regress/models.py +++ /dev/null @@ -1,266 +0,0 @@ -""" -A test spanning all the capabilities of all the serializers. - -This class sets up a model for each model field type -(except for image types, because of the PIL dependency). -""" - -from django.db import models -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.contrib.localflavor.us.models import USStateField, PhoneNumberField - -# The following classes are for testing basic data -# marshalling, including NULL values, where allowed. - -class BooleanData(models.Model): - data = models.BooleanField() - -class CharData(models.Model): - data = models.CharField(max_length=30, null=True) - -class DateData(models.Model): - data = models.DateField(null=True) - -class DateTimeData(models.Model): - data = models.DateTimeField(null=True) - -class DecimalData(models.Model): - data = models.DecimalField(null=True, decimal_places=3, max_digits=5) - -class EmailData(models.Model): - data = models.EmailField(null=True) - -class FileData(models.Model): - data = models.FileField(null=True, upload_to='/foo/bar') - -class FilePathData(models.Model): - data = models.FilePathField(null=True) - -class FloatData(models.Model): - data = models.FloatField(null=True) - -class IntegerData(models.Model): - data = models.IntegerField(null=True) - -class BigIntegerData(models.Model): - data = models.BigIntegerField(null=True) - -# class ImageData(models.Model): -# data = models.ImageField(null=True) - -class IPAddressData(models.Model): - data = models.IPAddressField(null=True) - -class NullBooleanData(models.Model): - data = models.NullBooleanField(null=True) - -class PhoneData(models.Model): - data = PhoneNumberField(null=True) - -class PositiveIntegerData(models.Model): - data = models.PositiveIntegerField(null=True) - -class PositiveSmallIntegerData(models.Model): - data = models.PositiveSmallIntegerField(null=True) - -class SlugData(models.Model): - data = models.SlugField(null=True) - -class SmallData(models.Model): - data = models.SmallIntegerField(null=True) - -class TextData(models.Model): - data = models.TextField(null=True) - -class TimeData(models.Model): - data = models.TimeField(null=True) - -class USStateData(models.Model): - data = USStateField(null=True) - -class XMLData(models.Model): - data = models.XMLField(null=True) - -class Tag(models.Model): - """A tag on an item.""" - data = models.SlugField() - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - - content_object = generic.GenericForeignKey() - - class Meta: - ordering = ["data"] - -class GenericData(models.Model): - data = models.CharField(max_length=30) - - tags = generic.GenericRelation(Tag) - -# The following test classes are all for validation -# of related objects; in particular, forward, backward, -# and self references. - -class Anchor(models.Model): - """This is a model that can be used as - something for other models to point at""" - - data = models.CharField(max_length=30) - - class Meta: - ordering = ('id',) - -class UniqueAnchor(models.Model): - """This is a model that can be used as - something for other models to point at""" - - data = models.CharField(unique=True, max_length=30) - -class FKData(models.Model): - data = models.ForeignKey(Anchor, null=True) - -class M2MData(models.Model): - data = models.ManyToManyField(Anchor, null=True) - -class O2OData(models.Model): - # One to one field can't be null here, since it is a PK. - data = models.OneToOneField(Anchor, primary_key=True) - -class FKSelfData(models.Model): - data = models.ForeignKey('self', null=True) - -class M2MSelfData(models.Model): - data = models.ManyToManyField('self', null=True, symmetrical=False) - -class FKDataToField(models.Model): - data = models.ForeignKey(UniqueAnchor, null=True, to_field='data') - -class FKDataToO2O(models.Model): - data = models.ForeignKey(O2OData, null=True) - -class M2MIntermediateData(models.Model): - data = models.ManyToManyField(Anchor, null=True, through='Intermediate') - -class Intermediate(models.Model): - left = models.ForeignKey(M2MIntermediateData) - right = models.ForeignKey(Anchor) - extra = models.CharField(max_length=30, blank=True, default="doesn't matter") - -# The following test classes are for validating the -# deserialization of objects that use a user-defined -# field as the primary key. -# Some of these data types have been commented out -# because they can't be used as a primary key on one -# or all database backends. - -class BooleanPKData(models.Model): - data = models.BooleanField(primary_key=True) - -class CharPKData(models.Model): - data = models.CharField(max_length=30, primary_key=True) - -# class DatePKData(models.Model): -# data = models.DateField(primary_key=True) - -# class DateTimePKData(models.Model): -# data = models.DateTimeField(primary_key=True) - -class DecimalPKData(models.Model): - data = models.DecimalField(primary_key=True, decimal_places=3, max_digits=5) - -class EmailPKData(models.Model): - data = models.EmailField(primary_key=True) - -# class FilePKData(models.Model): -# data = models.FileField(primary_key=True, upload_to='/foo/bar') - -class FilePathPKData(models.Model): - data = models.FilePathField(primary_key=True) - -class FloatPKData(models.Model): - data = models.FloatField(primary_key=True) - -class IntegerPKData(models.Model): - data = models.IntegerField(primary_key=True) - -# class ImagePKData(models.Model): -# data = models.ImageField(primary_key=True) - -class IPAddressPKData(models.Model): - data = models.IPAddressField(primary_key=True) - -# This is just a Boolean field with null=True, and we can't test a PK value of NULL. -# class NullBooleanPKData(models.Model): -# data = models.NullBooleanField(primary_key=True) - -class PhonePKData(models.Model): - data = PhoneNumberField(primary_key=True) - -class PositiveIntegerPKData(models.Model): - data = models.PositiveIntegerField(primary_key=True) - -class PositiveSmallIntegerPKData(models.Model): - data = models.PositiveSmallIntegerField(primary_key=True) - -class SlugPKData(models.Model): - data = models.SlugField(primary_key=True) - -class SmallPKData(models.Model): - data = models.SmallIntegerField(primary_key=True) - -# class TextPKData(models.Model): -# data = models.TextField(primary_key=True) - -# class TimePKData(models.Model): -# data = models.TimeField(primary_key=True) - -class USStatePKData(models.Model): - data = USStateField(primary_key=True) - -# class XMLPKData(models.Model): -# data = models.XMLField(primary_key=True) - -class ComplexModel(models.Model): - field1 = models.CharField(max_length=10) - field2 = models.CharField(max_length=10) - field3 = models.CharField(max_length=10) - -# Tests for handling fields with pre_save functions, or -# models with save functions that modify data -class AutoNowDateTimeData(models.Model): - data = models.DateTimeField(null=True, auto_now=True) - -class ModifyingSaveData(models.Model): - data = models.IntegerField(null=True) - - def save(self): - "A save method that modifies the data in the object" - self.data = 666 - super(ModifyingSaveData, self).save(raw) - -# Tests for serialization of models using inheritance. -# Regression for #7202, #7350 -class AbstractBaseModel(models.Model): - parent_data = models.IntegerField() - class Meta: - abstract = True - -class InheritAbstractModel(AbstractBaseModel): - child_data = models.IntegerField() - -class BaseModel(models.Model): - parent_data = models.IntegerField() - -class InheritBaseModel(BaseModel): - child_data = models.IntegerField() - -class ExplicitInheritBaseModel(BaseModel): - parent = models.OneToOneField(BaseModel) - child_data = models.IntegerField() - -class LengthModel(models.Model): - data = models.IntegerField() - - def __len__(self): - return self.data diff --git a/parts/django/tests/regressiontests/serializers_regress/tests.py b/parts/django/tests/regressiontests/serializers_regress/tests.py deleted file mode 100644 index be920c6..0000000 --- a/parts/django/tests/regressiontests/serializers_regress/tests.py +++ /dev/null @@ -1,421 +0,0 @@ -""" -A test spanning all the capabilities of all the serializers. - -This class defines sample data and a dynamically generated -test case that is capable of testing the capabilities of -the serializers. This includes all valid data values, plus -forward, backwards and self references. -""" - - -import datetime -import decimal -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -from django.conf import settings -from django.core import serializers, management -from django.db import transaction, DEFAULT_DB_ALIAS -from django.test import TestCase -from django.utils.functional import curry - -from models import * - -# A set of functions that can be used to recreate -# test data objects of various kinds. -# The save method is a raw base model save, to make -# sure that the data in the database matches the -# exact test case. -def data_create(pk, klass, data): - instance = klass(id=pk) - instance.data = data - models.Model.save_base(instance, raw=True) - return [instance] - -def generic_create(pk, klass, data): - instance = klass(id=pk) - instance.data = data[0] - models.Model.save_base(instance, raw=True) - for tag in data[1:]: - instance.tags.create(data=tag) - return [instance] - -def fk_create(pk, klass, data): - instance = klass(id=pk) - setattr(instance, 'data_id', data) - models.Model.save_base(instance, raw=True) - return [instance] - -def m2m_create(pk, klass, data): - instance = klass(id=pk) - models.Model.save_base(instance, raw=True) - instance.data = data - return [instance] - -def im2m_create(pk, klass, data): - instance = klass(id=pk) - models.Model.save_base(instance, raw=True) - return [instance] - -def im_create(pk, klass, data): - instance = klass(id=pk) - instance.right_id = data['right'] - instance.left_id = data['left'] - if 'extra' in data: - instance.extra = data['extra'] - models.Model.save_base(instance, raw=True) - return [instance] - -def o2o_create(pk, klass, data): - instance = klass() - instance.data_id = data - models.Model.save_base(instance, raw=True) - return [instance] - -def pk_create(pk, klass, data): - instance = klass() - instance.data = data - models.Model.save_base(instance, raw=True) - return [instance] - -def inherited_create(pk, klass, data): - instance = klass(id=pk,**data) - # This isn't a raw save because: - # 1) we're testing inheritance, not field behaviour, so none - # of the field values need to be protected. - # 2) saving the child class and having the parent created - # automatically is easier than manually creating both. - models.Model.save(instance) - created = [instance] - for klass,field in instance._meta.parents.items(): - created.append(klass.objects.get(id=pk)) - return created - -# A set of functions that can be used to compare -# test data objects of various kinds -def data_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - testcase.assertEqual(data, instance.data, - "Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % ( - pk, data, type(data), instance.data, type(instance.data)) - ) - -def generic_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - testcase.assertEqual(data[0], instance.data) - testcase.assertEqual(data[1:], [t.data for t in instance.tags.order_by('id')]) - -def fk_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - testcase.assertEqual(data, instance.data_id) - -def m2m_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - testcase.assertEqual(data, [obj.id for obj in instance.data.order_by('id')]) - -def im2m_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - #actually nothing else to check, the instance just should exist - -def im_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - testcase.assertEqual(data['left'], instance.left_id) - testcase.assertEqual(data['right'], instance.right_id) - if 'extra' in data: - testcase.assertEqual(data['extra'], instance.extra) - else: - testcase.assertEqual("doesn't matter", instance.extra) - -def o2o_compare(testcase, pk, klass, data): - instance = klass.objects.get(data=data) - testcase.assertEqual(data, instance.data_id) - -def pk_compare(testcase, pk, klass, data): - instance = klass.objects.get(data=data) - testcase.assertEqual(data, instance.data) - -def inherited_compare(testcase, pk, klass, data): - instance = klass.objects.get(id=pk) - for key,value in data.items(): - testcase.assertEqual(value, getattr(instance,key)) - -# Define some data types. Each data type is -# actually a pair of functions; one to create -# and one to compare objects of that type -data_obj = (data_create, data_compare) -generic_obj = (generic_create, generic_compare) -fk_obj = (fk_create, fk_compare) -m2m_obj = (m2m_create, m2m_compare) -im2m_obj = (im2m_create, im2m_compare) -im_obj = (im_create, im_compare) -o2o_obj = (o2o_create, o2o_compare) -pk_obj = (pk_create, pk_compare) -inherited_obj = (inherited_create, inherited_compare) - -test_data = [ - # Format: (data type, PK value, Model Class, data) - (data_obj, 1, BooleanData, True), - (data_obj, 2, BooleanData, False), - (data_obj, 10, CharData, "Test Char Data"), - (data_obj, 11, CharData, ""), - (data_obj, 12, CharData, "None"), - (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)), - (data_obj, 31, DateTimeData, None), - (data_obj, 40, EmailData, "hovercraft@example.com"), - (data_obj, 41, EmailData, None), - (data_obj, 42, EmailData, ""), - (data_obj, 50, FileData, 'file:///foo/bar/whiz.txt'), -# (data_obj, 51, FileData, None), - (data_obj, 52, FileData, ""), - (data_obj, 60, FilePathData, "/foo/bar/whiz.txt"), - (data_obj, 61, FilePathData, None), - (data_obj, 62, FilePathData, ""), - (data_obj, 70, DecimalData, decimal.Decimal('12.345')), - (data_obj, 71, DecimalData, decimal.Decimal('-12.345')), - (data_obj, 72, DecimalData, decimal.Decimal('0.0')), - (data_obj, 73, DecimalData, None), - (data_obj, 74, FloatData, 12.345), - (data_obj, 75, FloatData, -12.345), - (data_obj, 76, FloatData, 0.0), - (data_obj, 77, FloatData, None), - (data_obj, 80, IntegerData, 123456789), - (data_obj, 81, IntegerData, -123456789), - (data_obj, 82, IntegerData, 0), - (data_obj, 83, IntegerData, None), - #(XX, ImageData - (data_obj, 90, IPAddressData, "127.0.0.1"), - (data_obj, 91, IPAddressData, None), - (data_obj, 100, NullBooleanData, True), - (data_obj, 101, NullBooleanData, False), - (data_obj, 102, NullBooleanData, None), - (data_obj, 110, PhoneData, "212-634-5789"), - (data_obj, 111, PhoneData, None), - (data_obj, 120, PositiveIntegerData, 123456789), - (data_obj, 121, PositiveIntegerData, None), - (data_obj, 130, PositiveSmallIntegerData, 12), - (data_obj, 131, PositiveSmallIntegerData, None), - (data_obj, 140, SlugData, "this-is-a-slug"), - (data_obj, 141, SlugData, None), - (data_obj, 142, SlugData, ""), - (data_obj, 150, SmallData, 12), - (data_obj, 151, SmallData, -12), - (data_obj, 152, SmallData, 0), - (data_obj, 153, SmallData, None), - (data_obj, 160, TextData, """This is a long piece of text. -It contains line breaks. -Several of them. -The end."""), - (data_obj, 161, TextData, ""), - (data_obj, 162, TextData, None), - (data_obj, 170, TimeData, datetime.time(10,42,37)), - (data_obj, 171, TimeData, None), - (data_obj, 180, USStateData, "MA"), - (data_obj, 181, USStateData, None), - (data_obj, 182, USStateData, ""), - (data_obj, 190, XMLData, "<foo></foo>"), - (data_obj, 191, XMLData, None), - (data_obj, 192, XMLData, ""), - - (generic_obj, 200, GenericData, ['Generic Object 1', 'tag1', 'tag2']), - (generic_obj, 201, GenericData, ['Generic Object 2', 'tag2', 'tag3']), - - (data_obj, 300, Anchor, "Anchor 1"), - (data_obj, 301, Anchor, "Anchor 2"), - (data_obj, 302, UniqueAnchor, "UAnchor 1"), - - (fk_obj, 400, FKData, 300), # Post reference - (fk_obj, 401, FKData, 500), # Pre reference - (fk_obj, 402, FKData, None), # Empty reference - - (m2m_obj, 410, M2MData, []), # Empty set - (m2m_obj, 411, M2MData, [300,301]), # Post reference - (m2m_obj, 412, M2MData, [500,501]), # Pre reference - (m2m_obj, 413, M2MData, [300,301,500,501]), # Pre and Post reference - - (o2o_obj, None, O2OData, 300), # Post reference - (o2o_obj, None, O2OData, 500), # Pre reference - - (fk_obj, 430, FKSelfData, 431), # Pre reference - (fk_obj, 431, FKSelfData, 430), # Post reference - (fk_obj, 432, FKSelfData, None), # Empty reference - - (m2m_obj, 440, M2MSelfData, []), - (m2m_obj, 441, M2MSelfData, []), - (m2m_obj, 442, M2MSelfData, [440, 441]), - (m2m_obj, 443, M2MSelfData, [445, 446]), - (m2m_obj, 444, M2MSelfData, [440, 441, 445, 446]), - (m2m_obj, 445, M2MSelfData, []), - (m2m_obj, 446, M2MSelfData, []), - - (fk_obj, 450, FKDataToField, "UAnchor 1"), - (fk_obj, 451, FKDataToField, "UAnchor 2"), - (fk_obj, 452, FKDataToField, None), - - (fk_obj, 460, FKDataToO2O, 300), - - (im2m_obj, 470, M2MIntermediateData, None), - - #testing post- and prereferences and extra fields - (im_obj, 480, Intermediate, {'right': 300, 'left': 470}), - (im_obj, 481, Intermediate, {'right': 300, 'left': 490}), - (im_obj, 482, Intermediate, {'right': 500, 'left': 470}), - (im_obj, 483, Intermediate, {'right': 500, 'left': 490}), - (im_obj, 484, Intermediate, {'right': 300, 'left': 470, 'extra': "extra"}), - (im_obj, 485, Intermediate, {'right': 300, 'left': 490, 'extra': "extra"}), - (im_obj, 486, Intermediate, {'right': 500, 'left': 470, 'extra': "extra"}), - (im_obj, 487, Intermediate, {'right': 500, 'left': 490, 'extra': "extra"}), - - (im2m_obj, 490, M2MIntermediateData, []), - - (data_obj, 500, Anchor, "Anchor 3"), - (data_obj, 501, Anchor, "Anchor 4"), - (data_obj, 502, UniqueAnchor, "UAnchor 2"), - - (pk_obj, 601, BooleanPKData, True), - (pk_obj, 602, BooleanPKData, False), - (pk_obj, 610, CharPKData, "Test Char PKData"), -# (pk_obj, 620, DatePKData, datetime.date(2006,6,16)), -# (pk_obj, 630, DateTimePKData, datetime.datetime(2006,6,16,10,42,37)), - (pk_obj, 640, EmailPKData, "hovercraft@example.com"), -# (pk_obj, 650, FilePKData, 'file:///foo/bar/whiz.txt'), - (pk_obj, 660, FilePathPKData, "/foo/bar/whiz.txt"), - (pk_obj, 670, DecimalPKData, decimal.Decimal('12.345')), - (pk_obj, 671, DecimalPKData, decimal.Decimal('-12.345')), - (pk_obj, 672, DecimalPKData, decimal.Decimal('0.0')), - (pk_obj, 673, FloatPKData, 12.345), - (pk_obj, 674, FloatPKData, -12.345), - (pk_obj, 675, FloatPKData, 0.0), - (pk_obj, 680, IntegerPKData, 123456789), - (pk_obj, 681, IntegerPKData, -123456789), - (pk_obj, 682, IntegerPKData, 0), -# (XX, ImagePKData - (pk_obj, 690, IPAddressPKData, "127.0.0.1"), - # (pk_obj, 700, NullBooleanPKData, True), - # (pk_obj, 701, NullBooleanPKData, False), - (pk_obj, 710, PhonePKData, "212-634-5789"), - (pk_obj, 720, PositiveIntegerPKData, 123456789), - (pk_obj, 730, PositiveSmallIntegerPKData, 12), - (pk_obj, 740, SlugPKData, "this-is-a-slug"), - (pk_obj, 750, SmallPKData, 12), - (pk_obj, 751, SmallPKData, -12), - (pk_obj, 752, SmallPKData, 0), -# (pk_obj, 760, TextPKData, """This is a long piece of text. -# It contains line breaks. -# Several of them. -# The end."""), -# (pk_obj, 770, TimePKData, datetime.time(10,42,37)), - (pk_obj, 780, USStatePKData, "MA"), -# (pk_obj, 790, XMLPKData, "<foo></foo>"), - - (data_obj, 800, AutoNowDateTimeData, datetime.datetime(2006,6,16,10,42,37)), - (data_obj, 810, ModifyingSaveData, 42), - - (inherited_obj, 900, InheritAbstractModel, {'child_data':37,'parent_data':42}), - (inherited_obj, 910, ExplicitInheritBaseModel, {'child_data':37,'parent_data':42}), - (inherited_obj, 920, InheritBaseModel, {'child_data':37,'parent_data':42}), - - (data_obj, 1000, BigIntegerData, 9223372036854775807), - (data_obj, 1001, BigIntegerData, -9223372036854775808), - (data_obj, 1002, BigIntegerData, 0), - (data_obj, 1003, BigIntegerData, None), - (data_obj, 1004, LengthModel, 0), - (data_obj, 1005, LengthModel, 1), -] - -# Because Oracle treats the empty string as NULL, Oracle is expected to fail -# when field.empty_strings_allowed is True and the value is None; skip these -# tests. -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle': - test_data = [data for data in test_data - if not (data[0] == data_obj and - data[2]._meta.get_field('data').empty_strings_allowed and - data[3] is None)] - -# Regression test for #8651 -- a FK to an object iwth PK of 0 -# This won't work on MySQL since it won't let you create an object -# with a primary key of 0, -if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql': - test_data.extend([ - (data_obj, 0, Anchor, "Anchor 0"), - (fk_obj, 465, FKData, 0), - ]) - -# Dynamically create serializer tests to ensure that all -# registered serializers are automatically tested. -class SerializerTests(TestCase): - pass - -def serializerTest(format, self): - - # Create all the objects defined in the test data - objects = [] - instance_count = {} - for (func, pk, klass, datum) in test_data: - objects.extend(func[0](pk, klass, datum)) - - # Get a count of the number of objects created for each class - for klass in instance_count: - instance_count[klass] = klass.objects.count() - - # Add the generic tagged objects to the object list - objects.extend(Tag.objects.all()) - - # Serialize the test database - serialized_data = serializers.serialize(format, objects, indent=2) - - for obj in serializers.deserialize(format, serialized_data): - obj.save() - - # Assert that the deserialized data is the same - # as the original source - for (func, pk, klass, datum) in test_data: - func[1](self, pk, klass, datum) - - # Assert that the number of objects deserialized is the - # same as the number that was serialized. - for klass, count in instance_count.items(): - self.assertEquals(count, klass.objects.count()) - -def fieldsTest(format, self): - obj = ComplexModel(field1='first', field2='second', field3='third') - obj.save_base(raw=True) - - # Serialize then deserialize the test database - serialized_data = serializers.serialize(format, [obj], indent=2, fields=('field1','field3')) - result = serializers.deserialize(format, serialized_data).next() - - # Check that the deserialized object contains data in only the serialized fields. - self.assertEqual(result.object.field1, 'first') - self.assertEqual(result.object.field2, '') - self.assertEqual(result.object.field3, 'third') - -def streamTest(format, self): - obj = ComplexModel(field1='first',field2='second',field3='third') - obj.save_base(raw=True) - - # Serialize the test database to a stream - stream = StringIO() - serializers.serialize(format, [obj], indent=2, stream=stream) - - # Serialize normally for a comparison - string_data = serializers.serialize(format, [obj], indent=2) - - # Check that the two are the same - self.assertEqual(string_data, stream.getvalue()) - stream.close() - -for format in serializers.get_serializer_formats(): - setattr(SerializerTests, 'test_' + format + '_serializer', curry(serializerTest, format)) - setattr(SerializerTests, 'test_' + format + '_serializer_fields', curry(fieldsTest, format)) - if format != 'python': - setattr(SerializerTests, 'test_' + format + '_serializer_stream', curry(streamTest, format)) diff --git a/parts/django/tests/regressiontests/servers/__init__.py b/parts/django/tests/regressiontests/servers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/servers/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/servers/models.py b/parts/django/tests/regressiontests/servers/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/servers/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/servers/tests.py b/parts/django/tests/regressiontests/servers/tests.py deleted file mode 100644 index 4763982..0000000 --- a/parts/django/tests/regressiontests/servers/tests.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -Tests for django.core.servers. -""" - -import os - -import django -from django.test import TestCase -from django.core.handlers.wsgi import WSGIHandler -from django.core.servers.basehttp import AdminMediaHandler - - -class AdminMediaHandlerTests(TestCase): - - def setUp(self): - self.admin_media_file_path = os.path.abspath( - os.path.join(django.__path__[0], 'contrib', 'admin', 'media') - ) - self.handler = AdminMediaHandler(WSGIHandler()) - - def test_media_urls(self): - """ - Tests that URLs that look like absolute file paths after the - settings.ADMIN_MEDIA_PREFIX don't turn into absolute file paths. - """ - # Cases that should work on all platforms. - data = ( - ('/media/css/base.css', ('css', 'base.css')), - ) - # Cases that should raise an exception. - bad_data = () - - # Add platform-specific cases. - if os.sep == '/': - data += ( - # URL, tuple of relative path parts. - ('/media/\\css/base.css', ('\\css', 'base.css')), - ) - bad_data += ( - '/media//css/base.css', - '/media////css/base.css', - '/media/../css/base.css', - ) - elif os.sep == '\\': - bad_data += ( - '/media/C:\css/base.css', - '/media//\\css/base.css', - '/media/\\css/base.css', - '/media/\\\\css/base.css' - ) - for url, path_tuple in data: - try: - output = self.handler.file_path(url) - except ValueError: - self.fail("Got a ValueError exception, but wasn't expecting" - " one. URL was: %s" % url) - rel_path = os.path.join(*path_tuple) - desired = os.path.normcase( - os.path.join(self.admin_media_file_path, rel_path)) - self.assertEqual(output, desired, - "Got: %s, Expected: %s, URL was: %s" % (output, desired, url)) - for url in bad_data: - try: - output = self.handler.file_path(url) - except ValueError: - continue - self.fail('URL: %s should have caused a ValueError exception.' - % url) diff --git a/parts/django/tests/regressiontests/settings_tests/__init__.py b/parts/django/tests/regressiontests/settings_tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/settings_tests/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/settings_tests/models.py b/parts/django/tests/regressiontests/settings_tests/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/settings_tests/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/settings_tests/tests.py b/parts/django/tests/regressiontests/settings_tests/tests.py deleted file mode 100644 index fa217b1..0000000 --- a/parts/django/tests/regressiontests/settings_tests/tests.py +++ /dev/null @@ -1,17 +0,0 @@ -import unittest -from django.conf import settings - -class SettingsTests(unittest.TestCase): - - # - # Regression tests for #10130: deleting settings. - # - - def test_settings_delete(self): - settings.TEST = 'test' - self.assertEqual('test', settings.TEST) - del settings.TEST - self.assertRaises(AttributeError, getattr, settings, 'TEST') - - def test_settings_delete_wrapped(self): - self.assertRaises(TypeError, delattr, settings, '_wrapped') diff --git a/parts/django/tests/regressiontests/signals_regress/__init__.py b/parts/django/tests/regressiontests/signals_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/signals_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/signals_regress/models.py b/parts/django/tests/regressiontests/signals_regress/models.py deleted file mode 100644 index e7879d8..0000000 --- a/parts/django/tests/regressiontests/signals_regress/models.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.db import models - -class Author(models.Model): - name = models.CharField(max_length=20) - - def __unicode__(self): - return self.name - -class Book(models.Model): - name = models.CharField(max_length=20) - authors = models.ManyToManyField(Author) - - def __unicode__(self): - return self.name diff --git a/parts/django/tests/regressiontests/signals_regress/tests.py b/parts/django/tests/regressiontests/signals_regress/tests.py deleted file mode 100644 index 234893f..0000000 --- a/parts/django/tests/regressiontests/signals_regress/tests.py +++ /dev/null @@ -1,96 +0,0 @@ -import sys -from StringIO import StringIO -from django.test import TestCase - -from django.db import models -from regressiontests.signals_regress.models import Author, Book - -signal_output = [] - -def pre_save_test(signal, sender, instance, **kwargs): - signal_output.append('pre_save signal, %s' % instance) - if kwargs.get('raw'): - signal_output.append('Is raw') - -def post_save_test(signal, sender, instance, **kwargs): - signal_output.append('post_save signal, %s' % instance) - if 'created' in kwargs: - if kwargs['created']: - signal_output.append('Is created') - else: - signal_output.append('Is updated') - if kwargs.get('raw'): - signal_output.append('Is raw') - -def pre_delete_test(signal, sender, instance, **kwargs): - signal_output.append('pre_save signal, %s' % instance) - signal_output.append('instance.id is not None: %s' % (instance.id != None)) - -def post_delete_test(signal, sender, instance, **kwargs): - signal_output.append('post_delete signal, %s' % instance) - signal_output.append('instance.id is not None: %s' % (instance.id != None)) - -class SignalsRegressTests(TestCase): - """ - Testing signals before/after saving and deleting. - """ - - def get_signal_output(self, fn, *args, **kwargs): - # Flush any existing signal output - global signal_output - signal_output = [] - fn(*args, **kwargs) - return signal_output - - def setUp(self): - # Save up the number of connected signals so that we can check at the end - # that all the signals we register get properly unregistered (#9989) - self.pre_signals = (len(models.signals.pre_save.receivers), - len(models.signals.post_save.receivers), - len(models.signals.pre_delete.receivers), - len(models.signals.post_delete.receivers)) - - models.signals.pre_save.connect(pre_save_test) - models.signals.post_save.connect(post_save_test) - models.signals.pre_delete.connect(pre_delete_test) - models.signals.post_delete.connect(post_delete_test) - - def tearDown(self): - models.signals.post_delete.disconnect(post_delete_test) - models.signals.pre_delete.disconnect(pre_delete_test) - models.signals.post_save.disconnect(post_save_test) - models.signals.pre_save.disconnect(pre_save_test) - - # Check that all our signals got disconnected properly. - post_signals = (len(models.signals.pre_save.receivers), - len(models.signals.post_save.receivers), - len(models.signals.pre_delete.receivers), - len(models.signals.post_delete.receivers)) - - self.assertEquals(self.pre_signals, post_signals) - - def test_model_signals(self): - """ Model saves should throw some signals. """ - a1 = Author(name='Neal Stephenson') - self.assertEquals(self.get_signal_output(a1.save), [ - "pre_save signal, Neal Stephenson", - "post_save signal, Neal Stephenson", - "Is created" - ]) - - b1 = Book(name='Snow Crash') - self.assertEquals(self.get_signal_output(b1.save), [ - "pre_save signal, Snow Crash", - "post_save signal, Snow Crash", - "Is created" - ]) - - def test_m2m_signals(self): - """ Assigning and removing to/from m2m shouldn't generate an m2m signal """ - - b1 = Book(name='Snow Crash') - self.get_signal_output(b1.save) - a1 = Author(name='Neal Stephenson') - self.get_signal_output(a1.save) - self.assertEquals(self.get_signal_output(setattr, b1, 'authors', [a1]), []) - self.assertEquals(self.get_signal_output(setattr, b1, 'authors', []), []) diff --git a/parts/django/tests/regressiontests/sites_framework/__init__.py b/parts/django/tests/regressiontests/sites_framework/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/sites_framework/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/sites_framework/models.py b/parts/django/tests/regressiontests/sites_framework/models.py deleted file mode 100644 index 9ecc3e6..0000000 --- a/parts/django/tests/regressiontests/sites_framework/models.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.contrib.sites.managers import CurrentSiteManager -from django.contrib.sites.models import Site -from django.db import models - -class AbstractArticle(models.Model): - title = models.CharField(max_length=50) - - objects = models.Manager() - on_site = CurrentSiteManager() - - class Meta: - abstract = True - - def __unicode__(self): - return self.title - -class SyndicatedArticle(AbstractArticle): - sites = models.ManyToManyField(Site) - -class ExclusiveArticle(AbstractArticle): - site = models.ForeignKey(Site) - -class CustomArticle(AbstractArticle): - places_this_article_should_appear = models.ForeignKey(Site) - - objects = models.Manager() - on_site = CurrentSiteManager("places_this_article_should_appear") - -class InvalidArticle(AbstractArticle): - site = models.ForeignKey(Site) - - objects = models.Manager() - on_site = CurrentSiteManager("places_this_article_should_appear") - -class ConfusedArticle(AbstractArticle): - site = models.IntegerField() diff --git a/parts/django/tests/regressiontests/sites_framework/tests.py b/parts/django/tests/regressiontests/sites_framework/tests.py deleted file mode 100644 index b737727..0000000 --- a/parts/django/tests/regressiontests/sites_framework/tests.py +++ /dev/null @@ -1,34 +0,0 @@ -from django.conf import settings -from django.contrib.sites.models import Site -from django.test import TestCase - -from models import SyndicatedArticle, ExclusiveArticle, CustomArticle, InvalidArticle, ConfusedArticle - -class SitesFrameworkTestCase(TestCase): - def setUp(self): - Site.objects.get_or_create(id=settings.SITE_ID, domain="example.com", name="example.com") - Site.objects.create(id=settings.SITE_ID+1, domain="example2.com", name="example2.com") - - def test_site_fk(self): - article = ExclusiveArticle.objects.create(title="Breaking News!", site_id=settings.SITE_ID) - self.assertEqual(ExclusiveArticle.on_site.all().get(), article) - - def test_sites_m2m(self): - article = SyndicatedArticle.objects.create(title="Fresh News!") - article.sites.add(Site.objects.get(id=settings.SITE_ID)) - article.sites.add(Site.objects.get(id=settings.SITE_ID+1)) - article2 = SyndicatedArticle.objects.create(title="More News!") - article2.sites.add(Site.objects.get(id=settings.SITE_ID+1)) - self.assertEqual(SyndicatedArticle.on_site.all().get(), article) - - def test_custom_named_field(self): - article = CustomArticle.objects.create(title="Tantalizing News!", places_this_article_should_appear_id=settings.SITE_ID) - self.assertEqual(CustomArticle.on_site.all().get(), article) - - def test_invalid_name(self): - article = InvalidArticle.objects.create(title="Bad News!", site_id=settings.SITE_ID) - self.assertRaises(ValueError, InvalidArticle.on_site.all) - - def test_invalid_field_type(self): - article = ConfusedArticle.objects.create(title="More Bad News!", site=settings.SITE_ID) - self.assertRaises(TypeError, ConfusedArticle.on_site.all) diff --git a/parts/django/tests/regressiontests/special_headers/__init__.py b/parts/django/tests/regressiontests/special_headers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/special_headers/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/special_headers/fixtures/data.xml b/parts/django/tests/regressiontests/special_headers/fixtures/data.xml deleted file mode 100644 index 7e60d45..0000000 --- a/parts/django/tests/regressiontests/special_headers/fixtures/data.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="1" model="special_headers.article"> - <field type="TextField" name="text">text</field> - </object> -</django-objects> diff --git a/parts/django/tests/regressiontests/special_headers/models.py b/parts/django/tests/regressiontests/special_headers/models.py deleted file mode 100644 index 0c12675..0000000 --- a/parts/django/tests/regressiontests/special_headers/models.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.db import models - -class Article(models.Model): - text = models.TextField() diff --git a/parts/django/tests/regressiontests/special_headers/templates/special_headers/article_detail.html b/parts/django/tests/regressiontests/special_headers/templates/special_headers/article_detail.html deleted file mode 100644 index 3cbd38c..0000000 --- a/parts/django/tests/regressiontests/special_headers/templates/special_headers/article_detail.html +++ /dev/null @@ -1 +0,0 @@ -{{ object }} diff --git a/parts/django/tests/regressiontests/special_headers/tests.py b/parts/django/tests/regressiontests/special_headers/tests.py deleted file mode 100644 index f304bfa..0000000 --- a/parts/django/tests/regressiontests/special_headers/tests.py +++ /dev/null @@ -1,40 +0,0 @@ -from django.test import TestCase -from django.contrib.auth.models import User - -class SpecialHeadersTest(TestCase): - fixtures = ['data.xml'] - - def test_xheaders(self): - user = User.objects.get(username='super') - response = self.client.get('/special_headers/article/1/') - # import pdb; pdb.set_trace() - self.failUnless('X-Object-Type' not in response) - self.client.login(username='super', password='secret') - response = self.client.get('/special_headers/article/1/') - self.failUnless('X-Object-Type' in response) - user.is_staff = False - user.save() - response = self.client.get('/special_headers/article/1/') - self.failUnless('X-Object-Type' not in response) - user.is_staff = True - user.is_active = False - user.save() - response = self.client.get('/special_headers/article/1/') - self.failUnless('X-Object-Type' not in response) - - def test_xview(self): - user = User.objects.get(username='super') - response = self.client.head('/special_headers/xview/') - self.failUnless('X-View' not in response) - self.client.login(username='super', password='secret') - response = self.client.head('/special_headers/xview/') - self.failUnless('X-View' in response) - user.is_staff = False - user.save() - response = self.client.head('/special_headers/xview/') - self.failUnless('X-View' not in response) - user.is_staff = True - user.is_active = False - user.save() - response = self.client.head('/special_headers/xview/') - self.failUnless('X-View' not in response) diff --git a/parts/django/tests/regressiontests/special_headers/urls.py b/parts/django/tests/regressiontests/special_headers/urls.py deleted file mode 100644 index 721f60a..0000000 --- a/parts/django/tests/regressiontests/special_headers/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -# coding: utf-8 -from django.conf.urls.defaults import * -from django.views.generic.list_detail import object_detail -from models import Article -import views - -urlpatterns = patterns('', - (r'^article/(?P<object_id>\d+)/$', object_detail, {'queryset': Article.objects.all()}), - (r'^xview/$', views.xview), -) diff --git a/parts/django/tests/regressiontests/special_headers/views.py b/parts/django/tests/regressiontests/special_headers/views.py deleted file mode 100644 index 7a01203..0000000 --- a/parts/django/tests/regressiontests/special_headers/views.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding:utf-8 -*- -from django.http import HttpResponse -from django.utils.decorators import decorator_from_middleware -from django.middleware.doc import XViewMiddleware - -xview_dec = decorator_from_middleware(XViewMiddleware) - -def xview(request): - return HttpResponse() -xview = xview_dec(xview) diff --git a/parts/django/tests/regressiontests/string_lookup/__init__.py b/parts/django/tests/regressiontests/string_lookup/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/string_lookup/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/string_lookup/models.py b/parts/django/tests/regressiontests/string_lookup/models.py deleted file mode 100644 index 037854d..0000000 --- a/parts/django/tests/regressiontests/string_lookup/models.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -from django.db import models - -class Foo(models.Model): - name = models.CharField(max_length=50) - friend = models.CharField(max_length=50, blank=True) - - def __unicode__(self): - return "Foo %s" % self.name - -class Bar(models.Model): - name = models.CharField(max_length=50) - normal = models.ForeignKey(Foo, related_name='normal_foo') - fwd = models.ForeignKey("Whiz") - back = models.ForeignKey("Foo") - - def __unicode__(self): - return "Bar %s" % self.place.name - -class Whiz(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return "Whiz %s" % self.name - -class Child(models.Model): - parent = models.OneToOneField('Base') - name = models.CharField(max_length=50) - - def __unicode__(self): - return "Child %s" % self.name - -class Base(models.Model): - name = models.CharField(max_length=50) - - def __unicode__(self): - return "Base %s" % self.name - -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 diff --git a/parts/django/tests/regressiontests/string_lookup/tests.py b/parts/django/tests/regressiontests/string_lookup/tests.py deleted file mode 100644 index ddf7a8a..0000000 --- a/parts/django/tests/regressiontests/string_lookup/tests.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- -from django.test import TestCase -from regressiontests.string_lookup.models import Foo, Whiz, Bar, Article, Base, Child - -class StringLookupTests(TestCase): - - def test_string_form_referencing(self): - """ - 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="Foo2") - f2.save() - - w1 = Whiz(name="Whiz1") - w1.save() - - b1 = Bar(name="Bar1", normal=f1, fwd=w1, back=f2) - b1.save() - - self.assertEquals(b1.normal, f1) - - self.assertEquals(b1.fwd, w1) - - self.assertEquals(b1.back, f2) - - base1 = Base(name="Base1") - base1.save() - - child1 = Child(name="Child1", parent=base1) - child1.save() - - self.assertEquals(child1.parent, base1) - - def test_unicode_chars_in_queries(self): - """ - Regression tests for #3937 - - make sure we can use unicode characters in queries. - If these tests fail on MySQL, 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() - self.assertEquals(Foo.objects.get(friend__contains=u'\xe7'), fx) - - # We can also do the above query using UTF-8 strings. - self.assertEquals(Foo.objects.get(friend__contains='\xc3\xa7'), fx) - - def test_queries_on_textfields(self): - """ - Regression tests for #5087 - - make sure we can perform queries on TextFields. - """ - - a = Article(name='Test', text='The quick brown fox jumps over the lazy dog.') - a.save() - self.assertEquals(Article.objects.get(text__exact='The quick brown fox jumps over the lazy dog.'), a) - - self.assertEquals(Article.objects.get(text__contains='quick brown fox'), a) - - def test_ipaddress_on_postgresql(self): - """ - Regression test for #708 - - "like" queries on IP address fields require casting to text (on PostgreSQL). - """ - a = Article(name='IP test', text='The body', submitted_from='192.0.2.100') - a.save() - self.assertEquals(repr(Article.objects.filter(submitted_from__contains='192.0.2')), - repr([a])) diff --git a/parts/django/tests/regressiontests/syndication/__init__.py b/parts/django/tests/regressiontests/syndication/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/syndication/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/syndication/feeds.py b/parts/django/tests/regressiontests/syndication/feeds.py deleted file mode 100644 index 5563170..0000000 --- a/parts/django/tests/regressiontests/syndication/feeds.py +++ /dev/null @@ -1,142 +0,0 @@ -from django.contrib.syndication import feeds, views -from django.core.exceptions import ObjectDoesNotExist -from django.utils import feedgenerator, tzinfo -from models import Article, Entry - - -class ComplexFeed(views.Feed): - def get_object(self, request, foo=None): - if foo is not None: - raise ObjectDoesNotExist - return None - - -class TestRss2Feed(views.Feed): - title = 'My blog' - description = 'A more thorough description of my blog.' - link = '/blog/' - feed_guid = '/foo/bar/1234' - author_name = 'Sally Smith' - author_email = 'test@example.com' - author_link = 'http://www.example.com/' - categories = ('python', 'django') - feed_copyright = 'Copyright (c) 2007, Sally Smith' - ttl = 600 - - def items(self): - return Entry.objects.all() - - def item_description(self, item): - return "Overridden description: %s" % item - - def item_pubdate(self, item): - return item.date - - item_author_name = 'Sally Smith' - item_author_email = 'test@example.com' - item_author_link = 'http://www.example.com/' - item_categories = ('python', 'testing') - item_copyright = 'Copyright (c) 2007, Sally Smith' - - -class TestRss091Feed(TestRss2Feed): - feed_type = feedgenerator.RssUserland091Feed - - -class TestAtomFeed(TestRss2Feed): - feed_type = feedgenerator.Atom1Feed - subtitle = TestRss2Feed.description - - -class ArticlesFeed(TestRss2Feed): - """ - A feed to test no link being defined. Articles have no get_absolute_url() - method, and item_link() is not defined. - """ - def items(self): - return Article.objects.all() - - -class TestEnclosureFeed(TestRss2Feed): - pass - - -class TemplateFeed(TestRss2Feed): - """ - A feed to test defining item titles and descriptions with templates. - """ - title_template = 'syndication/title.html' - description_template = 'syndication/description.html' - - # Defining a template overrides any item_title definition - def item_title(self): - return "Not in a template" - - -class NaiveDatesFeed(TestAtomFeed): - """ - A feed with naive (non-timezone-aware) dates. - """ - def item_pubdate(self, item): - return item.date - - -class TZAwareDatesFeed(TestAtomFeed): - """ - A feed with timezone-aware dates. - """ - def item_pubdate(self, item): - # Provide a weird offset so that the test can know it's getting this - # specific offset and not accidentally getting on from - # settings.TIME_ZONE. - return item.date.replace(tzinfo=tzinfo.FixedOffset(42)) - - -class TestFeedUrlFeed(TestAtomFeed): - feed_url = 'http://example.com/customfeedurl/' - - -class MyCustomAtom1Feed(feedgenerator.Atom1Feed): - """ - Test of a custom feed generator class. - """ - def root_attributes(self): - attrs = super(MyCustomAtom1Feed, self).root_attributes() - attrs[u'django'] = u'rocks' - return attrs - - def add_root_elements(self, handler): - super(MyCustomAtom1Feed, self).add_root_elements(handler) - handler.addQuickElement(u'spam', u'eggs') - - def item_attributes(self, item): - attrs = super(MyCustomAtom1Feed, self).item_attributes(item) - attrs[u'bacon'] = u'yum' - return attrs - - def add_item_elements(self, handler, item): - super(MyCustomAtom1Feed, self).add_item_elements(handler, item) - handler.addQuickElement(u'ministry', u'silly walks') - - -class TestCustomFeed(TestAtomFeed): - feed_type = MyCustomAtom1Feed - - -class DeprecatedComplexFeed(feeds.Feed): - def get_object(self, bits): - if len(bits) != 1: - raise ObjectDoesNotExist - return None - - -class DeprecatedRssFeed(feeds.Feed): - link = "/blog/" - title = 'My blog' - - def items(self): - return Entry.objects.all() - - def item_link(self, item): - return "/blog/%s/" % item.pk - diff --git a/parts/django/tests/regressiontests/syndication/fixtures/feeddata.json b/parts/django/tests/regressiontests/syndication/fixtures/feeddata.json deleted file mode 100644 index 4a5c022..0000000 --- a/parts/django/tests/regressiontests/syndication/fixtures/feeddata.json +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "model": "syndication.entry", - "pk": 1, - "fields": { - "title": "My first entry", - "date": "2008-01-01 12:30:00" - } - }, - { - "model": "syndication.entry", - "pk": 2, - "fields": { - "title": "My second entry", - "date": "2008-01-02 12:30:00" - } - }, - { - "model": "syndication.entry", - "pk": 3, - "fields": { - "title": "My third entry", - "date": "2008-01-02 13:30:00" - } - }, - { - "model": "syndication.entry", - "pk": 4, - "fields": { - "title": "A & B < C > D", - "date": "2008-01-03 13:30:00" - } - }, - { - "model": "syndication.article", - "pk": 1, - "fields": { - "title": "My first article", - "entry": "1" - } - } -] diff --git a/parts/django/tests/regressiontests/syndication/models.py b/parts/django/tests/regressiontests/syndication/models.py deleted file mode 100644 index 54230b9..0000000 --- a/parts/django/tests/regressiontests/syndication/models.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.db import models - -class Entry(models.Model): - title = models.CharField(max_length=200) - date = models.DateTimeField() - - class Meta: - ordering = ('date',) - - def __unicode__(self): - return self.title - - def get_absolute_url(self): - return "/blog/%s/" % self.pk - - -class Article(models.Model): - title = models.CharField(max_length=200) - entry = models.ForeignKey(Entry) - - def __unicode__(self): - return self.title - diff --git a/parts/django/tests/regressiontests/syndication/templates/syndication/description.html b/parts/django/tests/regressiontests/syndication/templates/syndication/description.html deleted file mode 100644 index 85ec82c..0000000 --- a/parts/django/tests/regressiontests/syndication/templates/syndication/description.html +++ /dev/null @@ -1 +0,0 @@ -Description in your templates: {{ obj }}
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/syndication/templates/syndication/title.html b/parts/django/tests/regressiontests/syndication/templates/syndication/title.html deleted file mode 100644 index eb17969..0000000 --- a/parts/django/tests/regressiontests/syndication/templates/syndication/title.html +++ /dev/null @@ -1 +0,0 @@ -Title in your templates: {{ obj }}
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/syndication/tests.py b/parts/django/tests/regressiontests/syndication/tests.py deleted file mode 100644 index 76a6c88..0000000 --- a/parts/django/tests/regressiontests/syndication/tests.py +++ /dev/null @@ -1,356 +0,0 @@ -import datetime -from django.contrib.syndication import feeds, views -from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase -from django.utils import tzinfo -from django.utils.feedgenerator import rfc2822_date, rfc3339_date -from models import Entry -from xml.dom import minidom - -try: - set -except NameError: - from sets import Set as set - -class FeedTestCase(TestCase): - fixtures = ['feeddata.json'] - - def assertChildNodes(self, elem, expected): - actual = set([n.nodeName for n in elem.childNodes]) - expected = set(expected) - self.assertEqual(actual, expected) - - def assertChildNodeContent(self, elem, expected): - for k, v in expected.items(): - self.assertEqual( - elem.getElementsByTagName(k)[0].firstChild.wholeText, v) - - def assertCategories(self, elem, expected): - self.assertEqual(set(i.firstChild.wholeText for i in elem.childNodes if i.nodeName == 'category'), set(expected)); - -###################################### -# Feed view -###################################### - -class SyndicationFeedTest(FeedTestCase): - """ - Tests for the high-level syndication feed framework. - """ - - def test_rss2_feed(self): - """ - Test the structure and content of feeds generated by Rss201rev2Feed. - """ - response = self.client.get('/syndication/rss2/') - doc = minidom.parseString(response.content) - - # Making sure there's only 1 `rss` element and that the correct - # RSS version was specified. - feed_elem = doc.getElementsByTagName('rss') - self.assertEqual(len(feed_elem), 1) - feed = feed_elem[0] - self.assertEqual(feed.getAttribute('version'), '2.0') - - # Making sure there's only one `channel` element w/in the - # `rss` element. - chan_elem = feed.getElementsByTagName('channel') - self.assertEqual(len(chan_elem), 1) - chan = chan_elem[0] - - # Find the last build date - d = Entry.objects.latest('date').date - ltz = tzinfo.LocalTimezone(d) - last_build_date = rfc2822_date(d.replace(tzinfo=ltz)) - - self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category']) - self.assertChildNodeContent(chan, { - 'title': 'My blog', - 'description': 'A more thorough description of my blog.', - 'link': 'http://example.com/blog/', - 'language': 'en', - 'lastBuildDate': last_build_date, - #'atom:link': '', - 'ttl': '600', - 'copyright': 'Copyright (c) 2007, Sally Smith', - }) - self.assertCategories(chan, ['python', 'django']); - - # Ensure the content of the channel is correct - self.assertChildNodeContent(chan, { - 'title': 'My blog', - 'link': 'http://example.com/blog/', - }) - - # Check feed_url is passed - self.assertEqual( - chan.getElementsByTagName('atom:link')[0].getAttribute('href'), - 'http://example.com/syndication/rss2/' - ) - - # Find the pubdate of the first feed item - d = Entry.objects.get(pk=1).date - ltz = tzinfo.LocalTimezone(d) - pub_date = rfc2822_date(d.replace(tzinfo=ltz)) - - items = chan.getElementsByTagName('item') - self.assertEqual(len(items), Entry.objects.count()) - self.assertChildNodeContent(items[0], { - 'title': 'My first entry', - 'description': 'Overridden description: My first entry', - 'link': 'http://example.com/blog/1/', - 'guid': 'http://example.com/blog/1/', - 'pubDate': pub_date, - 'author': 'test@example.com (Sally Smith)', - }) - self.assertCategories(items[0], ['python', 'testing']); - - for item in items: - self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author']) - - def test_rss091_feed(self): - """ - Test the structure and content of feeds generated by RssUserland091Feed. - """ - response = self.client.get('/syndication/rss091/') - doc = minidom.parseString(response.content) - - # Making sure there's only 1 `rss` element and that the correct - # RSS version was specified. - feed_elem = doc.getElementsByTagName('rss') - self.assertEqual(len(feed_elem), 1) - feed = feed_elem[0] - self.assertEqual(feed.getAttribute('version'), '0.91') - - # Making sure there's only one `channel` element w/in the - # `rss` element. - chan_elem = feed.getElementsByTagName('channel') - self.assertEqual(len(chan_elem), 1) - chan = chan_elem[0] - self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category']) - - # Ensure the content of the channel is correct - self.assertChildNodeContent(chan, { - 'title': 'My blog', - 'link': 'http://example.com/blog/', - }) - self.assertCategories(chan, ['python', 'django']) - - # Check feed_url is passed - self.assertEqual( - chan.getElementsByTagName('atom:link')[0].getAttribute('href'), - 'http://example.com/syndication/rss091/' - ) - - items = chan.getElementsByTagName('item') - self.assertEqual(len(items), Entry.objects.count()) - self.assertChildNodeContent(items[0], { - 'title': 'My first entry', - 'description': 'Overridden description: My first entry', - 'link': 'http://example.com/blog/1/', - }) - for item in items: - self.assertChildNodes(item, ['title', 'link', 'description']) - self.assertCategories(item, []) - - def test_atom_feed(self): - """ - Test the structure and content of feeds generated by Atom1Feed. - """ - response = self.client.get('/syndication/atom/') - feed = minidom.parseString(response.content).firstChild - - self.assertEqual(feed.nodeName, 'feed') - self.assertEqual(feed.getAttribute('xmlns'), 'http://www.w3.org/2005/Atom') - self.assertChildNodes(feed, ['title', 'subtitle', 'link', 'id', 'updated', 'entry', 'rights', 'category', 'author']) - for link in feed.getElementsByTagName('link'): - if link.getAttribute('rel') == 'self': - self.assertEqual(link.getAttribute('href'), 'http://example.com/syndication/atom/') - - entries = feed.getElementsByTagName('entry') - self.assertEqual(len(entries), Entry.objects.count()) - for entry in entries: - self.assertChildNodes(entry, ['title', 'link', 'id', 'summary', 'category', 'updated', 'rights', 'author']) - summary = entry.getElementsByTagName('summary')[0] - self.assertEqual(summary.getAttribute('type'), 'html') - - def test_custom_feed_generator(self): - response = self.client.get('/syndication/custom/') - feed = minidom.parseString(response.content).firstChild - - self.assertEqual(feed.nodeName, 'feed') - self.assertEqual(feed.getAttribute('django'), 'rocks') - self.assertChildNodes(feed, ['title', 'subtitle', 'link', 'id', 'updated', 'entry', 'spam', 'rights', 'category', 'author']) - - entries = feed.getElementsByTagName('entry') - self.assertEqual(len(entries), Entry.objects.count()) - for entry in entries: - self.assertEqual(entry.getAttribute('bacon'), 'yum') - self.assertChildNodes(entry, ['title', 'link', 'id', 'summary', 'ministry', 'rights', 'author', 'updated', 'category']) - summary = entry.getElementsByTagName('summary')[0] - self.assertEqual(summary.getAttribute('type'), 'html') - - def test_title_escaping(self): - """ - Tests that titles are escaped correctly in RSS feeds. - """ - response = self.client.get('/syndication/rss2/') - doc = minidom.parseString(response.content) - for item in doc.getElementsByTagName('item'): - link = item.getElementsByTagName('link')[0] - if link.firstChild.wholeText == 'http://example.com/blog/4/': - title = item.getElementsByTagName('title')[0] - self.assertEquals(title.firstChild.wholeText, u'A & B < C > D') - - def test_naive_datetime_conversion(self): - """ - Test that datetimes are correctly converted to the local time zone. - """ - # Naive date times passed in get converted to the local time zone, so - # check the recived zone offset against the local offset. - response = self.client.get('/syndication/naive-dates/') - doc = minidom.parseString(response.content) - updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText - - d = Entry.objects.latest('date').date - ltz = tzinfo.LocalTimezone(d) - latest = rfc3339_date(d.replace(tzinfo=ltz)) - - self.assertEqual(updated, latest) - - def test_aware_datetime_conversion(self): - """ - Test that datetimes with timezones don't get trodden on. - """ - response = self.client.get('/syndication/aware-dates/') - doc = minidom.parseString(response.content) - updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText - self.assertEqual(updated[-6:], '+00:42') - - def test_feed_url(self): - """ - Test that the feed_url can be overridden. - """ - response = self.client.get('/syndication/feedurl/') - doc = minidom.parseString(response.content) - for link in doc.getElementsByTagName('link'): - if link.getAttribute('rel') == 'self': - self.assertEqual(link.getAttribute('href'), 'http://example.com/customfeedurl/') - - def test_secure_urls(self): - """ - Test URLs are prefixed with https:// when feed is requested over HTTPS. - """ - response = self.client.get('/syndication/rss2/', **{ - 'wsgi.url_scheme': 'https', - }) - doc = minidom.parseString(response.content) - chan = doc.getElementsByTagName('channel')[0] - self.assertEqual( - chan.getElementsByTagName('link')[0].firstChild.wholeText[0:5], - 'https' - ) - atom_link = chan.getElementsByTagName('atom:link')[0] - self.assertEqual(atom_link.getAttribute('href')[0:5], 'https') - for link in doc.getElementsByTagName('link'): - if link.getAttribute('rel') == 'self': - self.assertEqual(link.getAttribute('href')[0:5], 'https') - - def test_item_link_error(self): - """ - Test that a ImproperlyConfigured is raised if no link could be found - for the item(s). - """ - self.assertRaises(ImproperlyConfigured, - self.client.get, - '/syndication/articles/') - - def test_template_feed(self): - """ - Test that the item title and description can be overridden with - templates. - """ - response = self.client.get('/syndication/template/') - doc = minidom.parseString(response.content) - feed = doc.getElementsByTagName('rss')[0] - chan = feed.getElementsByTagName('channel')[0] - items = chan.getElementsByTagName('item') - - self.assertChildNodeContent(items[0], { - 'title': 'Title in your templates: My first entry', - 'description': 'Description in your templates: My first entry', - 'link': 'http://example.com/blog/1/', - }) - - def test_add_domain(self): - """ - Test add_domain() prefixes domains onto the correct URLs. - """ - self.assertEqual( - views.add_domain('example.com', '/foo/?arg=value'), - 'http://example.com/foo/?arg=value' - ) - self.assertEqual( - views.add_domain('example.com', '/foo/?arg=value', True), - 'https://example.com/foo/?arg=value' - ) - self.assertEqual( - views.add_domain('example.com', 'http://djangoproject.com/doc/'), - 'http://djangoproject.com/doc/' - ) - self.assertEqual( - views.add_domain('example.com', 'https://djangoproject.com/doc/'), - 'https://djangoproject.com/doc/' - ) - self.assertEqual( - views.add_domain('example.com', 'mailto:uhoh@djangoproject.com'), - 'mailto:uhoh@djangoproject.com' - ) - - -###################################### -# Deprecated feeds -###################################### - -class DeprecatedSyndicationFeedTest(FeedTestCase): - """ - Tests for the deprecated API (feed() view and the feed_dict etc). - """ - - def test_empty_feed_dict(self): - """ - Test that an empty feed_dict raises a 404. - """ - response = self.client.get('/syndication/depr-feeds-empty/aware-dates/') - self.assertEquals(response.status_code, 404) - - def test_nonexistent_slug(self): - """ - Test that a non-existent slug raises a 404. - """ - response = self.client.get('/syndication/depr-feeds/foobar/') - self.assertEquals(response.status_code, 404) - - def test_rss_feed(self): - """ - A simple test for Rss201rev2Feed feeds generated by the deprecated - system. - """ - response = self.client.get('/syndication/depr-feeds/rss/') - doc = minidom.parseString(response.content) - feed = doc.getElementsByTagName('rss')[0] - self.assertEqual(feed.getAttribute('version'), '2.0') - - chan = feed.getElementsByTagName('channel')[0] - self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link']) - - items = chan.getElementsByTagName('item') - self.assertEqual(len(items), Entry.objects.count()) - - def test_complex_base_url(self): - """ - Tests that the base url for a complex feed doesn't raise a 500 - exception. - """ - response = self.client.get('/syndication/depr-feeds/complex/') - self.assertEquals(response.status_code, 404) - diff --git a/parts/django/tests/regressiontests/syndication/urls.py b/parts/django/tests/regressiontests/syndication/urls.py deleted file mode 100644 index 881fa48..0000000 --- a/parts/django/tests/regressiontests/syndication/urls.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.conf.urls.defaults import * - -import feeds - -feed_dict = { - 'complex': feeds.DeprecatedComplexFeed, - 'rss': feeds.DeprecatedRssFeed, -} - -urlpatterns = patterns('django.contrib.syndication.views', - (r'^complex/(?P<foo>.*)/$', feeds.ComplexFeed()), - (r'^rss2/$', feeds.TestRss2Feed()), - (r'^rss091/$', feeds.TestRss091Feed()), - (r'^atom/$', feeds.TestAtomFeed()), - (r'^custom/$', feeds.TestCustomFeed()), - (r'^naive-dates/$', feeds.NaiveDatesFeed()), - (r'^aware-dates/$', feeds.TZAwareDatesFeed()), - (r'^feedurl/$', feeds.TestFeedUrlFeed()), - (r'^articles/$', feeds.ArticlesFeed()), - (r'^template/$', feeds.TemplateFeed()), - - (r'^depr-feeds/(?P<url>.*)/$', 'feed', {'feed_dict': feed_dict}), - (r'^depr-feeds-empty/(?P<url>.*)/$', 'feed', {'feed_dict': None}), -) diff --git a/parts/django/tests/regressiontests/templates/__init__.py b/parts/django/tests/regressiontests/templates/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/templates/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/templates/context.py b/parts/django/tests/regressiontests/templates/context.py deleted file mode 100644 index 394de94..0000000 --- a/parts/django/tests/regressiontests/templates/context.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding: utf-8 -from unittest import TestCase - -from django.template import Context - - -class ContextTests(TestCase): - def test_context(self): - c = Context({"a": 1, "b": "xyzzy"}) - self.assertEqual(c["a"], 1) - self.assertEqual(c.push(), {}) - c["a"] = 2 - self.assertEqual(c["a"], 2) - self.assertEqual(c.get("a"), 2) - self.assertEqual(c.pop(), {"a": 2}) - self.assertEqual(c["a"], 1) - self.assertEqual(c.get("foo", 42), 42) diff --git a/parts/django/tests/regressiontests/templates/custom.py b/parts/django/tests/regressiontests/templates/custom.py deleted file mode 100644 index b346198..0000000 --- a/parts/django/tests/regressiontests/templates/custom.py +++ /dev/null @@ -1,12 +0,0 @@ -from unittest import TestCase - -from django import template - - -class CustomTests(TestCase): - def test_filter(self): - t = template.Template("{% load custom %}{{ string|trim:5 }}") - self.assertEqual( - t.render(template.Context({"string": "abcdefghijklmnopqrstuvwxyz"})), - u"abcde" - ) diff --git a/parts/django/tests/regressiontests/templates/eggs/tagsegg.egg b/parts/django/tests/regressiontests/templates/eggs/tagsegg.egg Binary files differdeleted file mode 100755 index 3941914..0000000 --- a/parts/django/tests/regressiontests/templates/eggs/tagsegg.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/templates/filters.py b/parts/django/tests/regressiontests/templates/filters.py deleted file mode 100644 index af34c58..0000000 --- a/parts/django/tests/regressiontests/templates/filters.py +++ /dev/null @@ -1,350 +0,0 @@ -# coding: utf-8 -""" -Tests for template filters (as opposed to template tags). - -The tests are hidden inside a function so that things like timestamps and -timezones are only evaluated at the moment of execution and will therefore be -consistent. -""" - -from datetime import date, datetime, timedelta - -from django.utils.tzinfo import LocalTimezone, FixedOffset -from django.utils.safestring import mark_safe - -# These two classes are used to test auto-escaping of __unicode__ output. -class UnsafeClass: - def __unicode__(self): - return u'you & me' - -class SafeClass: - def __unicode__(self): - return mark_safe(u'you > me') - -# RESULT SYNTAX -- -# 'template_name': ('template contents', 'context dict', -# 'expected string output' or Exception class) -def get_filter_tests(): - now = datetime.now() - now_tz = datetime.now(LocalTimezone(now)) - now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone - today = date.today() - - return { - # Default compare with datetime.now() - 'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1 minute'), - 'filter-timesince02' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(days=1, minutes = 1)}, '1 day'), - 'filter-timesince03' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(hours=1, minutes=25, seconds = 10)}, '1 hour, 25 minutes'), - - # Compare to a given parameter - 'filter-timesince04' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=1)}, '1 day'), - 'filter-timesince05' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2, minutes=1), 'b':now - timedelta(days=2)}, '1 minute'), - - # Check that timezone is respected - 'filter-timesince06' : ('{{ a|timesince:b }}', {'a':now_tz - timedelta(hours=8), 'b':now_tz}, '8 hours'), - - # Regression for #7443 - 'filter-timesince07': ('{{ earlier|timesince }}', { 'earlier': now - timedelta(days=7) }, '1 week'), - 'filter-timesince08': ('{{ earlier|timesince:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '1 week'), - 'filter-timesince09': ('{{ later|timesince }}', { 'later': now + timedelta(days=7) }, '0 minutes'), - 'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0 minutes'), - - # Ensures that differing timezones are calculated correctly - 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0 minutes'), - 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0 minutes'), - 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0 minutes'), - 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0 minutes'), - 'filter-timesince15' : ('{{ a|timesince:b }}', {'a': now, 'b': now_tz_i}, ''), - 'filter-timesince16' : ('{{ a|timesince:b }}', {'a': now_tz_i, 'b': now}, ''), - - # Regression for #9065 (two date objects). - 'filter-timesince17' : ('{{ a|timesince:b }}', {'a': today, 'b': today}, '0 minutes'), - 'filter-timesince18' : ('{{ a|timesince:b }}', {'a': today, 'b': today + timedelta(hours=24)}, '1 day'), - - # Default compare with datetime.now() - 'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'), - 'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1 day'), - 'filter-timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8 hours, 10 minutes'), - - # Compare to a given parameter - 'filter-timeuntil04' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=1), 'b':now - timedelta(days=2)}, '1 day'), - 'filter-timeuntil05' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=2, minutes=1)}, '1 minute'), - - # Regression for #7443 - 'filter-timeuntil06': ('{{ earlier|timeuntil }}', { 'earlier': now - timedelta(days=7) }, '0 minutes'), - 'filter-timeuntil07': ('{{ earlier|timeuntil:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '0 minutes'), - 'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now + timedelta(days=7, hours=1) }, '1 week'), - 'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1 week'), - - # Ensures that differing timezones are calculated correctly - 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0 minutes'), - 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0 minutes'), - - # Regression for #9065 (two date objects). - 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0 minutes'), - 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1 day'), - - 'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{ b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")}, ur"<a>\' <a>\'"), - 'filter-addslash02': ("{{ a|addslashes }} {{ b|addslashes }}", {"a": "<a>'", "b": mark_safe("<a>'")}, ur"<a>\' <a>\'"), - - 'filter-capfirst01': ("{% autoescape off %}{{ a|capfirst }} {{ b|capfirst }}{% endautoescape %}", {"a": "fred>", "b": mark_safe("fred>")}, u"Fred> Fred>"), - 'filter-capfirst02': ("{{ a|capfirst }} {{ b|capfirst }}", {"a": "fred>", "b": mark_safe("fred>")}, u"Fred> Fred>"), - - # Note that applying fix_ampsersands in autoescape mode leads to - # double escaping. - 'filter-fix_ampersands01': ("{% autoescape off %}{{ a|fix_ampersands }} {{ b|fix_ampersands }}{% endautoescape %}", {"a": "a&b", "b": mark_safe("a&b")}, u"a&b a&b"), - 'filter-fix_ampersands02': ("{{ a|fix_ampersands }} {{ b|fix_ampersands }}", {"a": "a&b", "b": mark_safe("a&b")}, u"a&amp;b a&b"), - - 'filter-floatformat01': ("{% autoescape off %}{{ a|floatformat }} {{ b|floatformat }}{% endautoescape %}", {"a": "1.42", "b": mark_safe("1.42")}, u"1.4 1.4"), - 'filter-floatformat02': ("{{ a|floatformat }} {{ b|floatformat }}", {"a": "1.42", "b": mark_safe("1.42")}, u"1.4 1.4"), - - # The contents of "linenumbers" is escaped according to the current - # autoescape setting. - 'filter-linenumbers01': ("{{ a|linenumbers }} {{ b|linenumbers }}", {"a": "one\n<two>\nthree", "b": mark_safe("one\n<two>\nthree")}, u"1. one\n2. <two>\n3. three 1. one\n2. <two>\n3. three"), - 'filter-linenumbers02': ("{% autoescape off %}{{ a|linenumbers }} {{ b|linenumbers }}{% endautoescape %}", {"a": "one\n<two>\nthree", "b": mark_safe("one\n<two>\nthree")}, u"1. one\n2. <two>\n3. three 1. one\n2. <two>\n3. three"), - - 'filter-lower01': ("{% autoescape off %}{{ a|lower }} {{ b|lower }}{% endautoescape %}", {"a": "Apple & banana", "b": mark_safe("Apple & banana")}, u"apple & banana apple & banana"), - 'filter-lower02': ("{{ a|lower }} {{ b|lower }}", {"a": "Apple & banana", "b": mark_safe("Apple & banana")}, u"apple & banana apple & banana"), - - # The make_list filter can destroy existing escaping, so the results are - # escaped. - 'filter-make_list01': ("{% autoescape off %}{{ a|make_list }}{% endautoescape %}", {"a": mark_safe("&")}, u"[u'&']"), - 'filter-make_list02': ("{{ a|make_list }}", {"a": mark_safe("&")}, u"[u'&']"), - 'filter-make_list03': ('{% autoescape off %}{{ a|make_list|stringformat:"s"|safe }}{% endautoescape %}', {"a": mark_safe("&")}, u"[u'&']"), - 'filter-make_list04': ('{{ a|make_list|stringformat:"s"|safe }}', {"a": mark_safe("&")}, u"[u'&']"), - - # Running slugify on a pre-escaped string leads to odd behaviour, - # but the result is still safe. - 'filter-slugify01': ("{% autoescape off %}{{ a|slugify }} {{ b|slugify }}{% endautoescape %}", {"a": "a & b", "b": mark_safe("a & b")}, u"a-b a-amp-b"), - 'filter-slugify02': ("{{ a|slugify }} {{ b|slugify }}", {"a": "a & b", "b": mark_safe("a & b")}, u"a-b a-amp-b"), - - # Notice that escaping is applied *after* any filters, so the string - # formatting here only needs to deal with pre-escaped characters. - 'filter-stringformat01': ('{% autoescape off %}.{{ a|stringformat:"5s" }}. .{{ b|stringformat:"5s" }}.{% endautoescape %}', - {"a": "a<b", "b": mark_safe("a<b")}, u". a<b. . a<b."), - 'filter-stringformat02': ('.{{ a|stringformat:"5s" }}. .{{ b|stringformat:"5s" }}.', {"a": "a<b", "b": mark_safe("a<b")}, - u". a<b. . a<b."), - - # Test the title filter - 'filter-title1' : ('{{ a|title }}', {'a' : 'JOE\'S CRAB SHACK'}, u'Joe's Crab Shack'), - 'filter-title2' : ('{{ a|title }}', {'a' : '555 WEST 53RD STREET'}, u'555 West 53rd Street'), - - 'filter-truncatewords01': ('{% autoescape off %}{{ a|truncatewords:"2" }} {{ b|truncatewords:"2"}}{% endautoescape %}', - {"a": "alpha & bravo", "b": mark_safe("alpha & bravo")}, u"alpha & ... alpha & ..."), - 'filter-truncatewords02': ('{{ a|truncatewords:"2" }} {{ b|truncatewords:"2"}}', - {"a": "alpha & bravo", "b": mark_safe("alpha & bravo")}, u"alpha & ... alpha & ..."), - - # The "upper" filter messes up entities (which are case-sensitive), - # so it's not safe for non-escaping purposes. - 'filter-upper01': ('{% autoescape off %}{{ a|upper }} {{ b|upper }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A & B"), - 'filter-upper02': ('{{ a|upper }} {{ b|upper }}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A &AMP; B"), - - 'filter-urlize01': ('{% autoescape off %}{{ a|urlize }} {{ b|urlize }}{% endautoescape %}', {"a": "http://example.com/?x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/?x=&y=" rel="nofollow">http://example.com/?x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'), - 'filter-urlize02': ('{{ a|urlize }} {{ b|urlize }}', {"a": "http://example.com/?x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/?x=&y=" rel="nofollow">http://example.com/?x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'), - 'filter-urlize03': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": mark_safe("a & b")}, 'a & b'), - 'filter-urlize04': ('{{ a|urlize }}', {"a": mark_safe("a & b")}, 'a & b'), - - # This will lead to a nonsense result, but at least it won't be - # exploitable for XSS purposes when auto-escaping is on. - 'filter-urlize05': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": "<script>alert('foo')</script>"}, "<script>alert('foo')</script>"), - 'filter-urlize06': ('{{ a|urlize }}', {"a": "<script>alert('foo')</script>"}, '<script>alert('foo')</script>'), - - # mailto: testing for urlize - 'filter-urlize07': ('{{ a|urlize }}', {"a": "Email me at me@example.com"}, 'Email me at <a href="mailto:me@example.com">me@example.com</a>'), - 'filter-urlize08': ('{{ a|urlize }}', {"a": "Email me at <me@example.com>"}, 'Email me at <<a href="mailto:me@example.com">me@example.com</a>>'), - - 'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'), - 'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'), - - 'filter-wordcount01': ('{% autoescape off %}{{ a|wordcount }} {{ b|wordcount }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"), - 'filter-wordcount02': ('{{ a|wordcount }} {{ b|wordcount }}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"), - - 'filter-wordwrap01': ('{% autoescape off %}{{ a|wordwrap:"3" }} {{ b|wordwrap:"3" }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, u"a &\nb a &\nb"), - 'filter-wordwrap02': ('{{ a|wordwrap:"3" }} {{ b|wordwrap:"3" }}', {"a": "a & b", "b": mark_safe("a & b")}, u"a &\nb a &\nb"), - - 'filter-ljust01': ('{% autoescape off %}.{{ a|ljust:"5" }}. .{{ b|ljust:"5" }}.{% endautoescape %}', {"a": "a&b", "b": mark_safe("a&b")}, u".a&b . .a&b ."), - 'filter-ljust02': ('.{{ a|ljust:"5" }}. .{{ b|ljust:"5" }}.', {"a": "a&b", "b": mark_safe("a&b")}, u".a&b . .a&b ."), - - 'filter-rjust01': ('{% autoescape off %}.{{ a|rjust:"5" }}. .{{ b|rjust:"5" }}.{% endautoescape %}', {"a": "a&b", "b": mark_safe("a&b")}, u". a&b. . a&b."), - 'filter-rjust02': ('.{{ a|rjust:"5" }}. .{{ b|rjust:"5" }}.', {"a": "a&b", "b": mark_safe("a&b")}, u". a&b. . a&b."), - - 'filter-center01': ('{% autoescape off %}.{{ a|center:"5" }}. .{{ b|center:"5" }}.{% endautoescape %}', {"a": "a&b", "b": mark_safe("a&b")}, u". a&b . . a&b ."), - 'filter-center02': ('.{{ a|center:"5" }}. .{{ b|center:"5" }}.', {"a": "a&b", "b": mark_safe("a&b")}, u". a&b . . a&b ."), - - 'filter-cut01': ('{% autoescape off %}{{ a|cut:"x" }} {{ b|cut:"x" }}{% endautoescape %}', {"a": "x&y", "b": mark_safe("x&y")}, u"&y &y"), - 'filter-cut02': ('{{ a|cut:"x" }} {{ b|cut:"x" }}', {"a": "x&y", "b": mark_safe("x&y")}, u"&y &y"), - 'filter-cut03': ('{% autoescape off %}{{ a|cut:"&" }} {{ b|cut:"&" }}{% endautoescape %}', {"a": "x&y", "b": mark_safe("x&y")}, u"xy xamp;y"), - 'filter-cut04': ('{{ a|cut:"&" }} {{ b|cut:"&" }}', {"a": "x&y", "b": mark_safe("x&y")}, u"xy xamp;y"), - # Passing ';' to cut can break existing HTML entities, so those strings - # are auto-escaped. - 'filter-cut05': ('{% autoescape off %}{{ a|cut:";" }} {{ b|cut:";" }}{% endautoescape %}', {"a": "x&y", "b": mark_safe("x&y")}, u"x&y x&y"), - 'filter-cut06': ('{{ a|cut:";" }} {{ b|cut:";" }}', {"a": "x&y", "b": mark_safe("x&y")}, u"x&y x&ampy"), - - # The "escape" filter works the same whether autoescape is on or off, - # but it has no effect on strings already marked as safe. - 'filter-escape01': ('{{ a|escape }} {{ b|escape }}', {"a": "x&y", "b": mark_safe("x&y")}, u"x&y x&y"), - 'filter-escape02': ('{% autoescape off %}{{ a|escape }} {{ b|escape }}{% endautoescape %}', {"a": "x&y", "b": mark_safe("x&y")}, "x&y x&y"), - - # It is only applied once, regardless of the number of times it - # appears in a chain. - 'filter-escape03': ('{% autoescape off %}{{ a|escape|escape }}{% endautoescape %}', {"a": "x&y"}, u"x&y"), - 'filter-escape04': ('{{ a|escape|escape }}', {"a": "x&y"}, u"x&y"), - - # Force_escape is applied immediately. It can be used to provide - # double-escaping, for example. - 'filter-force-escape01': ('{% autoescape off %}{{ a|force_escape }}{% endautoescape %}', {"a": "x&y"}, u"x&y"), - 'filter-force-escape02': ('{{ a|force_escape }}', {"a": "x&y"}, u"x&y"), - 'filter-force-escape03': ('{% autoescape off %}{{ a|force_escape|force_escape }}{% endautoescape %}', {"a": "x&y"}, u"x&amp;y"), - 'filter-force-escape04': ('{{ a|force_escape|force_escape }}', {"a": "x&y"}, u"x&amp;y"), - - # Because the result of force_escape is "safe", an additional - # escape filter has no effect. - 'filter-force-escape05': ('{% autoescape off %}{{ a|force_escape|escape }}{% endautoescape %}', {"a": "x&y"}, u"x&y"), - 'filter-force-escape06': ('{{ a|force_escape|escape }}', {"a": "x&y"}, u"x&y"), - 'filter-force-escape07': ('{% autoescape off %}{{ a|escape|force_escape }}{% endautoescape %}', {"a": "x&y"}, u"x&y"), - 'filter-force-escape08': ('{{ a|escape|force_escape }}', {"a": "x&y"}, u"x&y"), - - # The contents in "linebreaks" and "linebreaksbr" are escaped - # according to the current autoescape setting. - 'filter-linebreaks01': ('{{ a|linebreaks }} {{ b|linebreaks }}', {"a": "x&\ny", "b": mark_safe("x&\ny")}, u"<p>x&<br />y</p> <p>x&<br />y</p>"), - 'filter-linebreaks02': ('{% autoescape off %}{{ a|linebreaks }} {{ b|linebreaks }}{% endautoescape %}', {"a": "x&\ny", "b": mark_safe("x&\ny")}, u"<p>x&<br />y</p> <p>x&<br />y</p>"), - - 'filter-linebreaksbr01': ('{{ a|linebreaksbr }} {{ b|linebreaksbr }}', {"a": "x&\ny", "b": mark_safe("x&\ny")}, u"x&<br />y x&<br />y"), - 'filter-linebreaksbr02': ('{% autoescape off %}{{ a|linebreaksbr }} {{ b|linebreaksbr }}{% endautoescape %}', {"a": "x&\ny", "b": mark_safe("x&\ny")}, u"x&<br />y x&<br />y"), - - 'filter-safe01': ("{{ a }} -- {{ a|safe }}", {"a": u"<b>hello</b>"}, "<b>hello</b> -- <b>hello</b>"), - 'filter-safe02': ("{% autoescape off %}{{ a }} -- {{ a|safe }}{% endautoescape %}", {"a": "<b>hello</b>"}, u"<b>hello</b> -- <b>hello</b>"), - - 'filter-safeseq01': ('{{ a|join:", " }} -- {{ a|safeseq|join:", " }}', {"a": ["&", "<"]}, "&, < -- &, <"), - 'filter-safeseq02': ('{% autoescape off %}{{ a|join:", " }} -- {{ a|safeseq|join:", " }}{% endautoescape %}', {"a": ["&", "<"]}, "&, < -- &, <"), - - 'filter-removetags01': ('{{ a|removetags:"a b" }} {{ b|removetags:"a b" }}', {"a": "<a>x</a> <p><b>y</b></p>", "b": mark_safe("<a>x</a> <p><b>y</b></p>")}, u"x <p>y</p> x <p>y</p>"), - 'filter-removetags02': ('{% autoescape off %}{{ a|removetags:"a b" }} {{ b|removetags:"a b" }}{% endautoescape %}', {"a": "<a>x</a> <p><b>y</b></p>", "b": mark_safe("<a>x</a> <p><b>y</b></p>")}, u"x <p>y</p> x <p>y</p>"), - - 'filter-striptags01': ('{{ a|striptags }} {{ b|striptags }}', {"a": "<a>x</a> <p><b>y</b></p>", "b": mark_safe("<a>x</a> <p><b>y</b></p>")}, "x y x y"), - 'filter-striptags02': ('{% autoescape off %}{{ a|striptags }} {{ b|striptags }}{% endautoescape %}', {"a": "<a>x</a> <p><b>y</b></p>", "b": mark_safe("<a>x</a> <p><b>y</b></p>")}, "x y x y"), - - 'filter-first01': ('{{ a|first }} {{ b|first }}', {"a": ["a&b", "x"], "b": [mark_safe("a&b"), "x"]}, "a&b a&b"), - 'filter-first02': ('{% autoescape off %}{{ a|first }} {{ b|first }}{% endautoescape %}', {"a": ["a&b", "x"], "b": [mark_safe("a&b"), "x"]}, "a&b a&b"), - - 'filter-last01': ('{{ a|last }} {{ b|last }}', {"a": ["x", "a&b"], "b": ["x", mark_safe("a&b")]}, "a&b a&b"), - 'filter-last02': ('{% autoescape off %}{{ a|last }} {{ b|last }}{% endautoescape %}', {"a": ["x", "a&b"], "b": ["x", mark_safe("a&b")]}, "a&b a&b"), - - 'filter-random01': ('{{ a|random }} {{ b|random }}', {"a": ["a&b", "a&b"], "b": [mark_safe("a&b"), mark_safe("a&b")]}, "a&b a&b"), - 'filter-random02': ('{% autoescape off %}{{ a|random }} {{ b|random }}{% endautoescape %}', {"a": ["a&b", "a&b"], "b": [mark_safe("a&b"), mark_safe("a&b")]}, "a&b a&b"), - - 'filter-slice01': ('{{ a|slice:"1:3" }} {{ b|slice:"1:3" }}', {"a": "a&b", "b": mark_safe("a&b")}, "&b &b"), - 'filter-slice02': ('{% autoescape off %}{{ a|slice:"1:3" }} {{ b|slice:"1:3" }}{% endautoescape %}', {"a": "a&b", "b": mark_safe("a&b")}, "&b &b"), - - 'filter-unordered_list01': ('{{ a|unordered_list }}', {"a": ["x>", [["<y", []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"), - 'filter-unordered_list02': ('{% autoescape off %}{{ a|unordered_list }}{% endautoescape %}', {"a": ["x>", [["<y", []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"), - 'filter-unordered_list03': ('{{ a|unordered_list }}', {"a": ["x>", [[mark_safe("<y"), []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"), - 'filter-unordered_list04': ('{% autoescape off %}{{ a|unordered_list }}{% endautoescape %}', {"a": ["x>", [[mark_safe("<y"), []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"), - 'filter-unordered_list05': ('{% autoescape off %}{{ a|unordered_list }}{% endautoescape %}', {"a": ["x>", [["<y", []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"), - - # Literal string arguments to the default filter are always treated as - # safe strings, regardless of the auto-escaping state. - # - # Note: we have to use {"a": ""} here, otherwise the invalid template - # variable string interferes with the test result. - 'filter-default01': ('{{ a|default:"x<" }}', {"a": ""}, "x<"), - 'filter-default02': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": ""}, "x<"), - 'filter-default03': ('{{ a|default:"x<" }}', {"a": mark_safe("x>")}, "x>"), - 'filter-default04': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": mark_safe("x>")}, "x>"), - - 'filter-default_if_none01': ('{{ a|default:"x<" }}', {"a": None}, "x<"), - 'filter-default_if_none02': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": None}, "x<"), - - 'filter-phone2numeric01': ('{{ a|phone2numeric }} {{ b|phone2numeric }}', {"a": "<1-800-call-me>", "b": mark_safe("<1-800-call-me>") }, "<1-800-2255-63> <1-800-2255-63>"), - 'filter-phone2numeric02': ('{% autoescape off %}{{ a|phone2numeric }} {{ b|phone2numeric }}{% endautoescape %}', {"a": "<1-800-call-me>", "b": mark_safe("<1-800-call-me>") }, "<1-800-2255-63> <1-800-2255-63>"), - 'filter-phone2numeric03': ('{{ a|phone2numeric }}', {"a": "How razorback-jumping frogs can level six piqued gymnasts!"}, "469 729672225-5867464 37647 226 53835 749 747833 49662787!"), - - # Ensure iriencode keeps safe strings: - 'filter-iriencode01': ('{{ url|iriencode }}', {'url': '?test=1&me=2'}, '?test=1&me=2'), - 'filter-iriencode02': ('{% autoescape off %}{{ url|iriencode }}{% endautoescape %}', {'url': '?test=1&me=2'}, '?test=1&me=2'), - 'filter-iriencode03': ('{{ url|iriencode }}', {'url': mark_safe('?test=1&me=2')}, '?test=1&me=2'), - 'filter-iriencode04': ('{% autoescape off %}{{ url|iriencode }}{% endautoescape %}', {'url': mark_safe('?test=1&me=2')}, '?test=1&me=2'), - - # Chaining a bunch of safeness-preserving filters should not alter - # the safe status either way. - 'chaining01': ('{{ a|capfirst|center:"7" }}.{{ b|capfirst|center:"7" }}', {"a": "a < b", "b": mark_safe("a < b")}, " A < b . A < b "), - 'chaining02': ('{% autoescape off %}{{ a|capfirst|center:"7" }}.{{ b|capfirst|center:"7" }}{% endautoescape %}', {"a": "a < b", "b": mark_safe("a < b")}, " A < b . A < b "), - - # Using a filter that forces a string back to unsafe: - 'chaining03': ('{{ a|cut:"b"|capfirst }}.{{ b|cut:"b"|capfirst }}', {"a": "a < b", "b": mark_safe("a < b")}, "A < .A < "), - 'chaining04': ('{% autoescape off %}{{ a|cut:"b"|capfirst }}.{{ b|cut:"b"|capfirst }}{% endautoescape %}', {"a": "a < b", "b": mark_safe("a < b")}, "A < .A < "), - - # Using a filter that forces safeness does not lead to double-escaping - 'chaining05': ('{{ a|escape|capfirst }}', {"a": "a < b"}, "A < b"), - 'chaining06': ('{% autoescape off %}{{ a|escape|capfirst }}{% endautoescape %}', {"a": "a < b"}, "A < b"), - - # Force to safe, then back (also showing why using force_escape too - # early in a chain can lead to unexpected results). - 'chaining07': ('{{ a|force_escape|cut:";" }}', {"a": "a < b"}, "a &lt b"), - 'chaining08': ('{% autoescape off %}{{ a|force_escape|cut:";" }}{% endautoescape %}', {"a": "a < b"}, "a < b"), - 'chaining09': ('{{ a|cut:";"|force_escape }}', {"a": "a < b"}, "a < b"), - 'chaining10': ('{% autoescape off %}{{ a|cut:";"|force_escape }}{% endautoescape %}', {"a": "a < b"}, "a < b"), - 'chaining11': ('{{ a|cut:"b"|safe }}', {"a": "a < b"}, "a < "), - 'chaining12': ('{% autoescape off %}{{ a|cut:"b"|safe }}{% endautoescape %}', {"a": "a < b"}, "a < "), - 'chaining13': ('{{ a|safe|force_escape }}', {"a": "a < b"}, "a < b"), - 'chaining14': ('{% autoescape off %}{{ a|safe|force_escape }}{% endautoescape %}', {"a": "a < b"}, "a < b"), - - # Filters decorated with stringfilter still respect is_safe. - 'autoescape-stringfilter01': (r'{{ unsafe|capfirst }}', {'unsafe': UnsafeClass()}, 'You & me'), - 'autoescape-stringfilter02': (r'{% autoescape off %}{{ unsafe|capfirst }}{% endautoescape %}', {'unsafe': UnsafeClass()}, 'You & me'), - 'autoescape-stringfilter03': (r'{{ safe|capfirst }}', {'safe': SafeClass()}, 'You > me'), - 'autoescape-stringfilter04': (r'{% autoescape off %}{{ safe|capfirst }}{% endautoescape %}', {'safe': SafeClass()}, 'You > me'), - - 'escapejs01': (r'{{ a|escapejs }}', {'a': 'testing\r\njavascript \'string" <b>escaping</b>'}, 'testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E'), - 'escapejs02': (r'{% autoescape off %}{{ a|escapejs }}{% endautoescape %}', {'a': 'testing\r\njavascript \'string" <b>escaping</b>'}, 'testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E'), - - - # length filter. - 'length01': ('{{ list|length }}', {'list': ['4', None, True, {}]}, '4'), - 'length02': ('{{ list|length }}', {'list': []}, '0'), - 'length03': ('{{ string|length }}', {'string': ''}, '0'), - 'length04': ('{{ string|length }}', {'string': 'django'}, '6'), - # Invalid uses that should fail silently. - 'length05': ('{{ int|length }}', {'int': 7}, ''), - 'length06': ('{{ None|length }}', {'None': None}, ''), - - # length_is filter. - 'length_is01': ('{% if some_list|length_is:"4" %}Four{% endif %}', {'some_list': ['4', None, True, {}]}, 'Four'), - 'length_is02': ('{% if some_list|length_is:"4" %}Four{% else %}Not Four{% endif %}', {'some_list': ['4', None, True, {}, 17]}, 'Not Four'), - 'length_is03': ('{% if mystring|length_is:"4" %}Four{% endif %}', {'mystring': 'word'}, 'Four'), - 'length_is04': ('{% if mystring|length_is:"4" %}Four{% else %}Not Four{% endif %}', {'mystring': 'Python'}, 'Not Four'), - 'length_is05': ('{% if mystring|length_is:"4" %}Four{% else %}Not Four{% endif %}', {'mystring': ''}, 'Not Four'), - 'length_is06': ('{% with var|length as my_length %}{{ my_length }}{% endwith %}', {'var': 'django'}, '6'), - # Boolean return value from length_is should not be coerced to a string - 'length_is07': (r'{% if "X"|length_is:0 %}Length is 0{% else %}Length not 0{% endif %}', {}, 'Length not 0'), - 'length_is08': (r'{% if "X"|length_is:1 %}Length is 1{% else %}Length not 1{% endif %}', {}, 'Length is 1'), - # Invalid uses that should fail silently. - 'length_is09': ('{{ var|length_is:"fish" }}', {'var': 'django'}, ''), - 'length_is10': ('{{ int|length_is:"1" }}', {'int': 7}, ''), - 'length_is11': ('{{ none|length_is:"1" }}', {'none': None}, ''), - - 'join01': (r'{{ a|join:", " }}', {'a': ['alpha', 'beta & me']}, 'alpha, beta & me'), - 'join02': (r'{% autoescape off %}{{ a|join:", " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha, beta & me'), - 'join03': (r'{{ a|join:" & " }}', {'a': ['alpha', 'beta & me']}, 'alpha & beta & me'), - 'join04': (r'{% autoescape off %}{{ a|join:" & " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha & beta & me'), - - # Test that joining with unsafe joiners don't result in unsafe strings (#11377) - 'join05': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': ' & '}, 'alpha & beta & me'), - 'join06': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta & me'), - 'join07': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': ' & ' }, 'alpha & beta & me'), - 'join08': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta & me'), - - 'date01': (r'{{ d|date:"m" }}', {'d': datetime(2008, 1, 1)}, '01'), - 'date02': (r'{{ d|date }}', {'d': datetime(2008, 1, 1)}, 'Jan. 1, 2008'), - #Ticket 9520: Make sure |date doesn't blow up on non-dates - 'date03': (r'{{ d|date:"m" }}', {'d': 'fail_string'}, ''), - - # Tests for #11687 - 'add01': (r'{{ i|add:"5" }}', {'i': 2000}, '2005'), - 'add02': (r'{{ i|add:"napis" }}', {'i': 2000}, '2000'), - 'add03': (r'{{ i|add:16 }}', {'i': 'not_an_int'}, 'not_an_int'), - 'add04': (r'{{ i|add:"16" }}', {'i': 'not_an_int'}, 'not_an_int16'), - 'add05': (r'{{ l1|add:l2 }}', {'l1': [1, 2], 'l2': [3, 4]}, '[1, 2, 3, 4]'), - 'add06': (r'{{ t1|add:t2 }}', {'t1': (3, 4), 't2': (1, 2)}, '(3, 4, 1, 2)'), - 'add07': (r'{{ d|add:t }}', {'d': date(2000, 1, 1), 't': timedelta(10)}, 'Jan. 11, 2000'), - } diff --git a/parts/django/tests/regressiontests/templates/loaders.py b/parts/django/tests/regressiontests/templates/loaders.py deleted file mode 100644 index 47cd18a..0000000 --- a/parts/django/tests/regressiontests/templates/loaders.py +++ /dev/null @@ -1,150 +0,0 @@ -""" -Test cases for the template loaders - -Note: This test requires setuptools! -""" - -from django.conf import settings - -if __name__ == '__main__': - settings.configure() - -import unittest -import sys -import pkg_resources -import imp -import StringIO -import os.path -import warnings - -from django.template import TemplateDoesNotExist, Context -from django.template.loaders.eggs import load_template_source as lts_egg -from django.template.loaders.eggs import Loader as EggLoader -from django.template import loader -from django.test.utils import get_warnings_state, restore_warnings_state - -# Mock classes and objects for pkg_resources functions. -class MockProvider(pkg_resources.NullProvider): - def __init__(self, module): - pkg_resources.NullProvider.__init__(self, module) - self.module = module - - def _has(self, path): - return path in self.module._resources - - def _isdir(self,path): - return False - - def get_resource_stream(self, manager, resource_name): - return self.module._resources[resource_name] - - def _get(self, path): - return self.module._resources[path].read() - -class MockLoader(object): - pass - -def create_egg(name, resources): - """ - Creates a mock egg with a list of resources. - - name: The name of the module. - resources: A dictionary of resources. Keys are the names and values the data. - """ - egg = imp.new_module(name) - egg.__loader__ = MockLoader() - egg._resources = resources - sys.modules[name] = egg - -class DeprecatedEggLoaderTest(unittest.TestCase): - "Test the deprecated load_template_source interface to the egg loader" - def setUp(self): - pkg_resources._provider_factories[MockLoader] = MockProvider - - self.empty_egg = create_egg("egg_empty", {}) - self.egg_1 = create_egg("egg_1", { - os.path.normcase('templates/y.html') : StringIO.StringIO("y"), - os.path.normcase('templates/x.txt') : StringIO.StringIO("x"), - }) - self._old_installed_apps = settings.INSTALLED_APPS - settings.INSTALLED_APPS = [] - self._warnings_state = get_warnings_state() - warnings.simplefilter("ignore", PendingDeprecationWarning) - - def tearDown(self): - settings.INSTALLED_APPS = self._old_installed_apps - restore_warnings_state(self._warnings_state) - - def test_existing(self): - "A template can be loaded from an egg" - settings.INSTALLED_APPS = ['egg_1'] - contents, template_name = lts_egg("y.html") - self.assertEqual(contents, "y") - self.assertEqual(template_name, "egg:egg_1:templates/y.html") - - -class EggLoaderTest(unittest.TestCase): - def setUp(self): - pkg_resources._provider_factories[MockLoader] = MockProvider - - self.empty_egg = create_egg("egg_empty", {}) - self.egg_1 = create_egg("egg_1", { - os.path.normcase('templates/y.html') : StringIO.StringIO("y"), - os.path.normcase('templates/x.txt') : StringIO.StringIO("x"), - }) - self._old_installed_apps = settings.INSTALLED_APPS - settings.INSTALLED_APPS = [] - - def tearDown(self): - settings.INSTALLED_APPS = self._old_installed_apps - - def test_empty(self): - "Loading any template on an empty egg should fail" - settings.INSTALLED_APPS = ['egg_empty'] - egg_loader = EggLoader() - self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html") - - def test_non_existing(self): - "Template loading fails if the template is not in the egg" - settings.INSTALLED_APPS = ['egg_1'] - egg_loader = EggLoader() - self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html") - - def test_existing(self): - "A template can be loaded from an egg" - settings.INSTALLED_APPS = ['egg_1'] - egg_loader = EggLoader() - contents, template_name = egg_loader.load_template_source("y.html") - self.assertEqual(contents, "y") - self.assertEqual(template_name, "egg:egg_1:templates/y.html") - - def test_not_installed(self): - "Loading an existent template from an egg not included in INSTALLED_APPS should fail" - settings.INSTALLED_APPS = [] - egg_loader = EggLoader() - self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "y.html") - -class CachedLoader(unittest.TestCase): - def setUp(self): - self.old_TEMPLATE_LOADERS = settings.TEMPLATE_LOADERS - settings.TEMPLATE_LOADERS = ( - ('django.template.loaders.cached.Loader', ( - 'django.template.loaders.filesystem.Loader', - ) - ), - ) - def tearDown(self): - settings.TEMPLATE_LOADERS = self.old_TEMPLATE_LOADERS - - def test_templatedir_caching(self): - "Check that the template directories form part of the template cache key. Refs #13573" - # Retrive a template specifying a template directory to check - t1, name = loader.find_template('test.html', (os.path.join(os.path.dirname(__file__), 'templates', 'first'),)) - # Now retrieve the same template name, but from a different directory - t2, name = loader.find_template('test.html', (os.path.join(os.path.dirname(__file__), 'templates', 'second'),)) - - # The two templates should not have the same content - self.assertNotEqual(t1.render(Context({})), t2.render(Context({}))) - -if __name__ == "__main__": - unittest.main() diff --git a/parts/django/tests/regressiontests/templates/models.py b/parts/django/tests/regressiontests/templates/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/templates/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/templates/nodelist.py b/parts/django/tests/regressiontests/templates/nodelist.py deleted file mode 100644 index 89fac97..0000000 --- a/parts/django/tests/regressiontests/templates/nodelist.py +++ /dev/null @@ -1,30 +0,0 @@ -from unittest import TestCase -from django.template.loader import get_template_from_string -from django.template import VariableNode - - -class NodelistTest(TestCase): - - def test_for(self): - source = '{% for i in 1 %}{{ a }}{% endfor %}' - template = get_template_from_string(source) - vars = template.nodelist.get_nodes_by_type(VariableNode) - self.assertEqual(len(vars), 1) - - def test_if(self): - source = '{% if x %}{{ a }}{% endif %}' - template = get_template_from_string(source) - vars = template.nodelist.get_nodes_by_type(VariableNode) - self.assertEqual(len(vars), 1) - - def test_ifequal(self): - source = '{% ifequal x y %}{{ a }}{% endifequal %}' - template = get_template_from_string(source) - vars = template.nodelist.get_nodes_by_type(VariableNode) - self.assertEqual(len(vars), 1) - - def test_ifchanged(self): - source = '{% ifchanged x %}{{ a }}{% endifchanged %}' - template = get_template_from_string(source) - vars = template.nodelist.get_nodes_by_type(VariableNode) - self.assertEqual(len(vars), 1) diff --git a/parts/django/tests/regressiontests/templates/parser.py b/parts/django/tests/regressiontests/templates/parser.py deleted file mode 100644 index 93e8118..0000000 --- a/parts/django/tests/regressiontests/templates/parser.py +++ /dev/null @@ -1,84 +0,0 @@ -""" -Testing some internals of the template processing. These are *not* examples to be copied in user code. -""" -from unittest import TestCase - -from django.template import (TokenParser, FilterExpression, Parser, Variable, - TemplateSyntaxError) - - -class ParserTests(TestCase): - def test_token_parsing(self): - # Tests for TokenParser behavior in the face of quoted strings with - # spaces. - - p = TokenParser("tag thevar|filter sometag") - self.assertEqual(p.tagname, "tag") - self.assertEqual(p.value(), "thevar|filter") - self.assertTrue(p.more()) - self.assertEqual(p.tag(), "sometag") - self.assertFalse(p.more()) - - p = TokenParser('tag "a value"|filter sometag') - self.assertEqual(p.tagname, "tag") - self.assertEqual(p.value(), '"a value"|filter') - self.assertTrue(p.more()) - self.assertEqual(p.tag(), "sometag") - self.assertFalse(p.more()) - - p = TokenParser("tag 'a value'|filter sometag") - self.assertEqual(p.tagname, "tag") - self.assertEqual(p.value(), "'a value'|filter") - self.assertTrue(p.more()) - self.assertEqual(p.tag(), "sometag") - self.assertFalse(p.more()) - - def test_filter_parsing(self): - c = {"article": {"section": u"News"}} - p = Parser("") - - def fe_test(s, val): - self.assertEqual(FilterExpression(s, p).resolve(c), val) - - fe_test("article.section", u"News") - fe_test("article.section|upper", u"NEWS") - fe_test(u'"News"', u"News") - fe_test(u"'News'", u"News") - fe_test(ur'"Some \"Good\" News"', u'Some "Good" News') - fe_test(ur'"Some \"Good\" News"', u'Some "Good" News') - fe_test(ur"'Some \'Bad\' News'", u"Some 'Bad' News") - - fe = FilterExpression(ur'"Some \"Good\" News"', p) - self.assertEqual(fe.filters, []) - self.assertEqual(fe.var, u'Some "Good" News') - - # Filtered variables should reject access of attributes beginning with - # underscores. - self.assertRaises(TemplateSyntaxError, - FilterExpression, "article._hidden|upper", p - ) - - def test_variable_parsing(self): - c = {"article": {"section": u"News"}} - self.assertEqual(Variable("article.section").resolve(c), "News") - self.assertEqual(Variable(u'"News"').resolve(c), "News") - self.assertEqual(Variable(u"'News'").resolve(c), "News") - - # Translated strings are handled correctly. - self.assertEqual(Variable("_(article.section)").resolve(c), "News") - self.assertEqual(Variable('_("Good News")').resolve(c), "Good News") - self.assertEqual(Variable("_('Better News')").resolve(c), "Better News") - - # Escaped quotes work correctly as well. - self.assertEqual( - Variable(ur'"Some \"Good\" News"').resolve(c), 'Some "Good" News' - ) - self.assertEqual( - Variable(ur"'Some \'Better\' News'").resolve(c), "Some 'Better' News" - ) - - # Variables should reject access of attributes beginning with - # underscores. - self.assertRaises(TemplateSyntaxError, - Variable, "article._hidden" - ) diff --git a/parts/django/tests/regressiontests/templates/smartif.py b/parts/django/tests/regressiontests/templates/smartif.py deleted file mode 100644 index 5e5d770..0000000 --- a/parts/django/tests/regressiontests/templates/smartif.py +++ /dev/null @@ -1,53 +0,0 @@ -import unittest -from django.template.smartif import IfParser, Literal - -class SmartIfTests(unittest.TestCase): - - def assertCalcEqual(self, expected, tokens): - self.assertEqual(expected, IfParser(tokens).parse().eval({})) - - # We only test things here that are difficult to test elsewhere - # Many other tests are found in the main tests for builtin template tags - # Test parsing via the printed parse tree - def test_not(self): - var = IfParser(["not", False]).parse() - self.assertEqual("(not (literal False))", repr(var)) - self.assert_(var.eval({})) - - self.assertFalse(IfParser(["not", True]).parse().eval({})) - - def test_or(self): - var = IfParser([True, "or", False]).parse() - self.assertEqual("(or (literal True) (literal False))", repr(var)) - self.assert_(var.eval({})) - - def test_in(self): - list_ = [1,2,3] - self.assertCalcEqual(True, [1, 'in', list_]) - self.assertCalcEqual(False, [1, 'in', None]) - self.assertCalcEqual(False, [None, 'in', list_]) - - def test_not_in(self): - list_ = [1,2,3] - self.assertCalcEqual(False, [1, 'not', 'in', list_]) - self.assertCalcEqual(True, [4, 'not', 'in', list_]) - self.assertCalcEqual(False, [1, 'not', 'in', None]) - self.assertCalcEqual(True, [None, 'not', 'in', list_]) - - def test_precedence(self): - # (False and False) or True == True <- we want this one, like Python - # False and (False or True) == False - self.assertCalcEqual(True, [False, 'and', False, 'or', True]) - - # True or (False and False) == True <- we want this one, like Python - # (True or False) and False == False - self.assertCalcEqual(True, [True, 'or', False, 'and', False]) - - # (1 or 1) == 2 -> False - # 1 or (1 == 2) -> True <- we want this one - self.assertCalcEqual(True, [1, 'or', 1, '==', 2]) - - self.assertCalcEqual(True, [True, '==', True, 'or', True, '==', False]) - - self.assertEqual("(or (and (== (literal 1) (literal 2)) (literal 3)) (literal 4))", - repr(IfParser([1, '==', 2, 'and', 3, 'or', 4]).parse())) diff --git a/parts/django/tests/regressiontests/templates/templates/broken_base.html b/parts/django/tests/regressiontests/templates/templates/broken_base.html deleted file mode 100644 index aa41f44..0000000 --- a/parts/django/tests/regressiontests/templates/templates/broken_base.html +++ /dev/null @@ -1 +0,0 @@ -{% include "missing.html" %} diff --git a/parts/django/tests/regressiontests/templates/templates/first/test.html b/parts/django/tests/regressiontests/templates/templates/first/test.html deleted file mode 100644 index 6029fe5..0000000 --- a/parts/django/tests/regressiontests/templates/templates/first/test.html +++ /dev/null @@ -1 +0,0 @@ -First template diff --git a/parts/django/tests/regressiontests/templates/templates/second/test.html b/parts/django/tests/regressiontests/templates/templates/second/test.html deleted file mode 100644 index d9b316f..0000000 --- a/parts/django/tests/regressiontests/templates/templates/second/test.html +++ /dev/null @@ -1 +0,0 @@ -Second template diff --git a/parts/django/tests/regressiontests/templates/templates/test_extends_error.html b/parts/django/tests/regressiontests/templates/templates/test_extends_error.html deleted file mode 100755 index fc74690..0000000 --- a/parts/django/tests/regressiontests/templates/templates/test_extends_error.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "broken_base.html" %} diff --git a/parts/django/tests/regressiontests/templates/templatetags/__init__.py b/parts/django/tests/regressiontests/templates/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/templates/templatetags/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/templates/templatetags/broken_tag.py b/parts/django/tests/regressiontests/templates/templatetags/broken_tag.py deleted file mode 100644 index c70e183..0000000 --- a/parts/django/tests/regressiontests/templates/templatetags/broken_tag.py +++ /dev/null @@ -1 +0,0 @@ -from django import Xtemplate diff --git a/parts/django/tests/regressiontests/templates/templatetags/custom.py b/parts/django/tests/regressiontests/templates/templatetags/custom.py deleted file mode 100644 index fdf8d10..0000000 --- a/parts/django/tests/regressiontests/templates/templatetags/custom.py +++ /dev/null @@ -1,11 +0,0 @@ -from django import template -from django.template.defaultfilters import stringfilter - -register = template.Library() - -def trim(value, num): - return value[:num] -trim = stringfilter(trim) - -register.filter(trim) - diff --git a/parts/django/tests/regressiontests/templates/tests.py b/parts/django/tests/regressiontests/templates/tests.py deleted file mode 100644 index 62b2237..0000000 --- a/parts/django/tests/regressiontests/templates/tests.py +++ /dev/null @@ -1,1389 +0,0 @@ -# -*- coding: utf-8 -*- -from django.conf import settings - -if __name__ == '__main__': - # When running this file in isolation, we need to set up the configuration - # before importing 'template'. - settings.configure() - -from datetime import datetime, timedelta -import time -import os -import sys -import traceback -import unittest - -from django import template -from django.core import urlresolvers -from django.template import loader -from django.template.loaders import app_directories, filesystem, cached -from django.utils.translation import activate, deactivate, ugettext as _ -from django.utils.safestring import mark_safe -from django.utils.tzinfo import LocalTimezone - -from context import ContextTests -from custom import CustomTests -from parser import ParserTests -from unicode import UnicodeTests -from nodelist import NodelistTest -from smartif import * - -try: - from loaders import * -except ImportError: - pass # If setuptools isn't installed, that's fine. Just move on. - -import filters - -################################# -# Custom template tag for tests # -################################# - -register = template.Library() - -class EchoNode(template.Node): - def __init__(self, contents): - self.contents = contents - - def render(self, context): - return " ".join(self.contents) - -def do_echo(parser, token): - return EchoNode(token.contents.split()[1:]) - -register.tag("echo", do_echo) - -template.libraries['testtags'] = register - -##################################### -# Helper objects for template tests # -##################################### - -class SomeException(Exception): - silent_variable_failure = True - -class SomeOtherException(Exception): - pass - -class ContextStackException(Exception): - pass - -class SomeClass: - def __init__(self): - self.otherclass = OtherClass() - - def method(self): - return "SomeClass.method" - - def method2(self, o): - return o - - def method3(self): - raise SomeException - - def method4(self): - raise SomeOtherException - -class OtherClass: - def method(self): - return "OtherClass.method" - -class TestObj(object): - def is_true(self): - return True - - def is_false(self): - return False - - def is_bad(self): - time.sleep(0.3) - return True - -class SilentGetItemClass(object): - def __getitem__(self, key): - raise SomeException - -class SilentAttrClass(object): - def b(self): - raise SomeException - b = property(b) - -class UTF8Class: - "Class whose __str__ returns non-ASCII data" - def __str__(self): - return u'ŠĐĆŽćžšđ'.encode('utf-8') - -class Templates(unittest.TestCase): - def test_loaders_security(self): - ad_loader = app_directories.Loader() - fs_loader = filesystem.Loader() - def test_template_sources(path, template_dirs, expected_sources): - if isinstance(expected_sources, list): - # Fix expected sources so they are normcased and abspathed - expected_sources = [os.path.normcase(os.path.abspath(s)) for s in expected_sources] - # Test the two loaders (app_directores and filesystem). - func1 = lambda p, t: list(ad_loader.get_template_sources(p, t)) - func2 = lambda p, t: list(fs_loader.get_template_sources(p, t)) - for func in (func1, func2): - if isinstance(expected_sources, list): - self.assertEqual(func(path, template_dirs), expected_sources) - else: - self.assertRaises(expected_sources, func, path, template_dirs) - - template_dirs = ['/dir1', '/dir2'] - test_template_sources('index.html', template_dirs, - ['/dir1/index.html', '/dir2/index.html']) - test_template_sources('/etc/passwd', template_dirs, []) - test_template_sources('etc/passwd', template_dirs, - ['/dir1/etc/passwd', '/dir2/etc/passwd']) - test_template_sources('../etc/passwd', template_dirs, []) - test_template_sources('../../../etc/passwd', template_dirs, []) - test_template_sources('/dir1/index.html', template_dirs, - ['/dir1/index.html']) - test_template_sources('../dir2/index.html', template_dirs, - ['/dir2/index.html']) - test_template_sources('/dir1blah', template_dirs, []) - test_template_sources('../dir1blah', template_dirs, []) - - # UTF-8 bytestrings are permitted. - test_template_sources('\xc3\x85ngstr\xc3\xb6m', template_dirs, - [u'/dir1/Ångström', u'/dir2/Ångström']) - # Unicode strings are permitted. - test_template_sources(u'Ångström', template_dirs, - [u'/dir1/Ångström', u'/dir2/Ångström']) - test_template_sources(u'Ångström', ['/Straße'], [u'/Straße/Ångström']) - test_template_sources('\xc3\x85ngstr\xc3\xb6m', ['/Straße'], - [u'/Straße/Ångström']) - # Invalid UTF-8 encoding in bytestrings is not. Should raise a - # semi-useful error message. - test_template_sources('\xc3\xc3', template_dirs, UnicodeDecodeError) - - # Case insensitive tests (for win32). Not run unless we're on - # a case insensitive operating system. - if os.path.normcase('/TEST') == os.path.normpath('/test'): - template_dirs = ['/dir1', '/DIR2'] - test_template_sources('index.html', template_dirs, - ['/dir1/index.html', '/dir2/index.html']) - test_template_sources('/DIR1/index.HTML', template_dirs, - ['/dir1/index.html']) - - def test_loader_debug_origin(self): - # Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with - # the compiled templates. - old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True - old_loaders = loader.template_source_loaders - - try: - loader.template_source_loaders = (filesystem.Loader(),) - - # We rely on the fact that runtests.py sets up TEMPLATE_DIRS to - # point to a directory containing a 404.html file. Also that - # the file system and app directories loaders both inherit the - # load_template method from the BaseLoader class, so we only need - # to test one of them. - load_name = '404.html' - template = loader.get_template(load_name) - template_name = template.nodelist[0].source[0].name - self.assertTrue(template_name.endswith(load_name), - 'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name) - - # Aso test the cached loader, since it overrides load_template - cache_loader = cached.Loader(('',)) - cache_loader._cached_loaders = loader.template_source_loaders - loader.template_source_loaders = (cache_loader,) - - template = loader.get_template(load_name) - template_name = template.nodelist[0].source[0].name - self.assertTrue(template_name.endswith(load_name), - 'Template loaded through cached loader has incorrect name for debug page: %s' % template_name) - - template = loader.get_template(load_name) - template_name = template.nodelist[0].source[0].name - self.assertTrue(template_name.endswith(load_name), - 'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name) - finally: - loader.template_source_loaders = old_loaders - settings.TEMPLATE_DEBUG = old_td - - def test_extends_include_missing_baseloader(self): - """ - Tests that the correct template is identified as not existing - when {% extends %} specifies a template that does exist, but - that template has an {% include %} of something that does not - exist. See #12787. - """ - - # TEMPLATE_DEBUG must be true, otherwise the exception raised - # during {% include %} processing will be suppressed. - old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True - old_loaders = loader.template_source_loaders - - try: - # Test the base loader class via the app loader. load_template - # from base is used by all shipped loaders excepting cached, - # which has its own test. - loader.template_source_loaders = (app_directories.Loader(),) - - load_name = 'test_extends_error.html' - tmpl = loader.get_template(load_name) - r = None - try: - r = tmpl.render(template.Context({})) - except template.TemplateSyntaxError, e: - settings.TEMPLATE_DEBUG = old_td - self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') - self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) - finally: - loader.template_source_loaders = old_loaders - settings.TEMPLATE_DEBUG = old_td - - def test_extends_include_missing_cachedloader(self): - """ - Same as test_extends_include_missing_baseloader, only tests - behavior of the cached loader instead of BaseLoader. - """ - - old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True - old_loaders = loader.template_source_loaders - - try: - cache_loader = cached.Loader(('',)) - cache_loader._cached_loaders = (app_directories.Loader(),) - loader.template_source_loaders = (cache_loader,) - - load_name = 'test_extends_error.html' - tmpl = loader.get_template(load_name) - r = None - try: - r = tmpl.render(template.Context({})) - except template.TemplateSyntaxError, e: - self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') - self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) - - # For the cached loader, repeat the test, to ensure the first attempt did not cache a - # result that behaves incorrectly on subsequent attempts. - tmpl = loader.get_template(load_name) - try: - tmpl.render(template.Context({})) - except template.TemplateSyntaxError, e: - self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') - self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) - finally: - loader.template_source_loaders = old_loaders - settings.TEMPLATE_DEBUG = old_td - - def test_token_smart_split(self): - # Regression test for #7027 - token = template.Token(template.TOKEN_BLOCK, 'sometag _("Page not found") value|yesno:_("yes,no")') - split = token.split_contents() - self.assertEqual(split, ["sometag", '_("Page not found")', 'value|yesno:_("yes,no")']) - - def test_url_reverse_no_settings_module(self): - # Regression test for #9005 - from django.template import Template, Context, TemplateSyntaxError - - old_settings_module = settings.SETTINGS_MODULE - old_template_debug = settings.TEMPLATE_DEBUG - - settings.SETTINGS_MODULE = None - settings.TEMPLATE_DEBUG = True - - t = Template('{% url will_not_match %}') - c = Context() - try: - rendered = t.render(c) - except TemplateSyntaxError, e: - # Assert that we are getting the template syntax error and not the - # string encoding error. - self.assertEquals(e.args[0], "Caught NoReverseMatch while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.") - - settings.SETTINGS_MODULE = old_settings_module - settings.TEMPLATE_DEBUG = old_template_debug - - def test_invalid_block_suggestion(self): - # See #7876 - from django.template import Template, TemplateSyntaxError - try: - t = Template("{% if 1 %}lala{% endblock %}{% endif %}") - except TemplateSyntaxError, e: - self.assertEquals(e.args[0], "Invalid block tag: 'endblock', expected 'else' or 'endif'") - - def test_templates(self): - template_tests = self.get_template_tests() - filter_tests = filters.get_filter_tests() - - # Quickly check that we aren't accidentally using a name in both - # template and filter tests. - overlapping_names = [name for name in filter_tests if name in template_tests] - assert not overlapping_names, 'Duplicate test name(s): %s' % ', '.join(overlapping_names) - - template_tests.update(filter_tests) - - # Register our custom template loader. - def test_template_loader(template_name, template_dirs=None): - "A custom template loader that loads the unit-test templates." - try: - return (template_tests[template_name][0] , "test:%s" % template_name) - except KeyError: - raise template.TemplateDoesNotExist, template_name - - cache_loader = cached.Loader(('test_template_loader',)) - cache_loader._cached_loaders = (test_template_loader,) - - old_template_loaders = loader.template_source_loaders - loader.template_source_loaders = [cache_loader] - - failures = [] - tests = template_tests.items() - tests.sort() - - # Turn TEMPLATE_DEBUG off, because tests assume that. - old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, False - - # Set TEMPLATE_STRING_IF_INVALID to a known string. - old_invalid = settings.TEMPLATE_STRING_IF_INVALID - expected_invalid_str = 'INVALID' - - # Warm the URL reversing cache. This ensures we don't pay the cost - # warming the cache during one of the tests. - urlresolvers.reverse('regressiontests.templates.views.client_action', - kwargs={'id':0,'action':"update"}) - - for name, vals in tests: - if isinstance(vals[2], tuple): - normal_string_result = vals[2][0] - invalid_string_result = vals[2][1] - if isinstance(invalid_string_result, basestring) and '%s' in invalid_string_result: - expected_invalid_str = 'INVALID %s' - invalid_string_result = invalid_string_result % vals[2][2] - template.invalid_var_format_string = True - else: - normal_string_result = vals[2] - invalid_string_result = vals[2] - - if 'LANGUAGE_CODE' in vals[1]: - activate(vals[1]['LANGUAGE_CODE']) - else: - activate('en-us') - - for invalid_str, result in [('', normal_string_result), - (expected_invalid_str, invalid_string_result)]: - settings.TEMPLATE_STRING_IF_INVALID = invalid_str - for is_cached in (False, True): - try: - start = datetime.now() - test_template = loader.get_template(name) - end = datetime.now() - if end-start > timedelta(seconds=0.2): - failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, name)) - - start = datetime.now() - output = self.render(test_template, vals) - end = datetime.now() - if end-start > timedelta(seconds=0.2): - failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name)) - except ContextStackException: - failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name)) - continue - except Exception: - exc_type, exc_value, exc_tb = sys.exc_info() - if exc_type != result: - tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb)) - failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, name, exc_type, exc_value, tb)) - continue - if output != result: - failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, name, result, output)) - cache_loader.reset() - - if 'LANGUAGE_CODE' in vals[1]: - deactivate() - - if template.invalid_var_format_string: - expected_invalid_str = 'INVALID' - template.invalid_var_format_string = False - - loader.template_source_loaders = old_template_loaders - deactivate() - settings.TEMPLATE_DEBUG = old_td - settings.TEMPLATE_STRING_IF_INVALID = old_invalid - - self.assertEqual(failures, [], "Tests failed:\n%s\n%s" % - ('-'*70, ("\n%s\n" % ('-'*70)).join(failures))) - - def render(self, test_template, vals): - context = template.Context(vals[1]) - before_stack_size = len(context.dicts) - output = test_template.render(context) - if len(context.dicts) != before_stack_size: - raise ContextStackException - return output - - def get_template_tests(self): - # SYNTAX -- - # 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class) - return { - ### BASIC SYNTAX ################################################ - - # Plain text should go through the template parser untouched - 'basic-syntax01': ("something cool", {}, "something cool"), - - # Variables should be replaced with their value in the current - # context - 'basic-syntax02': ("{{ headline }}", {'headline':'Success'}, "Success"), - - # More than one replacement variable is allowed in a template - 'basic-syntax03': ("{{ first }} --- {{ second }}", {"first" : 1, "second" : 2}, "1 --- 2"), - - # Fail silently when a variable is not found in the current context - 'basic-syntax04': ("as{{ missing }}df", {}, ("asdf","asINVALIDdf")), - - # A variable may not contain more than one word - 'basic-syntax06': ("{{ multi word variable }}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError for empty variable tags - 'basic-syntax07': ("{{ }}", {}, template.TemplateSyntaxError), - 'basic-syntax08': ("{{ }}", {}, template.TemplateSyntaxError), - - # Attribute syntax allows a template to call an object's attribute - 'basic-syntax09': ("{{ var.method }}", {"var": SomeClass()}, "SomeClass.method"), - - # Multiple levels of attribute access are allowed - 'basic-syntax10': ("{{ var.otherclass.method }}", {"var": SomeClass()}, "OtherClass.method"), - - # Fail silently when a variable's attribute isn't found - 'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, ("","INVALID")), - - # Raise TemplateSyntaxError when trying to access a variable beginning with an underscore - 'basic-syntax12': ("{{ var.__dict__ }}", {"var": SomeClass()}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError when trying to access a variable containing an illegal character - 'basic-syntax13': ("{{ va>r }}", {}, template.TemplateSyntaxError), - 'basic-syntax14': ("{{ (var.r) }}", {}, template.TemplateSyntaxError), - 'basic-syntax15': ("{{ sp%am }}", {}, template.TemplateSyntaxError), - 'basic-syntax16': ("{{ eggs! }}", {}, template.TemplateSyntaxError), - 'basic-syntax17': ("{{ moo? }}", {}, template.TemplateSyntaxError), - - # Attribute syntax allows a template to call a dictionary key's value - 'basic-syntax18': ("{{ foo.bar }}", {"foo" : {"bar" : "baz"}}, "baz"), - - # Fail silently when a variable's dictionary key isn't found - 'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, ("","INVALID")), - - # Fail silently when accessing a non-simple method - 'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ("","INVALID")), - - # Don't get confused when parsing something that is almost, but not - # quite, a template tag. - 'basic-syntax21': ("a {{ moo %} b", {}, "a {{ moo %} b"), - 'basic-syntax22': ("{{ moo #}", {}, "{{ moo #}"), - - # Will try to treat "moo #} {{ cow" as the variable. Not ideal, but - # costly to work around, so this triggers an error. - 'basic-syntax23': ("{{ moo #} {{ cow }}", {"cow": "cow"}, template.TemplateSyntaxError), - - # Embedded newlines make it not-a-tag. - 'basic-syntax24': ("{{ moo\n }}", {}, "{{ moo\n }}"), - - # Literal strings are permitted inside variables, mostly for i18n - # purposes. - 'basic-syntax25': ('{{ "fred" }}', {}, "fred"), - 'basic-syntax26': (r'{{ "\"fred\"" }}', {}, "\"fred\""), - 'basic-syntax27': (r'{{ _("\"fred\"") }}', {}, "\"fred\""), - - # regression test for ticket #12554 - # make sure a silent_variable_failure Exception is supressed - # on dictionary and attribute lookup - 'basic-syntax28': ("{{ a.b }}", {'a': SilentGetItemClass()}, ('', 'INVALID')), - 'basic-syntax29': ("{{ a.b }}", {'a': SilentAttrClass()}, ('', 'INVALID')), - - # Something that starts like a number but has an extra lookup works as a lookup. - 'basic-syntax30': ("{{ 1.2.3 }}", {"1": {"2": {"3": "d"}}}, "d"), - 'basic-syntax31': ("{{ 1.2.3 }}", {"1": {"2": ("a", "b", "c", "d")}}, "d"), - 'basic-syntax32': ("{{ 1.2.3 }}", {"1": (("x", "x", "x", "x"), ("y", "y", "y", "y"), ("a", "b", "c", "d"))}, "d"), - 'basic-syntax33': ("{{ 1.2.3 }}", {"1": ("xxxx", "yyyy", "abcd")}, "d"), - 'basic-syntax34': ("{{ 1.2.3 }}", {"1": ({"x": "x"}, {"y": "y"}, {"z": "z", "3": "d"})}, "d"), - - # Numbers are numbers even if their digits are in the context. - 'basic-syntax35': ("{{ 1 }}", {"1": "abc"}, "1"), - 'basic-syntax36': ("{{ 1.2 }}", {"1": "abc"}, "1.2"), - - # List-index syntax allows a template to access a certain item of a subscriptable object. - 'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"), - - # Fail silently when the list index is out of range. - 'list-index02': ("{{ var.5 }}", {"var": ["first item", "second item"]}, ("", "INVALID")), - - # Fail silently when the variable is not a subscriptable object. - 'list-index03': ("{{ var.1 }}", {"var": None}, ("", "INVALID")), - - # Fail silently when variable is a dict without the specified key. - 'list-index04': ("{{ var.1 }}", {"var": {}}, ("", "INVALID")), - - # Dictionary lookup wins out when dict's key is a string. - 'list-index05': ("{{ var.1 }}", {"var": {'1': "hello"}}, "hello"), - - # But list-index lookup wins out when dict's key is an int, which - # behind the scenes is really a dictionary lookup (for a dict) - # after converting the key to an int. - 'list-index06': ("{{ var.1 }}", {"var": {1: "hello"}}, "hello"), - - # Dictionary lookup wins out when there is a string and int version of the key. - 'list-index07': ("{{ var.1 }}", {"var": {'1': "hello", 1: "world"}}, "hello"), - - # Basic filter usage - 'filter-syntax01': ("{{ var|upper }}", {"var": "Django is the greatest!"}, "DJANGO IS THE GREATEST!"), - - # Chained filters - 'filter-syntax02': ("{{ var|upper|lower }}", {"var": "Django is the greatest!"}, "django is the greatest!"), - - # Raise TemplateSyntaxError for space between a variable and filter pipe - 'filter-syntax03': ("{{ var |upper }}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError for space after a filter pipe - 'filter-syntax04': ("{{ var| upper }}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError for a nonexistent filter - 'filter-syntax05': ("{{ var|does_not_exist }}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError when trying to access a filter containing an illegal character - 'filter-syntax06': ("{{ var|fil(ter) }}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError for invalid block tags - 'filter-syntax07': ("{% nothing_to_see_here %}", {}, template.TemplateSyntaxError), - - # Raise TemplateSyntaxError for empty block tags - 'filter-syntax08': ("{% %}", {}, template.TemplateSyntaxError), - - # Chained filters, with an argument to the first one - 'filter-syntax09': ('{{ var|removetags:"b i"|upper|lower }}', {"var": "<b><i>Yes</i></b>"}, "yes"), - - # Literal string as argument is always "safe" from auto-escaping.. - 'filter-syntax10': (r'{{ var|default_if_none:" endquote\" hah" }}', - {"var": None}, ' endquote" hah'), - - # Variable as argument - 'filter-syntax11': (r'{{ var|default_if_none:var2 }}', {"var": None, "var2": "happy"}, 'happy'), - - # Default argument testing - 'filter-syntax12': (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'), - - # Fail silently for methods that raise an exception with a - # "silent_variable_failure" attribute - 'filter-syntax13': (r'1{{ var.method3 }}2', {"var": SomeClass()}, ("12", "1INVALID2")), - - # In methods that raise an exception without a - # "silent_variable_attribute" set to True, the exception propagates - 'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException), - - # Escaped backslash in argument - 'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'), - - # Escaped backslash using known escape char - 'filter-syntax16': (r'{{ var|default_if_none:"foo\now" }}', {"var": None}, r'foo\now'), - - # Empty strings can be passed as arguments to filters - 'filter-syntax17': (r'{{ var|join:"" }}', {'var': ['a', 'b', 'c']}, 'abc'), - - # 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 ..."), - - #filters should accept empty string constants - 'filter-syntax20': ('{{ ""|default_if_none:"was none" }}', {}, ""), - - ### COMMENT SYNTAX ######################################################## - 'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"), - 'comment-syntax02': ("{# this is hidden #}hello{# foo #}", {}, "hello"), - - # Comments can contain invalid stuff. - 'comment-syntax03': ("foo{# {% if %} #}", {}, "foo"), - 'comment-syntax04': ("foo{# {% endblock %} #}", {}, "foo"), - 'comment-syntax05': ("foo{# {% somerandomtag %} #}", {}, "foo"), - 'comment-syntax06': ("foo{# {% #}", {}, "foo"), - 'comment-syntax07': ("foo{# %} #}", {}, "foo"), - 'comment-syntax08': ("foo{# %} #}bar", {}, "foobar"), - 'comment-syntax09': ("foo{# {{ #}", {}, "foo"), - 'comment-syntax10': ("foo{# }} #}", {}, "foo"), - 'comment-syntax11': ("foo{# { #}", {}, "foo"), - 'comment-syntax12': ("foo{# } #}", {}, "foo"), - - ### COMMENT TAG ########################################################### - 'comment-tag01': ("{% comment %}this is hidden{% endcomment %}hello", {}, "hello"), - 'comment-tag02': ("{% comment %}this is hidden{% endcomment %}hello{% comment %}foo{% endcomment %}", {}, "hello"), - - # Comment tag can contain invalid stuff. - 'comment-tag03': ("foo{% comment %} {% if %} {% endcomment %}", {}, "foo"), - 'comment-tag04': ("foo{% comment %} {% endblock %} {% endcomment %}", {}, "foo"), - 'comment-tag05': ("foo{% comment %} {% somerandomtag %} {% endcomment %}", {}, "foo"), - - ### CYCLE TAG ############################################################# - 'cycle01': ('{% cycle a %}', {}, template.TemplateSyntaxError), - 'cycle02': ('{% cycle a,b,c as abc %}{% cycle abc %}', {}, 'ab'), - 'cycle03': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}', {}, 'abc'), - 'cycle04': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}', {}, 'abca'), - 'cycle05': ('{% cycle %}', {}, template.TemplateSyntaxError), - 'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError), - 'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError), - 'cycle08': ('{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}', {}, 'abbbcc'), - 'cycle09': ("{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), - 'cycle10': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}", {}, 'ab'), - 'cycle11': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}", {}, 'abc'), - 'cycle12': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, 'abca'), - 'cycle13': ("{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), - 'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'), - 'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'), - 'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'), - - ### EXCEPTIONS ############################################################ - - # Raise exception for invalid template name - 'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateDoesNotExist), - - # Raise exception for invalid template name (in variable) - 'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)), - - # Raise exception for extra {% extends %} tags - 'exception03': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% extends 'inheritance16' %}", {}, template.TemplateSyntaxError), - - # Raise exception for custom tags used in child with {% load %} tag in parent, not in child - 'exception04': ("{% extends 'inheritance17' %}{% block first %}{% echo 400 %}5678{% endblock %}", {}, template.TemplateSyntaxError), - - ### FILTER TAG ############################################################ - 'filter01': ('{% filter upper %}{% endfilter %}', {}, ''), - 'filter02': ('{% filter upper %}django{% endfilter %}', {}, 'DJANGO'), - 'filter03': ('{% filter upper|lower %}django{% endfilter %}', {}, 'django'), - 'filter04': ('{% filter cut:remove %}djangospam{% endfilter %}', {'remove': 'spam'}, 'django'), - - ### FIRSTOF TAG ########################################################### - 'firstof01': ('{% firstof a b c %}', {'a':0,'b':0,'c':0}, ''), - 'firstof02': ('{% firstof a b c %}', {'a':1,'b':0,'c':0}, '1'), - 'firstof03': ('{% firstof a b c %}', {'a':0,'b':2,'c':0}, '2'), - 'firstof04': ('{% firstof a b c %}', {'a':0,'b':0,'c':3}, '3'), - 'firstof05': ('{% firstof a b c %}', {'a':1,'b':2,'c':3}, '1'), - 'firstof06': ('{% firstof a b c %}', {'b':0,'c':3}, '3'), - 'firstof07': ('{% firstof a b "c" %}', {'a':0}, 'c'), - 'firstof08': ('{% firstof a b "c and d" %}', {'a':0,'b':0}, 'c and d'), - 'firstof09': ('{% firstof %}', {}, template.TemplateSyntaxError), - - ### FOR TAG ############################################################### - 'for-tag01': ("{% for val in values %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "123"), - 'for-tag02': ("{% for val in values reversed %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "321"), - 'for-tag-vars01': ("{% for val in values %}{{ forloop.counter }}{% endfor %}", {"values": [6, 6, 6]}, "123"), - 'for-tag-vars02': ("{% for val in values %}{{ forloop.counter0 }}{% endfor %}", {"values": [6, 6, 6]}, "012"), - 'for-tag-vars03': ("{% for val in values %}{{ forloop.revcounter }}{% endfor %}", {"values": [6, 6, 6]}, "321"), - 'for-tag-vars04': ("{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}", {"values": [6, 6, 6]}, "210"), - 'for-tag-vars05': ("{% for val in values %}{% if forloop.first %}f{% else %}x{% endif %}{% endfor %}", {"values": [6, 6, 6]}, "fxx"), - 'for-tag-vars06': ("{% for val in values %}{% if forloop.last %}l{% else %}x{% endif %}{% endfor %}", {"values": [6, 6, 6]}, "xxl"), - 'for-tag-unpack01': ("{% for key,value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"), - 'for-tag-unpack03': ("{% for key, value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"), - 'for-tag-unpack04': ("{% for key , value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"), - 'for-tag-unpack05': ("{% for key ,value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"), - 'for-tag-unpack06': ("{% for key value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, template.TemplateSyntaxError), - 'for-tag-unpack07': ("{% for key,,value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, template.TemplateSyntaxError), - 'for-tag-unpack08': ("{% for key,value, in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, template.TemplateSyntaxError), - # Ensure that a single loopvar doesn't truncate the list in val. - 'for-tag-unpack09': ("{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"), - # Otherwise, silently truncate if the length of loopvars differs to the length of each set of items. - 'for-tag-unpack10': ("{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2, 'orange'))}, "one:1/two:2/"), - 'for-tag-unpack11': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, ("one:1,/two:2,/", "one:1,INVALID/two:2,INVALID/")), - 'for-tag-unpack12': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2))}, ("one:1,carrot/two:2,/", "one:1,carrot/two:2,INVALID/")), - 'for-tag-unpack13': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2, 'cheese'))}, ("one:1,carrot/two:2,cheese/", "one:1,carrot/two:2,cheese/")), - 'for-tag-unpack14': ("{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}", {"items": (1, 2)}, (":/:/", "INVALID:INVALID/INVALID:INVALID/")), - 'for-tag-empty01': ("{% for val in values %}{{ val }}{% empty %}empty text{% endfor %}", {"values": [1, 2, 3]}, "123"), - 'for-tag-empty02': ("{% for val in values %}{{ val }}{% empty %}values array empty{% endfor %}", {"values": []}, "values array empty"), - 'for-tag-empty03': ("{% for val in values %}{{ val }}{% empty %}values array not found{% endfor %}", {}, "values array not found"), - - ### IF TAG ################################################################ - 'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"), - 'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"), - 'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"), - - # Filters - 'if-tag-filter01': ("{% if foo|length == 5 %}yes{% else %}no{% endif %}", {'foo': 'abcde'}, "yes"), - 'if-tag-filter02': ("{% if foo|upper == 'ABC' %}yes{% else %}no{% endif %}", {}, "no"), - - # Equality - 'if-tag-eq01': ("{% if foo == bar %}yes{% else %}no{% endif %}", {}, "yes"), - 'if-tag-eq02': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1}, "no"), - 'if-tag-eq03': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 1}, "yes"), - 'if-tag-eq04': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 2}, "no"), - 'if-tag-eq05': ("{% if foo == '' %}yes{% else %}no{% endif %}", {}, "no"), - - # Comparison - 'if-tag-gt-01': ("{% if 2 > 1 %}yes{% else %}no{% endif %}", {}, "yes"), - 'if-tag-gt-02': ("{% if 1 > 1 %}yes{% else %}no{% endif %}", {}, "no"), - 'if-tag-gte-01': ("{% if 1 >= 1 %}yes{% else %}no{% endif %}", {}, "yes"), - 'if-tag-gte-02': ("{% if 1 >= 2 %}yes{% else %}no{% endif %}", {}, "no"), - 'if-tag-lt-01': ("{% if 1 < 2 %}yes{% else %}no{% endif %}", {}, "yes"), - 'if-tag-lt-02': ("{% if 1 < 1 %}yes{% else %}no{% endif %}", {}, "no"), - 'if-tag-lte-01': ("{% if 1 <= 1 %}yes{% else %}no{% endif %}", {}, "yes"), - 'if-tag-lte-02': ("{% if 2 <= 1 %}yes{% else %}no{% endif %}", {}, "no"), - - # Contains - 'if-tag-in-01': ("{% if 1 in x %}yes{% else %}no{% endif %}", {'x':[1]}, "yes"), - 'if-tag-in-02': ("{% if 2 in x %}yes{% else %}no{% endif %}", {'x':[1]}, "no"), - 'if-tag-not-in-01': ("{% if 1 not in x %}yes{% else %}no{% endif %}", {'x':[1]}, "no"), - 'if-tag-not-in-02': ("{% if 2 not in x %}yes{% else %}no{% endif %}", {'x':[1]}, "yes"), - - # AND - 'if-tag-and01': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), - 'if-tag-and02': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), - 'if-tag-and03': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), - 'if-tag-and04': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), - 'if-tag-and05': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'), - 'if-tag-and06': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'), - 'if-tag-and07': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True}, 'no'), - 'if-tag-and08': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': True}, 'no'), - - # OR - 'if-tag-or01': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), - 'if-tag-or02': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), - 'if-tag-or03': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), - 'if-tag-or04': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), - 'if-tag-or05': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'), - 'if-tag-or06': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'), - 'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'), - 'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'), - - # multiple ORs - 'if-tag-or09': ("{% if foo or bar or baz %}yes{% else %}no{% endif %}", {'baz': True}, 'yes'), - - # NOT - 'if-tag-not01': ("{% if not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'yes'), - 'if-tag-not02': ("{% if not not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'no'), - # not03 to not05 removed, now TemplateSyntaxErrors - - 'if-tag-not06': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {}, 'no'), - 'if-tag-not07': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), - 'if-tag-not08': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), - 'if-tag-not09': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), - 'if-tag-not10': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), - - 'if-tag-not11': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {}, 'no'), - 'if-tag-not12': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), - 'if-tag-not13': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), - 'if-tag-not14': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), - 'if-tag-not15': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), - - 'if-tag-not16': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'), - 'if-tag-not17': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), - 'if-tag-not18': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), - 'if-tag-not19': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), - 'if-tag-not20': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), - - 'if-tag-not21': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {}, 'yes'), - 'if-tag-not22': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), - 'if-tag-not23': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), - 'if-tag-not24': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), - 'if-tag-not25': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), - - 'if-tag-not26': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {}, 'yes'), - 'if-tag-not27': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), - 'if-tag-not28': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), - 'if-tag-not29': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), - 'if-tag-not30': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), - - 'if-tag-not31': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'), - 'if-tag-not32': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), - 'if-tag-not33': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), - 'if-tag-not34': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), - 'if-tag-not35': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), - - # Various syntax errors - 'if-tag-error01': ("{% if %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error02': ("{% if foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), - 'if-tag-error03': ("{% if foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), - 'if-tag-error04': ("{% if not foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), - 'if-tag-error05': ("{% if not foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), - 'if-tag-error06': ("{% if abc def %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error07': ("{% if not %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error08': ("{% if and %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error09': ("{% if or %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error10': ("{% if == %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error11': ("{% if 1 == %}yes{% endif %}", {}, template.TemplateSyntaxError), - 'if-tag-error12': ("{% if a not b %}yes{% endif %}", {}, template.TemplateSyntaxError), - - # If evaluations are shortcircuited where possible - # These tests will fail by taking too long to run. When the if clause - # is shortcircuiting correctly, the is_bad() function shouldn't be - # evaluated, and the deliberate sleep won't happen. - 'if-tag-shortcircuit01': ('{% if x.is_true or x.is_bad %}yes{% else %}no{% endif %}', {'x': TestObj()}, "yes"), - 'if-tag-shortcircuit02': ('{% if x.is_false and x.is_bad %}yes{% else %}no{% endif %}', {'x': TestObj()}, "no"), - - # Non-existent args - 'if-tag-badarg01':("{% if x|default_if_none:y %}yes{% endif %}", {}, ''), - 'if-tag-badarg02':("{% if x|default_if_none:y %}yes{% endif %}", {'y': 0}, ''), - 'if-tag-badarg03':("{% if x|default_if_none:y %}yes{% endif %}", {'y': 1}, 'yes'), - 'if-tag-badarg04':("{% if x|default_if_none:y %}yes{% else %}no{% endif %}", {}, 'no'), - - # Additional, more precise parsing tests are in SmartIfTests - - ### IFCHANGED TAG ######################################################### - 'ifchanged01': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', {'num': (1,2,3)}, '123'), - 'ifchanged02': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', {'num': (1,1,3)}, '13'), - 'ifchanged03': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', {'num': (1,1,1)}, '1'), - 'ifchanged04': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', {'num': (1, 2, 3), 'numx': (2, 2, 2)}, '122232'), - 'ifchanged05': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', {'num': (1, 1, 1), 'numx': (1, 2, 3)}, '1123123123'), - 'ifchanged06': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', {'num': (1, 1, 1), 'numx': (2, 2, 2)}, '1222'), - 'ifchanged07': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% for y in numy %}{% ifchanged %}{{ y }}{% endifchanged %}{% endfor %}{% endfor %}{% endfor %}', {'num': (1, 1, 1), 'numx': (2, 2, 2), 'numy': (3, 3, 3)}, '1233323332333'), - 'ifchanged08': ('{% for data in datalist %}{% for c,d in data %}{% if c %}{% ifchanged %}{{ d }}{% endifchanged %}{% endif %}{% endfor %}{% endfor %}', {'datalist': [[(1, 'a'), (1, 'a'), (0, 'b'), (1, 'c')], [(0, 'a'), (1, 'c'), (1, 'd'), (1, 'd'), (0, 'e')]]}, 'accd'), - - # Test one parameter given to ifchanged. - 'ifchanged-param01': ('{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}', { 'num': (1,2,3) }, '..1..2..3'), - 'ifchanged-param02': ('{% for n in num %}{% for x in numx %}{% ifchanged n %}..{% endifchanged %}{{ x }}{% endfor %}{% endfor %}', { 'num': (1,2,3), 'numx': (5,6,7) }, '..567..567..567'), - - # Test multiple parameters to ifchanged. - 'ifchanged-param03': ('{% for n in num %}{{ n }}{% for x in numx %}{% ifchanged x n %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1,1,2), 'numx': (5,6,6) }, '156156256'), - - # Test a date+hour like construct, where the hour of the last day - # is the same but the date had changed, so print the hour anyway. - 'ifchanged-param04': ('{% for d in days %}{% ifchanged %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'), - - # Logically the same as above, just written with explicit - # ifchanged for the day. - 'ifchanged-param05': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'), - - # Test the else clause of ifchanged. - 'ifchanged-else01': ('{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-first,1-other,2-first,2-other,2-other,3-first,'), - - 'ifchanged-else02': ('{% for id in ids %}{{ id }}-{% ifchanged id %}{% cycle red,blue %}{% else %}grey{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1-grey,2-blue,2-grey,2-grey,3-red,'), - 'ifchanged-else03': ('{% for id in ids %}{{ id }}{% ifchanged id %}-{% cycle red,blue %}{% else %}{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1,2-blue,2,2,3-red,'), - - 'ifchanged-else04': ('{% for id in ids %}{% ifchanged %}***{{ id }}*{% else %}...{% endifchanged %}{{ forloop.counter }}{% endfor %}', {'ids': [1,1,2,2,2,3,4]}, '***1*1...2***2*3...4...5***3*6***4*7'), - - ### IFEQUAL TAG ########################################################### - 'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""), - 'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"), - 'ifequal03': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 2}, "no"), - 'ifequal04': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 1}, "yes"), - 'ifequal05': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "test"}, "yes"), - 'ifequal06': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "no"}, "no"), - 'ifequal07': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "test"}, "yes"), - 'ifequal08': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "no"}, "no"), - 'ifequal09': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {}, "no"), - 'ifequal10': ('{% ifequal a b %}yes{% else %}no{% endifequal %}', {}, "yes"), - - # SMART SPLITTING - 'ifequal-split01': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {}, "no"), - 'ifequal-split02': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'foo'}, "no"), - 'ifequal-split03': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'test man'}, "yes"), - 'ifequal-split04': ("{% ifequal a 'test man' %}yes{% else %}no{% endifequal %}", {'a': 'test man'}, "yes"), - 'ifequal-split05': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': ''}, "no"), - 'ifequal-split06': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i "love" you'}, "yes"), - 'ifequal-split07': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i love you'}, "no"), - 'ifequal-split08': (r"{% ifequal a 'I\'m happy' %}yes{% else %}no{% endifequal %}", {'a': "I'm happy"}, "yes"), - 'ifequal-split09': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slash\man"}, "yes"), - 'ifequal-split10': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slashman"}, "no"), - - # NUMERIC RESOLUTION - 'ifequal-numeric01': ('{% ifequal x 5 %}yes{% endifequal %}', {'x': '5'}, ''), - 'ifequal-numeric02': ('{% ifequal x 5 %}yes{% endifequal %}', {'x': 5}, 'yes'), - 'ifequal-numeric03': ('{% ifequal x 5.2 %}yes{% endifequal %}', {'x': 5}, ''), - 'ifequal-numeric04': ('{% ifequal x 5.2 %}yes{% endifequal %}', {'x': 5.2}, 'yes'), - 'ifequal-numeric05': ('{% ifequal x 0.2 %}yes{% endifequal %}', {'x': .2}, 'yes'), - 'ifequal-numeric06': ('{% ifequal x .2 %}yes{% endifequal %}', {'x': .2}, 'yes'), - 'ifequal-numeric07': ('{% ifequal x 2. %}yes{% endifequal %}', {'x': 2}, ''), - 'ifequal-numeric08': ('{% ifequal x "5" %}yes{% endifequal %}', {'x': 5}, ''), - 'ifequal-numeric09': ('{% ifequal x "5" %}yes{% endifequal %}', {'x': '5'}, 'yes'), - 'ifequal-numeric10': ('{% ifequal x -5 %}yes{% endifequal %}', {'x': -5}, 'yes'), - 'ifequal-numeric11': ('{% ifequal x -5.2 %}yes{% endifequal %}', {'x': -5.2}, 'yes'), - 'ifequal-numeric12': ('{% ifequal x +5 %}yes{% endifequal %}', {'x': 5}, 'yes'), - - # FILTER EXPRESSIONS AS ARGUMENTS - 'ifequal-filter01': ('{% ifequal a|upper "A" %}x{% endifequal %}', {'a': 'a'}, 'x'), - 'ifequal-filter02': ('{% ifequal "A" a|upper %}x{% endifequal %}', {'a': 'a'}, 'x'), - 'ifequal-filter03': ('{% ifequal a|upper b|upper %}x{% endifequal %}', {'a': 'x', 'b': 'X'}, 'x'), - 'ifequal-filter04': ('{% ifequal x|slice:"1" "a" %}x{% endifequal %}', {'x': 'aaa'}, 'x'), - 'ifequal-filter05': ('{% ifequal x|slice:"1"|upper "A" %}x{% endifequal %}', {'x': 'aaa'}, 'x'), - - ### IFNOTEQUAL TAG ######################################################## - 'ifnotequal01': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 2}, "yes"), - 'ifnotequal02': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 1}, ""), - 'ifnotequal03': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 2}, "yes"), - 'ifnotequal04': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 1}, "no"), - - ### INCLUDE TAG ########################################################### - 'include01': ('{% include "basic-syntax01" %}', {}, "something cool"), - 'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"), - 'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"), - 'include04': ('a{% include "nonexistent" %}b', {}, "ab"), - 'include 05': ('template with a space', {}, 'template with a space'), - 'include06': ('{% include "include 05"%}', {}, 'template with a space'), - - ### NAMED ENDBLOCKS ####################################################### - - # Basic test - 'namedendblocks01': ("1{% block first %}_{% block second %}2{% endblock second %}_{% endblock first %}3", {}, '1_2_3'), - - # Unbalanced blocks - 'namedendblocks02': ("1{% block first %}_{% block second %}2{% endblock first %}_{% endblock second %}3", {}, template.TemplateSyntaxError), - 'namedendblocks03': ("1{% block first %}_{% block second %}2{% endblock %}_{% endblock second %}3", {}, template.TemplateSyntaxError), - 'namedendblocks04': ("1{% block first %}_{% block second %}2{% endblock second %}_{% endblock third %}3", {}, template.TemplateSyntaxError), - 'namedendblocks05': ("1{% block first %}_{% block second %}2{% endblock first %}", {}, template.TemplateSyntaxError), - - # Mixed named and unnamed endblocks - 'namedendblocks06': ("1{% block first %}_{% block second %}2{% endblock %}_{% endblock first %}3", {}, '1_2_3'), - 'namedendblocks07': ("1{% block first %}_{% block second %}2{% endblock second %}_{% endblock %}3", {}, '1_2_3'), - - ### INHERITANCE ########################################################### - - # Standard template with no inheritance - 'inheritance01': ("1{% block first %}&{% endblock %}3{% block second %}_{% endblock %}", {}, '1&3_'), - - # Standard two-level inheritance - 'inheritance02': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'), - - # Three-level with no redefinitions on third level - 'inheritance03': ("{% extends 'inheritance02' %}", {}, '1234'), - - # Two-level with no redefinitions on second level - 'inheritance04': ("{% extends 'inheritance01' %}", {}, '1&3_'), - - # Two-level with double quotes instead of single quotes - 'inheritance05': ('{% extends "inheritance02" %}', {}, '1234'), - - # Three-level with variable parent-template name - 'inheritance06': ("{% extends foo %}", {'foo': 'inheritance02'}, '1234'), - - # Two-level with one block defined, one block not defined - 'inheritance07': ("{% extends 'inheritance01' %}{% block second %}5{% endblock %}", {}, '1&35'), - - # Three-level with one block defined on this level, two blocks defined next level - 'inheritance08': ("{% extends 'inheritance02' %}{% block second %}5{% endblock %}", {}, '1235'), - - # Three-level with second and third levels blank - 'inheritance09': ("{% extends 'inheritance04' %}", {}, '1&3_'), - - # Three-level with space NOT in a block -- should be ignored - 'inheritance10': ("{% extends 'inheritance04' %} ", {}, '1&3_'), - - # Three-level with both blocks defined on this level, but none on second level - 'inheritance11': ("{% extends 'inheritance04' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'), - - # Three-level with this level providing one and second level providing the other - 'inheritance12': ("{% extends 'inheritance07' %}{% block first %}2{% endblock %}", {}, '1235'), - - # Three-level with this level overriding second level - 'inheritance13': ("{% extends 'inheritance02' %}{% block first %}a{% endblock %}{% block second %}b{% endblock %}", {}, '1a3b'), - - # A block defined only in a child template shouldn't be displayed - 'inheritance14': ("{% extends 'inheritance01' %}{% block newblock %}NO DISPLAY{% endblock %}", {}, '1&3_'), - - # A block within another block - 'inheritance15': ("{% extends 'inheritance01' %}{% block first %}2{% block inner %}inner{% endblock %}{% endblock %}", {}, '12inner3_'), - - # A block within another block (level 2) - 'inheritance16': ("{% extends 'inheritance15' %}{% block inner %}out{% endblock %}", {}, '12out3_'), - - # {% load %} tag (parent -- setup for exception04) - 'inheritance17': ("{% load testtags %}{% block first %}1234{% endblock %}", {}, '1234'), - - # {% load %} tag (standard usage, without inheritance) - 'inheritance18': ("{% load testtags %}{% echo this that theother %}5678", {}, 'this that theother5678'), - - # {% load %} tag (within a child template) - 'inheritance19': ("{% extends 'inheritance01' %}{% block first %}{% load testtags %}{% echo 400 %}5678{% endblock %}", {}, '140056783_'), - - # Two-level inheritance with {{ block.super }} - 'inheritance20': ("{% extends 'inheritance01' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1&a3_'), - - # Three-level inheritance with {{ block.super }} from parent - 'inheritance21': ("{% extends 'inheritance02' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '12a34'), - - # Three-level inheritance with {{ block.super }} from grandparent - 'inheritance22': ("{% extends 'inheritance04' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1&a3_'), - - # Three-level inheritance with {{ block.super }} from parent and grandparent - 'inheritance23': ("{% extends 'inheritance20' %}{% block first %}{{ block.super }}b{% endblock %}", {}, '1&ab3_'), - - # Inheritance from local context without use of template loader - 'inheritance24': ("{% extends context_template %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {'context_template': template.Template("1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}")}, '1234'), - - # Inheritance from local context with variable parent template - 'inheritance25': ("{% extends context_template.1 %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {'context_template': [template.Template("Wrong"), template.Template("1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}")]}, '1234'), - - # Set up a base template to extend - 'inheritance26': ("no tags", {}, 'no tags'), - - # Inheritance from a template that doesn't have any blocks - 'inheritance27': ("{% extends 'inheritance26' %}", {}, 'no tags'), - - # Set up a base template with a space in it. - 'inheritance 28': ("{% block first %}!{% endblock %}", {}, '!'), - - # Inheritance from a template with a space in its name should work. - 'inheritance29': ("{% extends 'inheritance 28' %}", {}, '!'), - - # Base template, putting block in a conditional {% if %} tag - 'inheritance30': ("1{% if optional %}{% block opt %}2{% endblock %}{% endif %}3", {'optional': True}, '123'), - - # Inherit from a template with block wrapped in an {% if %} tag (in parent), still gets overridden - 'inheritance31': ("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}", {'optional': True}, '1two3'), - 'inheritance32': ("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}", {}, '13'), - - # Base template, putting block in a conditional {% ifequal %} tag - 'inheritance33': ("1{% ifequal optional 1 %}{% block opt %}2{% endblock %}{% endifequal %}3", {'optional': 1}, '123'), - - # Inherit from a template with block wrapped in an {% ifequal %} tag (in parent), still gets overridden - 'inheritance34': ("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}", {'optional': 1}, '1two3'), - 'inheritance35': ("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}", {'optional': 2}, '13'), - - # Base template, putting block in a {% for %} tag - 'inheritance36': ("{% for n in numbers %}_{% block opt %}{{ n }}{% endblock %}{% endfor %}_", {'numbers': '123'}, '_1_2_3_'), - - # Inherit from a template with block wrapped in an {% for %} tag (in parent), still gets overridden - 'inheritance37': ("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}", {'numbers': '123'}, '_X_X_X_'), - 'inheritance38': ("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}", {}, '_'), - - # The super block will still be found. - 'inheritance39': ("{% extends 'inheritance30' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': True}, '1new23'), - 'inheritance40': ("{% extends 'inheritance33' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': 1}, '1new23'), - 'inheritance41': ("{% extends 'inheritance36' %}{% block opt %}new{{ block.super }}{% endblock %}", {'numbers': '123'}, '_new1_new2_new3_'), - - ### I18N ################################################################## - - # {% spaceless %} tag - 'spaceless01': ("{% spaceless %} <b> <i> text </i> </b> {% endspaceless %}", {}, "<b><i> text </i></b>"), - 'spaceless02': ("{% spaceless %} <b> \n <i> text </i> \n </b> {% endspaceless %}", {}, "<b><i> text </i></b>"), - 'spaceless03': ("{% spaceless %}<b><i>text</i></b>{% endspaceless %}", {}, "<b><i>text</i></b>"), - - # simple translation of a string delimited by ' - 'i18n01': ("{% load i18n %}{% trans 'xxxyyyxxx' %}", {}, "xxxyyyxxx"), - - # simple translation of a string delimited by " - 'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, "xxxyyyxxx"), - - # simple translation of a variable - 'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u"Å"), - - # simple translation of a variable and filter - 'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u'å'), - - # simple translation of a string with interpolation - 'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"), - - # simple translation of a string to german - 'i18n06': ('{% load i18n %}{% trans "Page not found" %}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"), - - # translation of singular form - 'i18n07': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}{{ counter }} plural{% endblocktrans %}', {'number': 1}, "singular"), - - # translation of plural form - 'i18n08': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}{{ counter }} plural{% endblocktrans %}', {'number': 2}, "2 plural"), - - # simple non-translation (only marking) of a string to german - 'i18n09': ('{% load i18n %}{% trans "Page not found" noop %}', {'LANGUAGE_CODE': 'de'}, "Page not found"), - - # translation of a variable with a translated filter - 'i18n10': ('{{ bool|yesno:_("yes,no,maybe") }}', {'bool': True, 'LANGUAGE_CODE': 'de'}, 'Ja'), - - # translation of a variable with a non-translated filter - 'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'), - - # usage of the get_available_languages tag - 'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'), - - # translation of constant strings - 'i18n13': ('{{ _("Password") }}', {'LANGUAGE_CODE': 'de'}, 'Passwort'), - 'i18n14': ('{% cycle "foo" _("Password") _(\'Password\') as c %} {% cycle c %} {% cycle c %}', {'LANGUAGE_CODE': 'de'}, 'foo Passwort Passwort'), - 'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 'de', 'absent': ""}, 'Passwort'), - 'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'), - - # Escaping inside blocktrans and trans works as if it was directly in the - # template. - 'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), - 'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), - 'i18n19': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': 'a & b'}, u'a & b'), - 'i18n20': ('{% load i18n %}{% trans andrew %}', {'andrew': 'a & b'}, u'a & b'), - 'i18n21': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': mark_safe('a & b')}, u'a & b'), - 'i18n22': ('{% load i18n %}{% trans andrew %}', {'andrew': mark_safe('a & b')}, u'a & b'), - - # Use filters with the {% trans %} tag, #5972 - 'i18n23': ('{% load i18n %}{% trans "Page not found"|capfirst|slice:"6:" %}', {'LANGUAGE_CODE': 'de'}, u'nicht gefunden'), - 'i18n24': ("{% load i18n %}{% trans 'Page not found'|upper %}", {'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'), - 'i18n25': ('{% load i18n %}{% trans somevar|upper %}', {'somevar': 'Page not found', 'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'), - - # translation of plural form with extra field in singular form (#13568) - 'i18n26': ('{% load i18n %}{% blocktrans with myextra_field as extra_field count number as counter %}singular {{ extra_field }}{% plural %}plural{% endblocktrans %}', {'number': 1, 'myextra_field': 'test'}, "singular test"), - - # translation of singular form in russian (#14126) - 'i18n27': ('{% load i18n %}{% blocktrans count number as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %}', {'number': 1, 'LANGUAGE_CODE': 'ru'}, u'1 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442'), - - ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### - - 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')), - 'invalidstr02': ('{{ var|default_if_none:"Foo" }}', {}, ('','INVALID')), - 'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, ''), - 'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 'No'), - 'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% endif %}', {}, 'Yes'), - 'invalidstr05': ('{{ var }}', {}, ('', 'INVALID %s', 'var')), - 'invalidstr06': ('{{ var.prop }}', {'var': {}}, ('', 'INVALID %s', 'var.prop')), - - ### MULTILINE ############################################################# - - 'multiline01': (""" - Hello, - boys. - How - are - you - gentlemen. - """, - {}, - """ - Hello, - boys. - How - are - you - gentlemen. - """), - - ### REGROUP TAG ########################################################### - 'regroup01': ('{% regroup data by bar as grouped %}' + \ - '{% for group in grouped %}' + \ - '{{ group.grouper }}:' + \ - '{% for item in group.list %}' + \ - '{{ item.foo }}' + \ - '{% endfor %},' + \ - '{% endfor %}', - {'data': [ {'foo':'c', 'bar':1}, - {'foo':'d', 'bar':1}, - {'foo':'a', 'bar':2}, - {'foo':'b', 'bar':2}, - {'foo':'x', 'bar':3} ]}, - '1:cd,2:ab,3:x,'), - - # Test for silent failure when target variable isn't found - 'regroup02': ('{% regroup data by bar as grouped %}' + \ - '{% for group in grouped %}' + \ - '{{ group.grouper }}:' + \ - '{% for item in group.list %}' + \ - '{{ item.foo }}' + \ - '{% endfor %},' + \ - '{% endfor %}', - {}, ''), - - ### TEMPLATETAG TAG ####################################################### - 'templatetag01': ('{% templatetag openblock %}', {}, '{%'), - 'templatetag02': ('{% templatetag closeblock %}', {}, '%}'), - 'templatetag03': ('{% templatetag openvariable %}', {}, '{{'), - 'templatetag04': ('{% templatetag closevariable %}', {}, '}}'), - 'templatetag05': ('{% templatetag %}', {}, template.TemplateSyntaxError), - 'templatetag06': ('{% templatetag foo %}', {}, template.TemplateSyntaxError), - 'templatetag07': ('{% templatetag openbrace %}', {}, '{'), - 'templatetag08': ('{% templatetag closebrace %}', {}, '}'), - 'templatetag09': ('{% templatetag openbrace %}{% templatetag openbrace %}', {}, '{{'), - 'templatetag10': ('{% templatetag closebrace %}{% templatetag closebrace %}', {}, '}}'), - 'templatetag11': ('{% templatetag opencomment %}', {}, '{#'), - 'templatetag12': ('{% templatetag closecomment %}', {}, '#}'), - - ### WIDTHRATIO TAG ######################################################## - 'widthratio01': ('{% widthratio a b 0 %}', {'a':50,'b':100}, '0'), - 'widthratio02': ('{% widthratio a b 100 %}', {'a':0,'b':0}, ''), - 'widthratio03': ('{% widthratio a b 100 %}', {'a':0,'b':100}, '0'), - 'widthratio04': ('{% widthratio a b 100 %}', {'a':50,'b':100}, '50'), - 'widthratio05': ('{% widthratio a b 100 %}', {'a':100,'b':100}, '100'), - - # 62.5 should round to 63 - 'widthratio06': ('{% widthratio a b 100 %}', {'a':50,'b':80}, '63'), - - # 71.4 should round to 71 - 'widthratio07': ('{% widthratio a b 100 %}', {'a':50,'b':70}, '71'), - - # Raise exception if we don't have 3 args, last one an integer - 'widthratio08': ('{% widthratio %}', {}, template.TemplateSyntaxError), - 'widthratio09': ('{% widthratio a b %}', {'a':50,'b':100}, template.TemplateSyntaxError), - 'widthratio10': ('{% widthratio a b 100.0 %}', {'a':50,'b':100}, '50'), - - # #10043: widthratio should allow max_width to be a variable - 'widthratio11': ('{% widthratio a b c %}', {'a':50,'b':100, 'c': 100}, '50'), - - ### WITH TAG ######################################################## - 'with01': ('{% with dict.key as key %}{{ key }}{% endwith %}', {'dict': {'key':50}}, '50'), - 'with02': ('{{ key }}{% with dict.key as key %}{{ key }}-{{ dict.key }}-{{ key }}{% endwith %}{{ key }}', {'dict': {'key':50}}, ('50-50-50', 'INVALID50-50-50INVALID')), - - 'with-error01': ('{% with dict.key xx key %}{{ key }}{% endwith %}', {'dict': {'key':50}}, template.TemplateSyntaxError), - 'with-error02': ('{% with dict.key as %}{{ key }}{% endwith %}', {'dict': {'key':50}}, template.TemplateSyntaxError), - - ### NOW TAG ######################################################## - # Simple case - 'now01': ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)), - - # Check parsing of escaped and special characters - 'now02': ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError), - # 'now03': ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)), - # 'now04': ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year)) - - ### URL TAG ######################################################## - # Successes - 'legacyurl02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'legacyurl02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'legacyurl02b': ("{% url regressiontests.templates.views.client_action id=client.id,action='update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'legacyurl02c': ("{% url regressiontests.templates.views.client_action client.id,'update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'legacyurl10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), - 'legacyurl13': ('{% url regressiontests.templates.views.client_action id=client.id, action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), - 'legacyurl14': ('{% url regressiontests.templates.views.client_action client.id, arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), - 'legacyurl16': ('{% url regressiontests.templates.views.client_action action="update",id="1" %}', {}, '/url_tag/client/1/update/'), - 'legacyurl16a': ("{% url regressiontests.templates.views.client_action action='update',id='1' %}", {}, '/url_tag/client/1/update/'), - 'legacyurl17': ('{% url regressiontests.templates.views.client_action client_id=client.my_id,action=action %}', {'client': {'my_id': 1}, 'action': 'update'}, '/url_tag/client/1/update/'), - - 'url01': ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), - 'url02': ('{% url regressiontests.templates.views.client_action id=client.id action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'url02a': ('{% url regressiontests.templates.views.client_action client.id "update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'url02b': ("{% url regressiontests.templates.views.client_action id=client.id action='update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'), - 'url02c': ("{% url regressiontests.templates.views.client_action client.id '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 метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), - 'url06': (u'{% url метка_оператора_2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), - 'url07': (u'{% url regressiontests.templates.views.client2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), - 'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), - 'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), - 'url10': ('{% url regressiontests.templates.views.client_action id=client.id action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), - 'url11': ('{% url regressiontests.templates.views.client_action id=client.id action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'), - 'url12': ('{% url regressiontests.templates.views.client_action id=client.id action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'), - 'url13': ('{% url regressiontests.templates.views.client_action id=client.id action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), - 'url14': ('{% url regressiontests.templates.views.client_action client.id arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), - 'url15': ('{% url regressiontests.templates.views.client_action 12 "test" %}', {}, '/url_tag/client/12/test/'), - 'url18': ('{% url regressiontests.templates.views.client "1,2" %}', {}, '/url_tag/client/1,2/'), - - # Failures - 'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError), - 'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch), - 'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch), - 'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError), - 'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError), - 'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError), - 'url-fail07': ('{% url view a.id!id %}', {}, template.TemplateSyntaxError), - 'url-fail08': ('{% url view id="unterminatedstring %}', {}, template.TemplateSyntaxError), - 'url-fail09': ('{% url view id=", %}', {}, template.TemplateSyntaxError), - - # {% url ... as var %} - 'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''), - 'url-asvar02': ('{% url regressiontests.templates.views.index as url %}{{ url }}', {}, '/url_tag/'), - 'url-asvar03': ('{% url no_such_view as url %}{{ url }}', {}, ''), - - ### CACHE TAG ###################################################### - 'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'), - 'cache02': ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'), - 'cache03': ('{% load cache %}{% cache 2 test %}cache03{% endcache %}', {}, 'cache03'), - 'cache04': ('{% load cache %}{% cache 2 test %}cache04{% endcache %}', {}, 'cache03'), - 'cache05': ('{% load cache %}{% cache 2 test foo %}cache05{% endcache %}', {'foo': 1}, 'cache05'), - 'cache06': ('{% load cache %}{% cache 2 test foo %}cache06{% endcache %}', {'foo': 2}, 'cache06'), - 'cache07': ('{% load cache %}{% cache 2 test foo %}cache07{% endcache %}', {'foo': 1}, 'cache05'), - - # Allow first argument to be a variable. - 'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'), - 'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'), - 'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'), - - # Raise exception if we don't have at least 2 args, first one integer. - 'cache11': ('{% load cache %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError), - 'cache12': ('{% load cache %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError), - 'cache13': ('{% load cache %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError), - 'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError), - 'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError), - - # Regression test for #7460. - 'cache16': ('{% load cache %}{% cache 1 foo bar %}{% endcache %}', {'foo': 'foo', 'bar': 'with spaces'}, ''), - - # Regression test for #11270. - 'cache17': ('{% load cache %}{% cache 10 long_cache_key poem %}Some Content{% endcache %}', {'poem': 'Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont.'}, 'Some Content'), - - - ### AUTOESCAPE TAG ############################################## - 'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"), - 'autoescape-tag02': ("{% autoescape off %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"), - 'autoescape-tag03': ("{% autoescape on %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"), - - # Autoescape disabling and enabling nest in a predictable way. - 'autoescape-tag04': ("{% autoescape off %}{{ first }} {% autoescape on%}{{ first }}{% endautoescape %}{% endautoescape %}", {"first": "<a>"}, "<a> <a>"), - - 'autoescape-tag05': ("{% autoescape on %}{{ first }}{% endautoescape %}", {"first": "<b>first</b>"}, "<b>first</b>"), - - # Strings (ASCII or unicode) already marked as "safe" are not - # auto-escaped - 'autoescape-tag06': ("{{ first }}", {"first": mark_safe("<b>first</b>")}, "<b>first</b>"), - 'autoescape-tag07': ("{% autoescape on %}{{ first }}{% endautoescape %}", {"first": mark_safe(u"<b>Apple</b>")}, u"<b>Apple</b>"), - - # Literal string arguments to filters, if used in the result, are - # safe. - 'autoescape-tag08': (r'{% autoescape on %}{{ var|default_if_none:" endquote\" hah" }}{% endautoescape %}', {"var": None}, ' endquote" hah'), - - # Objects which return safe strings as their __unicode__ method - # won't get double-escaped. - 'autoescape-tag09': (r'{{ unsafe }}', {'unsafe': filters.UnsafeClass()}, 'you & me'), - 'autoescape-tag10': (r'{{ safe }}', {'safe': filters.SafeClass()}, 'you > me'), - - # The "safe" and "escape" filters cannot work due to internal - # implementation details (fortunately, the (no)autoescape block - # tags can be used in those cases) - 'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError), - - # ifqeual compares unescaped vales. - 'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes" ), - - # Arguments to filters are 'safe' and manipulate their input unescaped. - 'autoescape-filters01': ('{{ var|cut:"&" }}', { "var": "this & that" }, "this that" ), - 'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry" ), - - # Literal strings are safe. - 'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that" ), - - # Iterating over strings outputs safe characters. - 'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&,R," ), - - # Escape requirement survives lookup. - 'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this & that" ), - - } - - -class TemplateTagLoading(unittest.TestCase): - - def setUp(self): - self.old_path = sys.path[:] - self.old_apps = settings.INSTALLED_APPS - self.egg_dir = '%s/eggs' % os.path.dirname(__file__) - self.old_tag_modules = template.templatetags_modules - template.templatetags_modules = [] - - def tearDown(self): - settings.INSTALLED_APPS = self.old_apps - sys.path = self.old_path - template.templatetags_modules = self.old_tag_modules - - def test_load_error(self): - ttext = "{% load broken_tag %}" - self.assertRaises(template.TemplateSyntaxError, template.Template, ttext) - try: - template.Template(ttext) - except template.TemplateSyntaxError, e: - self.assertTrue('ImportError' in e.args[0]) - self.assertTrue('Xtemplate' in e.args[0]) - - def test_load_error_egg(self): - ttext = "{% load broken_egg %}" - egg_name = '%s/tagsegg.egg' % self.egg_dir - sys.path.append(egg_name) - settings.INSTALLED_APPS = ('tagsegg',) - self.assertRaises(template.TemplateSyntaxError, template.Template, ttext) - try: - template.Template(ttext) - except template.TemplateSyntaxError, e: - self.assertTrue('ImportError' in e.args[0]) - self.assertTrue('Xtemplate' in e.args[0]) - - def test_load_working_egg(self): - ttext = "{% load working_egg %}" - egg_name = '%s/tagsegg.egg' % self.egg_dir - sys.path.append(egg_name) - settings.INSTALLED_APPS = ('tagsegg',) - t = template.Template(ttext) - -if __name__ == "__main__": - unittest.main() diff --git a/parts/django/tests/regressiontests/templates/unicode.py b/parts/django/tests/regressiontests/templates/unicode.py deleted file mode 100644 index 05b0e22..0000000 --- a/parts/django/tests/regressiontests/templates/unicode.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase - -from django.template import Template, TemplateEncodingError, Context -from django.utils.safestring import SafeData - - -class UnicodeTests(TestCase): - def test_template(self): - # Templates can be created from unicode strings. - t1 = Template(u'ŠĐĆŽćžšđ {{ var }}') - # Templates can also be created from bytestrings. These are assumed to - # be 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' - self.assertRaises(TemplateEncodingError, Template, s) - - # 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 and - # "safe" objects as well, for auto-escaping purposes). - self.assertEqual(t1.render(c3), t2.render(c3)) - self.assertTrue(isinstance(t1.render(c3), unicode)) - self.assertTrue(isinstance(t1.render(c3), SafeData)) diff --git a/parts/django/tests/regressiontests/templates/urls.py b/parts/django/tests/regressiontests/templates/urls.py deleted file mode 100644 index 28d4133..0000000 --- a/parts/django/tests/regressiontests/templates/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding: utf-8 -from django.conf.urls.defaults import * -from regressiontests.templates import views - -urlpatterns = patterns('', - - # Test urls for testing reverse lookups - (r'^$', views.index), - (r'^client/([\d,]+)/$', views.client), - (r'^client/(?P<id>\d+)/(?P<action>[^/]+)/$', views.client_action), - (r'^client/(?P<client_id>\d+)/(?P<action>[^/]+)/$', views.client_action), - url(r'^named-client/(\d+)/$', views.client2, name="named.client"), - - # Unicode strings are permitted everywhere. - url(ur'^Юникод/(\w+)/$', views.client2, name=u"метка_оператора"), - url(ur'^Юникод/(?P<tag>\S+)/$', 'regressiontests.templates.views.client2', name=u"метка_оператора_2"), -) diff --git a/parts/django/tests/regressiontests/templates/views.py b/parts/django/tests/regressiontests/templates/views.py deleted file mode 100644 index ca3cecd..0000000 --- a/parts/django/tests/regressiontests/templates/views.py +++ /dev/null @@ -1,13 +0,0 @@ -# Fake views for testing url reverse lookup - -def index(request): - pass - -def client(request, id): - pass - -def client_action(request, id, action): - pass - -def client2(request, tag): - pass diff --git a/parts/django/tests/regressiontests/test_client_regress/__init__.py b/parts/django/tests/regressiontests/test_client_regress/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/test_client_regress/bad_templates/404.html b/parts/django/tests/regressiontests/test_client_regress/bad_templates/404.html deleted file mode 100644 index 816bcb9..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/bad_templates/404.html +++ /dev/null @@ -1,3 +0,0 @@ -{% block foo %} - -This template is deliberately bad - we want it to raise an exception when it is used. diff --git a/parts/django/tests/regressiontests/test_client_regress/fixtures/testdata.json b/parts/django/tests/regressiontests/test_client_regress/fixtures/testdata.json deleted file mode 100644 index 0dcf625..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/fixtures/testdata.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { - "pk": "1", - "model": "auth.user", - "fields": { - "username": "testclient", - "first_name": "Test", - "last_name": "Client", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "2", - "model": "auth.user", - "fields": { - "username": "inactive", - "first_name": "Inactive", - "last_name": "User", - "is_active": false, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "3", - "model": "auth.user", - "fields": { - "username": "staff", - "first_name": "Staff", - "last_name": "Member", - "is_active": true, - "is_superuser": false, - "is_staff": true, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - } -]
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/test_client_regress/models.py b/parts/django/tests/regressiontests/test_client_regress/models.py deleted file mode 100644 index 40c7623..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/models.py +++ /dev/null @@ -1,864 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Regression tests for the Test Client, especially the customized assertions. -""" -import os - -from django.conf import settings -from django.core.exceptions import SuspiciousOperation -from django.core.urlresolvers import reverse -from django.template import (TemplateDoesNotExist, TemplateSyntaxError, - Context, loader) -from django.test import TestCase, Client -from django.test.client import encode_file -from django.test.utils import ContextList - - -class AssertContainsTests(TestCase): - def setUp(self): - self.old_templates = settings.TEMPLATE_DIRS - settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'),) - - def tearDown(self): - settings.TEMPLATE_DIRS = self.old_templates - - def test_contains(self): - "Responses can be inspected for content, including counting repeated substrings" - response = self.client.get('/test_client_regress/no_template_view/') - - self.assertNotContains(response, 'never') - self.assertContains(response, 'never', 0) - self.assertContains(response, 'once') - self.assertContains(response, 'once', 1) - self.assertContains(response, 'twice') - self.assertContains(response, 'twice', 2) - - try: - self.assertContains(response, 'text', status_code=999) - except AssertionError, e: - self.assertEquals(str(e), "Couldn't retrieve page: Response code was 200 (expected 999)") - try: - self.assertContains(response, 'text', status_code=999, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Couldn't retrieve page: Response code was 200 (expected 999)") - - try: - self.assertNotContains(response, 'text', status_code=999) - except AssertionError, e: - self.assertEquals(str(e), "Couldn't retrieve page: Response code was 200 (expected 999)") - try: - self.assertNotContains(response, 'text', status_code=999, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Couldn't retrieve page: Response code was 200 (expected 999)") - - try: - self.assertNotContains(response, 'once') - except AssertionError, e: - self.assertEquals(str(e), "Response should not contain 'once'") - try: - self.assertNotContains(response, 'once', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Response should not contain 'once'") - - try: - self.assertContains(response, 'never', 1) - except AssertionError, e: - self.assertEquals(str(e), "Found 0 instances of 'never' in response (expected 1)") - try: - self.assertContains(response, 'never', 1, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Found 0 instances of 'never' in response (expected 1)") - - try: - self.assertContains(response, 'once', 0) - except AssertionError, e: - self.assertEquals(str(e), "Found 1 instances of 'once' in response (expected 0)") - try: - self.assertContains(response, 'once', 0, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Found 1 instances of 'once' in response (expected 0)") - - try: - self.assertContains(response, 'once', 2) - except AssertionError, e: - self.assertEquals(str(e), "Found 1 instances of 'once' in response (expected 2)") - try: - self.assertContains(response, 'once', 2, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Found 1 instances of 'once' in response (expected 2)") - - try: - self.assertContains(response, 'twice', 1) - except AssertionError, e: - self.assertEquals(str(e), "Found 2 instances of 'twice' in response (expected 1)") - try: - self.assertContains(response, 'twice', 1, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Found 2 instances of 'twice' in response (expected 1)") - - try: - self.assertContains(response, 'thrice') - except AssertionError, e: - self.assertEquals(str(e), "Couldn't find 'thrice' in response") - try: - self.assertContains(response, 'thrice', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Couldn't find 'thrice' in response") - - try: - self.assertContains(response, 'thrice', 3) - except AssertionError, e: - self.assertEquals(str(e), "Found 0 instances of 'thrice' in response (expected 3)") - try: - self.assertContains(response, 'thrice', 3, msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Found 0 instances of 'thrice' in response (expected 3)") - - def test_unicode_contains(self): - "Unicode characters can be found in template context" - #Regression test for #10183 - r = self.client.get('/test_client_regress/check_unicode/') - self.assertContains(r, u'さかき') - self.assertContains(r, '\xe5\xb3\xa0'.decode('utf-8')) - - def test_unicode_not_contains(self): - "Unicode characters can be searched for, and not found in template context" - #Regression test for #10183 - r = self.client.get('/test_client_regress/check_unicode/') - self.assertNotContains(r, u'はたけ') - self.assertNotContains(r, '\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8')) - - -class AssertTemplateUsedTests(TestCase): - fixtures = ['testdata.json'] - - def test_no_context(self): - "Template usage assertions work then templates aren't in use" - response = self.client.get('/test_client_regress/no_template_view/') - - # Check that the no template case doesn't mess with the template assertions - self.assertTemplateNotUsed(response, 'GET Template') - - try: - self.assertTemplateUsed(response, 'GET Template') - except AssertionError, e: - self.assertEquals(str(e), "No templates used to render the response") - - try: - self.assertTemplateUsed(response, 'GET Template', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: No templates used to render the response") - - def test_single_context(self): - "Template assertions work when there is a single context" - response = self.client.get('/test_client/post_view/', {}) - - try: - self.assertTemplateNotUsed(response, 'Empty GET Template') - except AssertionError, e: - self.assertEquals(str(e), "Template 'Empty GET Template' was used unexpectedly in rendering the response") - - try: - self.assertTemplateNotUsed(response, 'Empty GET Template', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Template 'Empty GET Template' was used unexpectedly in rendering the response") - - try: - self.assertTemplateUsed(response, 'Empty POST Template') - except AssertionError, e: - self.assertEquals(str(e), "Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template") - - try: - self.assertTemplateUsed(response, 'Empty POST Template', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template") - - def test_multiple_context(self): - "Template assertions work when there are multiple contexts" - post_data = { - 'text': 'Hello World', - 'email': 'foo@example.com', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view_with_template/', post_data) - self.assertContains(response, 'POST data OK') - try: - self.assertTemplateNotUsed(response, "form_view.html") - except AssertionError, e: - self.assertEquals(str(e), "Template 'form_view.html' was used unexpectedly in rendering the response") - - try: - self.assertTemplateNotUsed(response, 'base.html') - except AssertionError, e: - self.assertEquals(str(e), "Template 'base.html' was used unexpectedly in rendering the response") - - try: - self.assertTemplateUsed(response, "Valid POST Template") - except AssertionError, e: - self.assertEquals(str(e), "Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html") - -class AssertRedirectsTests(TestCase): - def test_redirect_page(self): - "An assertion is raised if the original page couldn't be retrieved as expected" - # This page will redirect with code 301, not 302 - response = self.client.get('/test_client/permanent_redirect_view/') - try: - self.assertRedirects(response, '/test_client/get_view/') - except AssertionError, e: - self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)") - - try: - self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 301 (expected 302)") - - def test_lost_query(self): - "An assertion is raised if the redirect location doesn't preserve GET parameters" - response = self.client.get('/test_client/redirect_view/', {'var': 'value'}) - try: - self.assertRedirects(response, '/test_client/get_view/') - except AssertionError, e: - self.assertEquals(str(e), "Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'") - - try: - self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'") - - def test_incorrect_target(self): - "An assertion is raised if the response redirects to another target" - response = self.client.get('/test_client/permanent_redirect_view/') - try: - # 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: Response code was 301 (expected 302)") - - def test_target_page(self): - "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 - self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/') - except AssertionError, e: - self.assertEquals(str(e), "Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)") - - try: - # The redirect target responds with a 301 code, not 200 - self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)") - - def test_redirect_chain(self): - "You can follow a redirect chain of multiple redirects" - response = self.client.get('/test_client_regress/redirects/further/more/', {}, follow=True) - self.assertRedirects(response, '/test_client_regress/no_template_view/', - status_code=301, target_status_code=200) - - self.assertEquals(len(response.redirect_chain), 1) - self.assertEquals(response.redirect_chain[0], ('http://testserver/test_client_regress/no_template_view/', 301)) - - def test_multiple_redirect_chain(self): - "You can follow a redirect chain of multiple redirects" - response = self.client.get('/test_client_regress/redirects/', {}, follow=True) - self.assertRedirects(response, '/test_client_regress/no_template_view/', - status_code=301, target_status_code=200) - - self.assertEquals(len(response.redirect_chain), 3) - self.assertEquals(response.redirect_chain[0], ('http://testserver/test_client_regress/redirects/further/', 301)) - self.assertEquals(response.redirect_chain[1], ('http://testserver/test_client_regress/redirects/further/more/', 301)) - self.assertEquals(response.redirect_chain[2], ('http://testserver/test_client_regress/no_template_view/', 301)) - - def test_redirect_chain_to_non_existent(self): - "You can follow a chain to a non-existent view" - response = self.client.get('/test_client_regress/redirect_to_non_existent_view2/', {}, follow=True) - self.assertRedirects(response, '/test_client_regress/non_existent_view/', - status_code=301, target_status_code=404) - - def test_redirect_chain_to_self(self): - "Redirections to self are caught and escaped" - response = self.client.get('/test_client_regress/redirect_to_self/', {}, follow=True) - # The chain of redirects stops once the cycle is detected. - self.assertRedirects(response, '/test_client_regress/redirect_to_self/', - status_code=301, target_status_code=301) - self.assertEquals(len(response.redirect_chain), 2) - - def test_circular_redirect(self): - "Circular redirect chains are caught and escaped" - response = self.client.get('/test_client_regress/circular_redirect_1/', {}, follow=True) - # The chain of redirects will get back to the starting point, but stop there. - self.assertRedirects(response, '/test_client_regress/circular_redirect_2/', - status_code=301, target_status_code=301) - self.assertEquals(len(response.redirect_chain), 4) - - def test_redirect_chain_post(self): - "A redirect chain will be followed from an initial POST post" - response = self.client.post('/test_client_regress/redirects/', - {'nothing': 'to_send'}, follow=True) - self.assertRedirects(response, - '/test_client_regress/no_template_view/', 301, 200) - self.assertEquals(len(response.redirect_chain), 3) - - def test_redirect_chain_head(self): - "A redirect chain will be followed from an initial HEAD request" - response = self.client.head('/test_client_regress/redirects/', - {'nothing': 'to_send'}, follow=True) - self.assertRedirects(response, - '/test_client_regress/no_template_view/', 301, 200) - self.assertEquals(len(response.redirect_chain), 3) - - def test_redirect_chain_options(self): - "A redirect chain will be followed from an initial OPTIONS request" - response = self.client.options('/test_client_regress/redirects/', - {'nothing': 'to_send'}, follow=True) - self.assertRedirects(response, - '/test_client_regress/no_template_view/', 301, 200) - self.assertEquals(len(response.redirect_chain), 3) - - def test_redirect_chain_put(self): - "A redirect chain will be followed from an initial PUT request" - response = self.client.put('/test_client_regress/redirects/', - {'nothing': 'to_send'}, follow=True) - self.assertRedirects(response, - '/test_client_regress/no_template_view/', 301, 200) - self.assertEquals(len(response.redirect_chain), 3) - - def test_redirect_chain_delete(self): - "A redirect chain will be followed from an initial DELETE request" - response = self.client.delete('/test_client_regress/redirects/', - {'nothing': 'to_send'}, follow=True) - self.assertRedirects(response, - '/test_client_regress/no_template_view/', 301, 200) - self.assertEquals(len(response.redirect_chain), 3) - - def test_redirect_chain_on_non_redirect_page(self): - "An assertion is raised if the original page couldn't be retrieved as expected" - # This page will redirect with code 301, not 302 - response = self.client.get('/test_client/get_view/', follow=True) - try: - self.assertRedirects(response, '/test_client/get_view/') - except AssertionError, e: - self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)") - - try: - self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)") - - def test_redirect_on_non_redirect_page(self): - "An assertion is raised if the original page couldn't be retrieved as expected" - # This page will redirect with code 301, not 302 - response = self.client.get('/test_client/get_view/') - try: - self.assertRedirects(response, '/test_client/get_view/') - except AssertionError, e: - self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)") - - try: - self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') - except AssertionError, e: - self.assertEquals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)") - - -class AssertFormErrorTests(TestCase): - def test_unknown_form(self): - "An assertion is raised if the form name is unknown" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - try: - self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.') - except AssertionError, e: - self.assertEqual(str(e), "The form 'wrong_form' was not used to render the response") - try: - self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.', msg_prefix='abc') - except AssertionError, e: - self.assertEqual(str(e), "abc: The form 'wrong_form' was not used to render the response") - - def test_unknown_field(self): - "An assertion is raised if the field name is unknown" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - try: - self.assertFormError(response, 'form', 'some_field', 'Some error.') - except AssertionError, e: - self.assertEqual(str(e), "The form 'form' in context 0 does not contain the field 'some_field'") - try: - self.assertFormError(response, 'form', 'some_field', 'Some error.', msg_prefix='abc') - except AssertionError, e: - self.assertEqual(str(e), "abc: The form 'form' in context 0 does not contain the field 'some_field'") - - def test_noerror_field(self): - "An assertion is raised if the field doesn't have any errors" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - try: - self.assertFormError(response, 'form', 'value', 'Some error.') - except AssertionError, e: - self.assertEqual(str(e), "The field 'value' on form 'form' in context 0 contains no errors") - try: - self.assertFormError(response, 'form', 'value', 'Some error.', msg_prefix='abc') - except AssertionError, e: - self.assertEqual(str(e), "abc: The field 'value' on form 'form' in context 0 contains no errors") - - def test_unknown_error(self): - "An assertion is raised if the field doesn't contain the provided error" - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - try: - self.assertFormError(response, 'form', 'email', 'Some error.') - 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.'])") - try: - self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc') - except AssertionError, e: - self.assertEqual(str(e), "abc: 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.'])") - - def test_unknown_nonfield_error(self): - """ - Checks that an assertion is raised if the form's non field errors - doesn't contain the provided error. - """ - post_data = { - 'text': 'Hello World', - 'email': 'not an email address', - 'value': 37, - 'single': 'b', - 'multi': ('b','c','e') - } - response = self.client.post('/test_client/form_view/', post_data) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "Invalid POST Template") - - try: - self.assertFormError(response, 'form', None, 'Some error.') - except AssertionError, e: - self.assertEqual(str(e), "The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )") - try: - self.assertFormError(response, 'form', None, 'Some error.', msg_prefix='abc') - except AssertionError, e: - self.assertEqual(str(e), "abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )") - -class LoginTests(TestCase): - fixtures = ['testdata'] - - def test_login_different_client(self): - "Check that using a different test client doesn't violate authentication" - - # Create a second client, and log in. - c = Client() - login = c.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Get a redirection page with the second client. - response = c.get("/test_client_regress/login_protected_redirect_view/") - - # At this points, the self.client isn't logged in. - # Check that assertRedirects uses the original client, not the - # default client. - self.assertRedirects(response, "http://testserver/test_client_regress/get_view/") - - -class SessionEngineTests(TestCase): - fixtures = ['testdata'] - - def setUp(self): - self.old_SESSION_ENGINE = settings.SESSION_ENGINE - settings.SESSION_ENGINE = 'regressiontests.test_client_regress.session' - - def tearDown(self): - settings.SESSION_ENGINE = self.old_SESSION_ENGINE - - def test_login(self): - "A session engine that modifies the session key can be used to log in" - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - - # Try to access a login protected page. - response = self.client.get("/test_client/login_protected_view/") - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['user'].username, 'testclient') - -class URLEscapingTests(TestCase): - def test_simple_argument_get(self): - "Get a view that has a simple string argument" - response = self.client.get(reverse('arg_view', args=['Slartibartfast'])) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'Howdy, Slartibartfast') - - def test_argument_with_space_get(self): - "Get a view that has a string argument that requires escaping" - response = self.client.get(reverse('arg_view', args=['Arthur Dent'])) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'Hi, Arthur') - - def test_simple_argument_post(self): - "Post for a view that has a simple string argument" - response = self.client.post(reverse('arg_view', args=['Slartibartfast'])) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'Howdy, Slartibartfast') - - def test_argument_with_space_post(self): - "Post for a view that has a string argument that requires escaping" - response = self.client.post(reverse('arg_view', args=['Arthur Dent'])) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'Hi, Arthur') - -class ExceptionTests(TestCase): - fixtures = ['testdata.json'] - - def test_exception_cleared(self): - "#5836 - A stale user exception isn't re-raised by the test client." - - login = self.client.login(username='testclient',password='password') - self.assertTrue(login, 'Could not log in') - try: - response = self.client.get("/test_client_regress/staff_only/") - self.fail("General users should not be able to visit this page") - except SuspiciousOperation: - pass - - # At this point, an exception has been raised, and should be cleared. - - # This next operation should be successful; if it isn't we have a problem. - login = self.client.login(username='staff', password='password') - self.assertTrue(login, 'Could not log in') - try: - self.client.get("/test_client_regress/staff_only/") - except SuspiciousOperation: - self.fail("Staff should be able to visit this page") - -class TemplateExceptionTests(TestCase): - def setUp(self): - # Reset the loaders so they don't try to render cached templates. - if loader.template_source_loaders is not None: - for template_loader in loader.template_source_loaders: - if hasattr(template_loader, 'reset'): - template_loader.reset() - self.old_templates = settings.TEMPLATE_DIRS - settings.TEMPLATE_DIRS = () - - def tearDown(self): - settings.TEMPLATE_DIRS = self.old_templates - - def test_no_404_template(self): - "Missing templates are correctly reported by test client" - try: - response = self.client.get("/no_such_view/") - self.fail("Should get error about missing template") - except TemplateDoesNotExist: - pass - - def test_bad_404_template(self): - "Errors found when rendering 404 error templates are re-raised" - settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'bad_templates'),) - try: - response = self.client.get("/no_such_view/") - self.fail("Should get error about syntax error in template") - except TemplateSyntaxError: - pass - -# We need two different tests to check URLconf substitution - one to check -# it was changed, and another one (without self.urls) to check it was reverted on -# teardown. This pair of tests relies upon the alphabetical ordering of test execution. -class UrlconfSubstitutionTests(TestCase): - urls = 'regressiontests.test_client_regress.urls' - - def test_urlconf_was_changed(self): - "TestCase can enforce a custom URLconf on a per-test basis" - url = reverse('arg_view', args=['somename']) - self.assertEquals(url, '/arg_view/somename/') - -# This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the -# name is to ensure alphabetical ordering. -class zzUrlconfSubstitutionTests(TestCase): - def test_urlconf_was_reverted(self): - "URLconf is reverted to original value after modification in a TestCase" - url = reverse('arg_view', args=['somename']) - self.assertEquals(url, '/test_client_regress/arg_view/somename/') - -class ContextTests(TestCase): - fixtures = ['testdata'] - - def test_single_context(self): - "Context variables can be retrieved from a single context" - response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'}) - self.assertEqual(response.context.__class__, Context) - self.assertTrue('get-foo' in response.context) - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['request-foo'], 'whiz') - self.assertEqual(response.context['data'], 'sausage') - - try: - response.context['does-not-exist'] - self.fail('Should not be able to retrieve non-existent key') - except KeyError, e: - self.assertEquals(e.args[0], 'does-not-exist') - - def test_inherited_context(self): - "Context variables can be retrieved from a list of contexts" - response = self.client.get("/test_client_regress/request_data_extended/", data={'foo':'whiz'}) - self.assertEqual(response.context.__class__, ContextList) - self.assertEqual(len(response.context), 2) - self.assertTrue('get-foo' in response.context) - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['request-foo'], 'whiz') - self.assertEqual(response.context['data'], 'bacon') - - try: - response.context['does-not-exist'] - self.fail('Should not be able to retrieve non-existent key') - except KeyError, e: - self.assertEquals(e.args[0], 'does-not-exist') - - -class SessionTests(TestCase): - fixtures = ['testdata.json'] - - def test_session(self): - "The session isn't lost if a user logs in" - # The session doesn't exist to start. - response = self.client.get('/test_client_regress/check_session/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'NO') - - # This request sets a session variable. - response = self.client.get('/test_client_regress/set_session/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'set_session') - - # Check that the session has been modified - response = self.client.get('/test_client_regress/check_session/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'YES') - - # Log in - login = self.client.login(username='testclient',password='password') - self.assertTrue(login, 'Could not log in') - - # Session should still contain the modified value - response = self.client.get('/test_client_regress/check_session/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'YES') - - def test_logout(self): - """Logout should work whether the user is logged in or not (#9978).""" - self.client.logout() - login = self.client.login(username='testclient',password='password') - self.assertTrue(login, 'Could not log in') - self.client.logout() - self.client.logout() - -class RequestMethodTests(TestCase): - def test_get(self): - "Request a view via request method GET" - response = self.client.get('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: GET') - - def test_post(self): - "Request a view via request method POST" - response = self.client.post('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: POST') - - def test_head(self): - "Request a view via request method HEAD" - response = self.client.head('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - # A HEAD request doesn't return any content. - self.assertNotEqual(response.content, 'request method: HEAD') - self.assertEqual(response.content, '') - - def test_options(self): - "Request a view via request method OPTIONS" - response = self.client.options('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: OPTIONS') - - def test_put(self): - "Request a view via request method PUT" - response = self.client.put('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: PUT') - - def test_delete(self): - "Request a view via request method DELETE" - response = self.client.delete('/test_client_regress/request_methods/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: DELETE') - -class RequestMethodStringDataTests(TestCase): - def test_post(self): - "Request a view with string data via request method POST" - # Regression test for #11371 - data = u'{"test": "json"}' - response = self.client.post('/test_client_regress/request_methods/', data=data, content_type='application/json') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: POST') - - def test_put(self): - "Request a view with string data via request method PUT" - # Regression test for #11371 - data = u'{"test": "json"}' - response = self.client.put('/test_client_regress/request_methods/', data=data, content_type='application/json') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'request method: PUT') - -class QueryStringTests(TestCase): - def test_get_like_requests(self): - for method_name in ('get','head','options','put','delete'): - # A GET-like request can pass a query string as data - method = getattr(self.client, method_name) - response = method("/test_client_regress/request_data/", data={'foo':'whiz'}) - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['request-foo'], 'whiz') - - # A GET-like request can pass a query string as part of the URL - response = method("/test_client_regress/request_data/?foo=whiz") - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['request-foo'], 'whiz') - - # Data provided in the URL to a GET-like request is overridden by actual form data - response = method("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'}) - self.assertEqual(response.context['get-foo'], 'bang') - self.assertEqual(response.context['request-foo'], 'bang') - - response = method("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'}) - self.assertEqual(response.context['get-foo'], None) - self.assertEqual(response.context['get-bar'], 'bang') - self.assertEqual(response.context['request-foo'], None) - self.assertEqual(response.context['request-bar'], 'bang') - - def test_post_like_requests(self): - # A POST-like request can pass a query string as data - response = self.client.post("/test_client_regress/request_data/", data={'foo':'whiz'}) - self.assertEqual(response.context['get-foo'], None) - self.assertEqual(response.context['post-foo'], 'whiz') - - # A POST-like request can pass a query string as part of the URL - response = self.client.post("/test_client_regress/request_data/?foo=whiz") - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['post-foo'], None) - self.assertEqual(response.context['request-foo'], 'whiz') - - # POST data provided in the URL augments actual form data - response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'}) - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['post-foo'], 'bang') - self.assertEqual(response.context['request-foo'], 'bang') - - response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'}) - self.assertEqual(response.context['get-foo'], 'whiz') - self.assertEqual(response.context['get-bar'], None) - self.assertEqual(response.context['post-foo'], None) - self.assertEqual(response.context['post-bar'], 'bang') - self.assertEqual(response.context['request-foo'], 'whiz') - self.assertEqual(response.context['request-bar'], 'bang') - -class UnicodePayloadTests(TestCase): - def test_simple_unicode_payload(self): - "A simple ASCII-only unicode JSON document can be POSTed" - # Regression test for #10571 - json = u'{"english": "mountain pass"}' - response = self.client.post("/test_client_regress/parse_unicode_json/", json, - content_type="application/json") - self.assertEqual(response.content, json) - - def test_unicode_payload_utf8(self): - "A non-ASCII unicode data encoded as UTF-8 can be POSTed" - # Regression test for #10571 - json = u'{"dog": "собака"}' - response = self.client.post("/test_client_regress/parse_unicode_json/", json, - content_type="application/json; charset=utf-8") - self.assertEqual(response.content, json.encode('utf-8')) - - def test_unicode_payload_utf16(self): - "A non-ASCII unicode data encoded as UTF-16 can be POSTed" - # Regression test for #10571 - json = u'{"dog": "собака"}' - response = self.client.post("/test_client_regress/parse_unicode_json/", json, - content_type="application/json; charset=utf-16") - self.assertEqual(response.content, json.encode('utf-16')) - - def test_unicode_payload_non_utf(self): - "A non-ASCII unicode data as a non-UTF based encoding can be POSTed" - #Regression test for #10571 - json = u'{"dog": "собака"}' - response = self.client.post("/test_client_regress/parse_unicode_json/", json, - content_type="application/json; charset=koi8-r") - self.assertEqual(response.content, json.encode('koi8-r')) - -class DummyFile(object): - def __init__(self, filename): - self.name = filename - def read(self): - return 'TEST_FILE_CONTENT' - -class UploadedFileEncodingTest(TestCase): - def test_file_encoding(self): - encoded_file = encode_file('TEST_BOUNDARY', 'TEST_KEY', DummyFile('test_name.bin')) - self.assertEqual('--TEST_BOUNDARY', encoded_file[0]) - self.assertEqual('Content-Disposition: form-data; name="TEST_KEY"; filename="test_name.bin"', encoded_file[1]) - self.assertEqual('TEST_FILE_CONTENT', encoded_file[-1]) - - def test_guesses_content_type_on_file_encoding(self): - self.assertEqual('Content-Type: application/octet-stream', - encode_file('IGNORE', 'IGNORE', DummyFile("file.bin"))[2]) - self.assertEqual('Content-Type: text/plain', - encode_file('IGNORE', 'IGNORE', DummyFile("file.txt"))[2]) - self.assertEqual('Content-Type: application/zip', - encode_file('IGNORE', 'IGNORE', DummyFile("file.zip"))[2]) - self.assertEqual('Content-Type: application/octet-stream', - encode_file('IGNORE', 'IGNORE', DummyFile("file.unknown"))[2]) - -class RequestHeadersTest(TestCase): - def test_client_headers(self): - "A test client can receive custom headers" - response = self.client.get("/test_client_regress/check_headers/", HTTP_X_ARG_CHECK='Testing 123') - self.assertEquals(response.content, "HTTP_X_ARG_CHECK: Testing 123") - self.assertEquals(response.status_code, 200) - - def test_client_headers_redirect(self): - "Test client headers are preserved through redirects" - response = self.client.get("/test_client_regress/check_headers_redirect/", follow=True, HTTP_X_ARG_CHECK='Testing 123') - self.assertEquals(response.content, "HTTP_X_ARG_CHECK: Testing 123") - self.assertRedirects(response, '/test_client_regress/check_headers/', - status_code=301, target_status_code=200) diff --git a/parts/django/tests/regressiontests/test_client_regress/session.py b/parts/django/tests/regressiontests/test_client_regress/session.py deleted file mode 100644 index 74ae3b6..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/session.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.contrib.sessions.backends.base import SessionBase - -class SessionStore(SessionBase): - """ - A simple cookie-based session storage implemenation. - - The session key is actually the session data, pickled and encoded. - This means that saving the session will change the session key. - """ - def __init__(self, session_key=None): - super(SessionStore, self).__init__(session_key) - - def exists(self, session_key): - return False - - def create(self): - self.session_key = self.encode({}) - - def save(self, must_create=False): - self.session_key = self.encode(self._session) - - def delete(self, session_key=None): - self.session_key = self.encode({}) - - def load(self): - try: - return self.decode(self.session_key) - except: - self.modified = True - return {}
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/test_client_regress/templates/unicode.html b/parts/django/tests/regressiontests/test_client_regress/templates/unicode.html deleted file mode 100644 index bdb6c91..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/templates/unicode.html +++ /dev/null @@ -1,5 +0,0 @@ -* 峠 (とうげ tōge "mountain pass") -* 榊 (さかき sakaki "tree, genus Cleyera") -* 辻 (つじ tsuji "crossroads, street") -* 働 (どう dō, はたら hatara(ku) "work") -* 腺 (せん sen, "gland") diff --git a/parts/django/tests/regressiontests/test_client_regress/urls.py b/parts/django/tests/regressiontests/test_client_regress/urls.py deleted file mode 100644 index 650d80b..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/urls.py +++ /dev/null @@ -1,29 +0,0 @@ -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'^staff_only/$', views.staff_only_view), - (r'^get_view/$', views.get_view), - (r'^request_data/$', views.request_data), - (r'^request_data_extended/$', views.request_data, {'template':'extended.html', 'data':'bacon'}), - url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'), - (r'^login_protected_redirect_view/$', views.login_protected_redirect_view), - (r'^redirects/$', redirect_to, {'url': '/test_client_regress/redirects/further/'}), - (r'^redirects/further/$', redirect_to, {'url': '/test_client_regress/redirects/further/more/'}), - (r'^redirects/further/more/$', redirect_to, {'url': '/test_client_regress/no_template_view/'}), - (r'^redirect_to_non_existent_view/$', redirect_to, {'url': '/test_client_regress/non_existent_view/'}), - (r'^redirect_to_non_existent_view2/$', redirect_to, {'url': '/test_client_regress/redirect_to_non_existent_view/'}), - (r'^redirect_to_self/$', redirect_to, {'url': '/test_client_regress/redirect_to_self/'}), - (r'^circular_redirect_1/$', redirect_to, {'url': '/test_client_regress/circular_redirect_2/'}), - (r'^circular_redirect_2/$', redirect_to, {'url': '/test_client_regress/circular_redirect_3/'}), - (r'^circular_redirect_3/$', redirect_to, {'url': '/test_client_regress/circular_redirect_1/'}), - (r'^set_session/$', views.set_session_view), - (r'^check_session/$', views.check_session_view), - (r'^request_methods/$', views.request_methods_view), - (r'^check_unicode/$', views.return_unicode), - (r'^parse_unicode_json/$', views.return_json_file), - (r'^check_headers/$', views.check_headers), - (r'^check_headers_redirect/$', redirect_to, {'url': '/test_client_regress/check_headers/'}), -) diff --git a/parts/django/tests/regressiontests/test_client_regress/views.py b/parts/django/tests/regressiontests/test_client_regress/views.py deleted file mode 100644 index 40aa61f..0000000 --- a/parts/django/tests/regressiontests/test_client_regress/views.py +++ /dev/null @@ -1,93 +0,0 @@ -from django.conf import settings -from django.contrib.auth.decorators import login_required -from django.http import HttpResponse, HttpResponseRedirect -from django.core.exceptions import SuspiciousOperation -from django.shortcuts import render_to_response -from django.utils import simplejson -from django.utils.encoding import smart_str -from django.core.serializers.json import DjangoJSONEncoder -from django.test.client import CONTENT_TYPE_RE - -def no_template_view(request): - "A simple view that expects a GET request, and returns a rendered template" - return HttpResponse("No template used. Sample content: twice once twice. Content ends.") - -def staff_only_view(request): - "A view that can only be visited by staff. Non staff members get an exception" - if request.user.is_staff: - return HttpResponse('') - else: - raise SuspiciousOperation() - -def get_view(request): - "A simple login protected view" - return HttpResponse("Hello world") -get_view = login_required(get_view) - -def request_data(request, template='base.html', data='sausage'): - "A simple view that returns the request data in the context" - return render_to_response(template, { - 'get-foo':request.GET.get('foo',None), - 'get-bar':request.GET.get('bar',None), - 'post-foo':request.POST.get('foo',None), - 'post-bar':request.POST.get('bar',None), - 'request-foo':request.REQUEST.get('foo',None), - 'request-bar':request.REQUEST.get('bar',None), - 'data': data, - }) - -def view_with_argument(request, name): - """A view that takes a string argument - - The purpose of this view is to check that if a space is provided in - the argument, the test framework unescapes the %20 before passing - the value to the view. - """ - if name == 'Arthur Dent': - return HttpResponse('Hi, Arthur') - else: - return HttpResponse('Howdy, %s' % name) - -def login_protected_redirect_view(request): - "A view that redirects all requests to the GET view" - return HttpResponseRedirect('/test_client_regress/get_view/') -login_protected_redirect_view = login_required(login_protected_redirect_view) - -def set_session_view(request): - "A view that sets a session variable" - request.session['session_var'] = 'YES' - return HttpResponse('set_session') - -def check_session_view(request): - "A view that reads a session variable" - return HttpResponse(request.session.get('session_var', 'NO')) - -def request_methods_view(request): - "A view that responds with the request method" - return HttpResponse('request method: %s' % request.method) - -def return_unicode(request): - return render_to_response('unicode.html') - -def return_json_file(request): - "A view that parses and returns a JSON string as a file." - match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE']) - if match: - charset = match.group(1) - else: - charset = settings.DEFAULT_CHARSET - - # This just checks that the uploaded data is JSON - obj_dict = simplejson.loads(request.raw_post_data.decode(charset)) - obj_json = simplejson.dumps(obj_dict, encoding=charset, - cls=DjangoJSONEncoder, - ensure_ascii=False) - response = HttpResponse(smart_str(obj_json, encoding=charset), status=200, - mimetype='application/json; charset=' + charset) - response['Content-Disposition'] = 'attachment; filename=testfile.json' - return response - -def check_headers(request): - "A view that responds with value of the X-ARG-CHECK header" - return HttpResponse('HTTP_X_ARG_CHECK: %s' % request.META.get('HTTP_X_ARG_CHECK', 'Undefined')) - diff --git a/parts/django/tests/regressiontests/test_runner/__init__.py b/parts/django/tests/regressiontests/test_runner/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/test_runner/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/test_runner/models.py b/parts/django/tests/regressiontests/test_runner/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/test_runner/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/test_runner/tests.py b/parts/django/tests/regressiontests/test_runner/tests.py deleted file mode 100644 index 3387d65..0000000 --- a/parts/django/tests/regressiontests/test_runner/tests.py +++ /dev/null @@ -1,120 +0,0 @@ -""" -Tests for django test runner -""" -import StringIO -import unittest -import django -from django.core.exceptions import ImproperlyConfigured -from django.test import simple - -class DjangoTestRunnerTests(unittest.TestCase): - - def test_failfast(self): - class MockTestOne(unittest.TestCase): - def runTest(self): - assert False - class MockTestTwo(unittest.TestCase): - def runTest(self): - assert False - - suite = unittest.TestSuite([MockTestOne(), MockTestTwo()]) - mock_stream = StringIO.StringIO() - dtr = simple.DjangoTestRunner(verbosity=0, failfast=False, stream=mock_stream) - result = dtr.run(suite) - self.assertEqual(2, result.testsRun) - self.assertEqual(2, len(result.failures)) - - dtr = simple.DjangoTestRunner(verbosity=0, failfast=True, stream=mock_stream) - result = dtr.run(suite) - self.assertEqual(1, result.testsRun) - self.assertEqual(1, len(result.failures)) - -class DependencyOrderingTests(unittest.TestCase): - - def test_simple_dependencies(self): - raw = [ - ('s1', ['alpha']), - ('s2', ['bravo']), - ('s3', ['charlie']), - ] - dependencies = { - 'alpha': ['charlie'], - 'bravo': ['charlie'], - } - - ordered = simple.dependency_ordered(raw, dependencies=dependencies) - ordered_sigs = [sig for sig,aliases in ordered] - - self.assertTrue('s1' in ordered_sigs) - self.assertTrue('s2' in ordered_sigs) - self.assertTrue('s3' in ordered_sigs) - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s1')) - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s2')) - - def test_chained_dependencies(self): - raw = [ - ('s1', ['alpha']), - ('s2', ['bravo']), - ('s3', ['charlie']), - ] - dependencies = { - 'alpha': ['bravo'], - 'bravo': ['charlie'], - } - - ordered = simple.dependency_ordered(raw, dependencies=dependencies) - ordered_sigs = [sig for sig,aliases in ordered] - - self.assertTrue('s1' in ordered_sigs) - self.assertTrue('s2' in ordered_sigs) - self.assertTrue('s3' in ordered_sigs) - - # Explicit dependencies - self.assertTrue(ordered_sigs.index('s2') < ordered_sigs.index('s1')) - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s2')) - - # Implied dependencies - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s1')) - - def test_multiple_dependencies(self): - raw = [ - ('s1', ['alpha']), - ('s2', ['bravo']), - ('s3', ['charlie']), - ('s4', ['delta']), - ] - dependencies = { - 'alpha': ['bravo','delta'], - 'bravo': ['charlie'], - 'delta': ['charlie'], - } - - ordered = simple.dependency_ordered(raw, dependencies=dependencies) - ordered_sigs = [sig for sig,aliases in ordered] - - self.assertTrue('s1' in ordered_sigs) - self.assertTrue('s2' in ordered_sigs) - self.assertTrue('s3' in ordered_sigs) - self.assertTrue('s4' in ordered_sigs) - - # Explicit dependencies - self.assertTrue(ordered_sigs.index('s2') < ordered_sigs.index('s1')) - self.assertTrue(ordered_sigs.index('s4') < ordered_sigs.index('s1')) - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s2')) - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s4')) - - # Implicit dependencies - self.assertTrue(ordered_sigs.index('s3') < ordered_sigs.index('s1')) - - def test_circular_dependencies(self): - raw = [ - ('s1', ['alpha']), - ('s2', ['bravo']), - ] - dependencies = { - 'bravo': ['alpha'], - 'alpha': ['bravo'], - } - - self.assertRaises(ImproperlyConfigured, simple.dependency_ordered, raw, dependencies=dependencies) - diff --git a/parts/django/tests/regressiontests/test_utils/__init__.py b/parts/django/tests/regressiontests/test_utils/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/test_utils/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/test_utils/models.py b/parts/django/tests/regressiontests/test_utils/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/test_utils/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/test_utils/tests.py b/parts/django/tests/regressiontests/test_utils/tests.py deleted file mode 100644 index a2539bf..0000000 --- a/parts/django/tests/regressiontests/test_utils/tests.py +++ /dev/null @@ -1,72 +0,0 @@ -r""" -# Some checks of the doctest output normalizer. -# Standard doctests do fairly ->>> from django.utils import simplejson ->>> from django.utils.xmlutils import SimplerXMLGenerator ->>> from StringIO import StringIO - ->>> def produce_long(): -... return 42L - ->>> def produce_int(): -... return 42 - ->>> def produce_json(): -... return simplejson.dumps(['foo', {'bar': ('baz', None, 1.0, 2), 'whiz': 42}]) - ->>> def produce_xml(): -... stream = StringIO() -... xml = SimplerXMLGenerator(stream, encoding='utf-8') -... xml.startDocument() -... xml.startElement("foo", {"aaa" : "1.0", "bbb": "2.0"}) -... xml.startElement("bar", {"ccc" : "3.0"}) -... xml.characters("Hello") -... xml.endElement("bar") -... xml.startElement("whiz", {}) -... xml.characters("Goodbye") -... xml.endElement("whiz") -... xml.endElement("foo") -... xml.endDocument() -... return stream.getvalue() - ->>> def produce_xml_fragment(): -... stream = StringIO() -... xml = SimplerXMLGenerator(stream, encoding='utf-8') -... xml.startElement("foo", {"aaa": "1.0", "bbb": "2.0"}) -... xml.characters("Hello") -... xml.endElement("foo") -... xml.startElement("bar", {"ccc": "3.0", "ddd": "4.0"}) -... xml.endElement("bar") -... return stream.getvalue() - -# Long values are normalized and are comparable to normal integers ... ->>> produce_long() -42 - -# ... and vice versa ->>> produce_int() -42L - -# JSON output is normalized for field order, so it doesn't matter -# which order json dictionary attributes are listed in output ->>> produce_json() -'["foo", {"bar": ["baz", null, 1.0, 2], "whiz": 42}]' - ->>> produce_json() -'["foo", {"whiz": 42, "bar": ["baz", null, 1.0, 2]}]' - -# XML output is normalized for attribute order, so it doesn't matter -# which order XML element attributes are listed in output ->>> produce_xml() -'<?xml version="1.0" encoding="UTF-8"?>\n<foo aaa="1.0" bbb="2.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>' - ->>> produce_xml() -'<?xml version="1.0" encoding="UTF-8"?>\n<foo bbb="2.0" aaa="1.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>' - ->>> produce_xml_fragment() -'<foo aaa="1.0" bbb="2.0">Hello</foo><bar ccc="3.0" ddd="4.0"></bar>' - ->>> produce_xml_fragment() -'<foo bbb="2.0" aaa="1.0">Hello</foo><bar ddd="4.0" ccc="3.0"></bar>' - -"""
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/text/__init__.py b/parts/django/tests/regressiontests/text/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/text/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/text/models.py b/parts/django/tests/regressiontests/text/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/text/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/text/tests.py b/parts/django/tests/regressiontests/text/tests.py deleted file mode 100644 index fd02036..0000000 --- a/parts/django/tests/regressiontests/text/tests.py +++ /dev/null @@ -1,81 +0,0 @@ -# coding: utf-8 -from django.test import TestCase - -from django.utils.text import * -from django.utils.http import urlquote, urlquote_plus, cookie_date, http_date -from django.utils.encoding import iri_to_uri - -class TextTests(TestCase): - """ - Tests for stuff in django.utils.text and other text munging util functions. - """ - - def test_smart_split(self): - - self.assertEquals(list(smart_split(r'''This is "a person" test.''')), - [u'This', u'is', u'"a person"', u'test.']) - - self.assertEquals(list(smart_split(r'''This is "a person's" test.'''))[2], - u'"a person\'s"') - - self.assertEquals(list(smart_split(r'''This is "a person\"s" test.'''))[2], - u'"a person\\"s"') - - self.assertEquals(list(smart_split('''"a 'one''')), [u'"a', u"'one"]) - - self.assertEquals(list(smart_split(r'''all friends' tests'''))[1], - "friends'") - - self.assertEquals(list(smart_split(u'url search_page words="something else"')), - [u'url', u'search_page', u'words="something else"']) - - self.assertEquals(list(smart_split(u"url search_page words='something else'")), - [u'url', u'search_page', u"words='something else'"]) - - self.assertEquals(list(smart_split(u'url search_page words "something else"')), - [u'url', u'search_page', u'words', u'"something else"']) - - self.assertEquals(list(smart_split(u'url search_page words-"something else"')), - [u'url', u'search_page', u'words-"something else"']) - - self.assertEquals(list(smart_split(u'url search_page words=hello')), - [u'url', u'search_page', u'words=hello']) - - self.assertEquals(list(smart_split(u'url search_page words="something else')), - [u'url', u'search_page', u'words="something', u'else']) - - self.assertEquals(list(smart_split("cut:','|cut:' '")), - [u"cut:','|cut:' '"]) - - def test_urlquote(self): - - self.assertEquals(urlquote(u'Paris & Orl\xe9ans'), - u'Paris%20%26%20Orl%C3%A9ans') - self.assertEquals(urlquote(u'Paris & Orl\xe9ans', safe="&"), - u'Paris%20&%20Orl%C3%A9ans') - self.assertEquals(urlquote_plus(u'Paris & Orl\xe9ans'), - u'Paris+%26+Orl%C3%A9ans') - self.assertEquals(urlquote_plus(u'Paris & Orl\xe9ans', safe="&"), - u'Paris+&+Orl%C3%A9ans') - - def test_cookie_date(self): - t = 1167616461.0 - self.assertEquals(cookie_date(t), 'Mon, 01-Jan-2007 01:54:21 GMT') - - def test_http_date(self): - t = 1167616461.0 - self.assertEquals(http_date(t), 'Mon, 01 Jan 2007 01:54:21 GMT') - - def test_iri_to_uri(self): - self.assertEquals(iri_to_uri(u'red%09ros\xe9#red'), - 'red%09ros%C3%A9#red') - - self.assertEquals(iri_to_uri(u'/blog/for/J\xfcrgen M\xfcnster/'), - '/blog/for/J%C3%BCrgen%20M%C3%BCnster/') - - self.assertEquals(iri_to_uri(u'locations/%s' % urlquote_plus(u'Paris & Orl\xe9ans')), - 'locations/Paris+%26+Orl%C3%A9ans') - - def test_iri_to_uri_idempotent(self): - self.assertEquals(iri_to_uri(iri_to_uri(u'red%09ros\xe9#red')), - 'red%09ros%C3%A9#red') diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/__init__.py b/parts/django/tests/regressiontests/urlpatterns_reverse/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/extra_urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/extra_urls.py deleted file mode 100644 index c171f6d..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/extra_urls.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Some extra URL patterns that are included at the top level. -""" - -from django.conf.urls.defaults import * -from views import empty_view - -urlpatterns = patterns('', - url(r'^e-places/(\d+)/$', empty_view, name='extra-places'), - url(r'^e-people/(?P<name>\w+)/$', empty_view, name="extra-people"), - url('', include('regressiontests.urlpatterns_reverse.included_urls2')), - url(r'^prefix/(?P<prefix>\w+)/', include('regressiontests.urlpatterns_reverse.included_urls2')), -) diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py deleted file mode 100644 index 0731906..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.conf.urls.defaults import * -from namespace_urls import URLObject - -testobj3 = URLObject('testapp', 'test-ns3') - -urlpatterns = patterns('regressiontests.urlpatterns_reverse.views', - url(r'^normal/$', 'empty_view', name='inc-normal-view'), - url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='inc-normal-view'), - - (r'^test3/', include(testobj3.urls)), - (r'^ns-included3/', include('regressiontests.urlpatterns_reverse.included_urls', namespace='inc-ns3')), -) - diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls.py deleted file mode 100644 index f8acf34..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.conf.urls.defaults import * -from views import empty_view - -urlpatterns = patterns('', - url(r'^$', empty_view, name="inner-nothing"), - url(r'^extra/(?P<extra>\w+)/$', empty_view, name="inner-extra"), - url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view, name="inner-disjunction"), -) diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls2.py b/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls2.py deleted file mode 100644 index f414ca6..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/included_urls2.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -These URL patterns are included in two different ways in the main urls.py, with -an extra argument present in one case. Thus, there are two different ways for -each name to resolve and Django must distinguish the possibilities based on the -argument list. -""" - -from django.conf.urls.defaults import * -from views import empty_view - -urlpatterns = patterns('', - url(r'^part/(?P<value>\w+)/$', empty_view, name="part"), - url(r'^part2/(?:(?P<value>\w+)/)?$', empty_view, name="part2"), -) diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/middleware.py b/parts/django/tests/regressiontests/urlpatterns_reverse/middleware.py deleted file mode 100644 index cd3c045..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/middleware.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.core.urlresolvers import set_urlconf - -import urlconf_inner - -class ChangeURLconfMiddleware(object): - def process_request(self, request): - request.urlconf = urlconf_inner.__name__ - -class NullChangeURLconfMiddleware(object): - def process_request(self, request): - request.urlconf = None diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/models.py b/parts/django/tests/regressiontests/urlpatterns_reverse/models.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/models.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/namespace_urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/namespace_urls.py deleted file mode 100644 index 27cc7f7..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/namespace_urls.py +++ /dev/null @@ -1,38 +0,0 @@ -from django.conf.urls.defaults import * - -class URLObject(object): - def __init__(self, app_name, namespace): - self.app_name = app_name - self.namespace = namespace - - def urls(self): - return patterns('', - url(r'^inner/$', 'empty_view', name='urlobject-view'), - url(r'^inner/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='urlobject-view'), - ), self.app_name, self.namespace - urls = property(urls) - -testobj1 = URLObject('testapp', 'test-ns1') -testobj2 = URLObject('testapp', 'test-ns2') -default_testobj = URLObject('testapp', 'testapp') - -otherobj1 = URLObject('nodefault', 'other-ns1') -otherobj2 = URLObject('nodefault', 'other-ns2') - -urlpatterns = patterns('regressiontests.urlpatterns_reverse.views', - url(r'^normal/$', 'empty_view', name='normal-view'), - url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='normal-view'), - - (r'^test1/', include(testobj1.urls)), - (r'^test2/', include(testobj2.urls)), - (r'^default/', include(default_testobj.urls)), - - (r'^other1/', include(otherobj1.urls)), - (r'^other2/', include(otherobj2.urls)), - - (r'^ns-included1/', include('regressiontests.urlpatterns_reverse.included_namespace_urls', namespace='inc-ns1')), - (r'^ns-included2/', include('regressiontests.urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')), - - (r'^included/', include('regressiontests.urlpatterns_reverse.included_namespace_urls')), - -) diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/no_urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/no_urls.py deleted file mode 100644 index c9b9efe..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/no_urls.py +++ /dev/null @@ -1,2 +0,0 @@ -#from django.conf.urls.defaults import * - diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/tests.py b/parts/django/tests/regressiontests/urlpatterns_reverse/tests.py deleted file mode 100644 index d0b7146..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/tests.py +++ /dev/null @@ -1,330 +0,0 @@ -""" -Unit tests for reverse URL lookups. -""" -import unittest - -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.core.urlresolvers import reverse, resolve, NoReverseMatch, Resolver404, RegexURLResolver -from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect -from django.shortcuts import redirect -from django.test import TestCase - -import urlconf_outer -import urlconf_inner -import middleware - -test_data = ( - ('places', '/places/3/', [3], {}), - ('places', '/places/3/', ['3'], {}), - ('places', NoReverseMatch, ['a'], {}), - ('places', NoReverseMatch, [], {}), - ('places?', '/place/', [], {}), - ('places+', '/places/', [], {}), - ('places*', '/place/', [], {}), - ('places2?', '/', [], {}), - ('places2+', '/places/', [], {}), - ('places2*', '/', [], {}), - ('places3', '/places/4/', [4], {}), - ('places3', '/places/harlem/', ['harlem'], {}), - ('places3', NoReverseMatch, ['harlem64'], {}), - ('places4', '/places/3/', [], {'id': 3}), - ('people', NoReverseMatch, [], {}), - ('people', '/people/adrian/', ['adrian'], {}), - ('people', '/people/adrian/', [], {'name': 'adrian'}), - ('people', NoReverseMatch, ['name with spaces'], {}), - ('people', NoReverseMatch, [], {'name': 'name with spaces'}), - ('people2', '/people/name/', [], {}), - ('people2a', '/people/name/fred/', ['fred'], {}), - ('optional', '/optional/fred/', [], {'name': 'fred'}), - ('optional', '/optional/fred/', ['fred'], {}), - ('hardcoded', '/hardcoded/', [], {}), - ('hardcoded2', '/hardcoded/doc.pdf', [], {}), - ('people3', '/people/il/adrian/', [], {'state': 'il', 'name': 'adrian'}), - ('people3', NoReverseMatch, [], {'state': 'il'}), - ('people3', NoReverseMatch, [], {'name': 'adrian'}), - ('people4', NoReverseMatch, [], {'state': 'il', 'name': 'adrian'}), - ('people6', '/people/il/test/adrian/', ['il/test', 'adrian'], {}), - ('people6', '/people//adrian/', ['adrian'], {}), - ('range', '/character_set/a/', [], {}), - ('range2', '/character_set/x/', [], {}), - ('price', '/price/$10/', ['10'], {}), - ('price2', '/price/$10/', ['10'], {}), - ('price3', '/price/$10/', ['10'], {}), - ('product', '/product/chocolate+($2.00)/', [], {'price': '2.00', 'product': 'chocolate'}), - ('headlines', '/headlines/2007.5.21/', [], dict(year=2007, month=5, day=21)), - ('windows', r'/windows_path/C:%5CDocuments%20and%20Settings%5Cspam/', [], dict(drive_name='C', path=r'Documents and Settings\spam')), - ('special', r'/special_chars/+%5C$*/', [r'+\$*'], {}), - ('special', NoReverseMatch, [''], {}), - ('mixed', '/john/0/', [], {'name': 'john'}), - ('repeats', '/repeats/a/', [], {}), - ('repeats2', '/repeats/aa/', [], {}), - ('repeats3', '/repeats/aa/', [], {}), - ('insensitive', '/CaseInsensitive/fred', ['fred'], {}), - ('test', '/test/1', [], {}), - ('test2', '/test/2', [], {}), - ('inner-nothing', '/outer/42/', [], {'outer': '42'}), - ('inner-nothing', '/outer/42/', ['42'], {}), - ('inner-nothing', NoReverseMatch, ['foo'], {}), - ('inner-extra', '/outer/42/extra/inner/', [], {'extra': 'inner', 'outer': '42'}), - ('inner-extra', '/outer/42/extra/inner/', ['42', 'inner'], {}), - ('inner-extra', NoReverseMatch, ['fred', 'inner'], {}), - ('disjunction', NoReverseMatch, ['foo'], {}), - ('inner-disjunction', NoReverseMatch, ['10', '11'], {}), - ('extra-places', '/e-places/10/', ['10'], {}), - ('extra-people', '/e-people/fred/', ['fred'], {}), - ('extra-people', '/e-people/fred/', [], {'name': 'fred'}), - ('part', '/part/one/', [], {'value': 'one'}), - ('part', '/prefix/xx/part/one/', [], {'value': 'one', 'prefix': 'xx'}), - ('part2', '/part2/one/', [], {'value': 'one'}), - ('part2', '/part2/', [], {}), - ('part2', '/prefix/xx/part2/one/', [], {'value': 'one', 'prefix': 'xx'}), - ('part2', '/prefix/xx/part2/', [], {'prefix': 'xx'}), - - # Regression for #9038 - # These views are resolved by method name. Each method is deployed twice - - # once with an explicit argument, and once using the default value on - # the method. This is potentially ambiguous, as you have to pick the - # correct view for the arguments provided. - ('kwargs_view', '/arg_view/', [], {}), - ('kwargs_view', '/arg_view/10/', [], {'arg1':10}), - ('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/', [], {}), - ('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/10/', [], {'arg1':10}), - ('non_path_include', '/includes/non_path_include/', [], {}) - -) - -class NoURLPatternsTests(TestCase): - urls = 'regressiontests.urlpatterns_reverse.no_urls' - - def assertRaisesErrorWithMessage(self, error, message, callable, - *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - def test_no_urls_exception(self): - """ - RegexURLResolver should raise an exception when no urlpatterns exist. - """ - resolver = RegexURLResolver(r'^$', self.urls) - - self.assertRaisesErrorWithMessage(ImproperlyConfigured, - "The included urlconf regressiontests.urlpatterns_reverse.no_urls "\ - "doesn't have any patterns in it", getattr, resolver, 'url_patterns') - -class URLPatternReverse(TestCase): - urls = 'regressiontests.urlpatterns_reverse.urls' - - def test_urlpattern_reverse(self): - for name, expected, args, kwargs in test_data: - try: - got = reverse(name, args=args, kwargs=kwargs) - except NoReverseMatch, e: - self.assertEqual(expected, NoReverseMatch) - else: - self.assertEquals(got, expected) - - def test_reverse_none(self): - # Reversing None should raise an error, not return the last un-named view. - self.assertRaises(NoReverseMatch, reverse, None) - -class ResolverTests(unittest.TestCase): - def test_non_regex(self): - """ - Verifies that we raise a Resolver404 if what we are resolving doesn't - meet the basic requirements of a path to match - i.e., at the very - least, it matches the root pattern '^/'. We must never return None - from resolve, or we will get a TypeError further down the line. - - Regression for #10834. - """ - self.assertRaises(Resolver404, resolve, '') - self.assertRaises(Resolver404, resolve, 'a') - self.assertRaises(Resolver404, resolve, '\\') - self.assertRaises(Resolver404, resolve, '.') - -class ReverseShortcutTests(TestCase): - urls = 'regressiontests.urlpatterns_reverse.urls' - - def test_redirect_to_object(self): - # We don't really need a model; just something with a get_absolute_url - class FakeObj(object): - def get_absolute_url(self): - return "/hi-there/" - - res = redirect(FakeObj()) - self.assert_(isinstance(res, HttpResponseRedirect)) - self.assertEqual(res['Location'], '/hi-there/') - - res = redirect(FakeObj(), permanent=True) - self.assert_(isinstance(res, HttpResponsePermanentRedirect)) - self.assertEqual(res['Location'], '/hi-there/') - - def test_redirect_to_view_name(self): - res = redirect('hardcoded2') - self.assertEqual(res['Location'], '/hardcoded/doc.pdf') - res = redirect('places', 1) - self.assertEqual(res['Location'], '/places/1/') - res = redirect('headlines', year='2008', month='02', day='17') - self.assertEqual(res['Location'], '/headlines/2008.02.17/') - self.assertRaises(NoReverseMatch, redirect, 'not-a-view') - - def test_redirect_to_url(self): - res = redirect('/foo/') - self.assertEqual(res['Location'], '/foo/') - res = redirect('http://example.com/') - self.assertEqual(res['Location'], 'http://example.com/') - - def test_redirect_view_object(self): - from views import absolute_kwargs_view - res = redirect(absolute_kwargs_view) - self.assertEqual(res['Location'], '/absolute_arg_view/') - self.assertRaises(NoReverseMatch, redirect, absolute_kwargs_view, wrong_argument=None) - - -class NamespaceTests(TestCase): - urls = 'regressiontests.urlpatterns_reverse.namespace_urls' - - def test_ambiguous_object(self): - "Names deployed via dynamic URL objects that require namespaces can't be resolved" - self.assertRaises(NoReverseMatch, reverse, 'urlobject-view') - self.assertRaises(NoReverseMatch, reverse, 'urlobject-view', args=[37,42]) - self.assertRaises(NoReverseMatch, reverse, 'urlobject-view', kwargs={'arg1':42, 'arg2':37}) - - def test_ambiguous_urlpattern(self): - "Names deployed via dynamic URL objects that require namespaces can't be resolved" - self.assertRaises(NoReverseMatch, reverse, 'inner-nothing') - self.assertRaises(NoReverseMatch, reverse, 'inner-nothing', args=[37,42]) - self.assertRaises(NoReverseMatch, reverse, 'inner-nothing', kwargs={'arg1':42, 'arg2':37}) - - def test_non_existent_namespace(self): - "Non-existent namespaces raise errors" - self.assertRaises(NoReverseMatch, reverse, 'blahblah:urlobject-view') - self.assertRaises(NoReverseMatch, reverse, 'test-ns1:blahblah:urlobject-view') - - def test_normal_name(self): - "Normal lookups work as expected" - self.assertEquals('/normal/', reverse('normal-view')) - self.assertEquals('/normal/37/42/', reverse('normal-view', args=[37,42])) - self.assertEquals('/normal/42/37/', reverse('normal-view', kwargs={'arg1':42, 'arg2':37})) - - def test_simple_included_name(self): - "Normal lookups work on names included from other patterns" - self.assertEquals('/included/normal/', reverse('inc-normal-view')) - self.assertEquals('/included/normal/37/42/', reverse('inc-normal-view', args=[37,42])) - self.assertEquals('/included/normal/42/37/', reverse('inc-normal-view', kwargs={'arg1':42, 'arg2':37})) - - def test_namespace_object(self): - "Dynamic URL objects can be found using a namespace" - self.assertEquals('/test1/inner/', reverse('test-ns1:urlobject-view')) - self.assertEquals('/test1/inner/37/42/', reverse('test-ns1:urlobject-view', args=[37,42])) - self.assertEquals('/test1/inner/42/37/', reverse('test-ns1:urlobject-view', kwargs={'arg1':42, 'arg2':37})) - - def test_embedded_namespace_object(self): - "Namespaces can be installed anywhere in the URL pattern tree" - self.assertEquals('/included/test3/inner/', reverse('test-ns3:urlobject-view')) - self.assertEquals('/included/test3/inner/37/42/', reverse('test-ns3:urlobject-view', args=[37,42])) - self.assertEquals('/included/test3/inner/42/37/', reverse('test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37})) - - def test_namespace_pattern(self): - "Namespaces can be applied to include()'d urlpatterns" - self.assertEquals('/ns-included1/normal/', reverse('inc-ns1:inc-normal-view')) - self.assertEquals('/ns-included1/normal/37/42/', reverse('inc-ns1:inc-normal-view', args=[37,42])) - self.assertEquals('/ns-included1/normal/42/37/', reverse('inc-ns1:inc-normal-view', kwargs={'arg1':42, 'arg2':37})) - - def test_multiple_namespace_pattern(self): - "Namespaces can be embedded" - self.assertEquals('/ns-included1/test3/inner/', reverse('inc-ns1:test-ns3:urlobject-view')) - self.assertEquals('/ns-included1/test3/inner/37/42/', reverse('inc-ns1:test-ns3:urlobject-view', args=[37,42])) - self.assertEquals('/ns-included1/test3/inner/42/37/', reverse('inc-ns1:test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37})) - - def test_app_lookup_object(self): - "A default application namespace can be used for lookup" - self.assertEquals('/default/inner/', reverse('testapp:urlobject-view')) - self.assertEquals('/default/inner/37/42/', reverse('testapp:urlobject-view', args=[37,42])) - self.assertEquals('/default/inner/42/37/', reverse('testapp:urlobject-view', kwargs={'arg1':42, 'arg2':37})) - - def test_app_lookup_object_with_default(self): - "A default application namespace is sensitive to the 'current' app can be used for lookup" - self.assertEquals('/included/test3/inner/', reverse('testapp:urlobject-view', current_app='test-ns3')) - self.assertEquals('/included/test3/inner/37/42/', reverse('testapp:urlobject-view', args=[37,42], current_app='test-ns3')) - self.assertEquals('/included/test3/inner/42/37/', reverse('testapp:urlobject-view', kwargs={'arg1':42, 'arg2':37}, current_app='test-ns3')) - - def test_app_lookup_object_without_default(self): - "An application namespace without a default is sensitive to the 'current' app can be used for lookup" - self.assertEquals('/other2/inner/', reverse('nodefault:urlobject-view')) - self.assertEquals('/other2/inner/37/42/', reverse('nodefault:urlobject-view', args=[37,42])) - self.assertEquals('/other2/inner/42/37/', reverse('nodefault:urlobject-view', kwargs={'arg1':42, 'arg2':37})) - - self.assertEquals('/other1/inner/', reverse('nodefault:urlobject-view', current_app='other-ns1')) - self.assertEquals('/other1/inner/37/42/', reverse('nodefault:urlobject-view', args=[37,42], current_app='other-ns1')) - self.assertEquals('/other1/inner/42/37/', reverse('nodefault:urlobject-view', kwargs={'arg1':42, 'arg2':37}, current_app='other-ns1')) - -class RequestURLconfTests(TestCase): - def setUp(self): - self.root_urlconf = settings.ROOT_URLCONF - self.middleware_classes = settings.MIDDLEWARE_CLASSES - settings.ROOT_URLCONF = urlconf_outer.__name__ - - def tearDown(self): - settings.ROOT_URLCONF = self.root_urlconf - settings.MIDDLEWARE_CLASSES = self.middleware_classes - - def test_urlconf(self): - response = self.client.get('/test/me/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'outer:/test/me/,' - 'inner:/inner_urlconf/second_test/') - response = self.client.get('/inner_urlconf/second_test/') - self.assertEqual(response.status_code, 200) - response = self.client.get('/second_test/') - self.assertEqual(response.status_code, 404) - - def test_urlconf_overridden(self): - settings.MIDDLEWARE_CLASSES += ( - '%s.ChangeURLconfMiddleware' % middleware.__name__, - ) - response = self.client.get('/test/me/') - self.assertEqual(response.status_code, 404) - response = self.client.get('/inner_urlconf/second_test/') - self.assertEqual(response.status_code, 404) - response = self.client.get('/second_test/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, 'outer:,inner:/second_test/') - - def test_urlconf_overridden_with_null(self): - settings.MIDDLEWARE_CLASSES += ( - '%s.NullChangeURLconfMiddleware' % middleware.__name__, - ) - self.assertRaises(ImproperlyConfigured, self.client.get, '/test/me/') - -class ErrorHandlerResolutionTests(TestCase): - """Tests for handler404 and handler500""" - - def setUp(self): - urlconf = 'regressiontests.urlpatterns_reverse.urls_error_handlers' - urlconf_callables = 'regressiontests.urlpatterns_reverse.urls_error_handlers_callables' - self.resolver = RegexURLResolver(r'^$', urlconf) - self.callable_resolver = RegexURLResolver(r'^$', urlconf_callables) - - def test_named_handlers(self): - from views import empty_view - handler = (empty_view, {}) - self.assertEqual(self.resolver.resolve404(), handler) - self.assertEqual(self.resolver.resolve500(), handler) - - def test_callable_handers(self): - from views import empty_view - handler = (empty_view, {}) - self.assertEqual(self.callable_resolver.resolve404(), handler) - self.assertEqual(self.callable_resolver.resolve500(), handler) - -class NoRootUrlConfTests(TestCase): - """Tests for handler404 and handler500 if urlconf is None""" - urls = None - - def test_no_handler_exception(self): - self.assertRaises(ImproperlyConfigured, self.client.get, '/test/me/') diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_inner.py b/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_inner.py deleted file mode 100644 index d188e06..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_inner.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.conf.urls.defaults import * -from django.template import Template, Context -from django.http import HttpResponse - -def inner_view(request): - content = Template('{% url outer as outer_url %}outer:{{ outer_url }},' - '{% url inner as inner_url %}inner:{{ inner_url }}').render(Context()) - return HttpResponse(content) - -urlpatterns = patterns('', - url(r'^second_test/$', inner_view, name='inner'), -)
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_outer.py b/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_outer.py deleted file mode 100644 index 506e036..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/urlconf_outer.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.conf.urls.defaults import * - -import urlconf_inner - - -urlpatterns = patterns('', - url(r'^test/me/$', urlconf_inner.inner_view, name='outer'), - url(r'^inner_urlconf/', include(urlconf_inner.__name__)) -)
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/urls.py b/parts/django/tests/regressiontests/urlpatterns_reverse/urls.py deleted file mode 100644 index c603c02..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/urls.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.conf.urls.defaults import * -from views import empty_view, absolute_kwargs_view - -other_patterns = patterns('', - url(r'non_path_include/$', empty_view, name='non_path_include'), -) - -urlpatterns = patterns('', - url(r'^places/(\d+)/$', empty_view, name='places'), - url(r'^places?/$', empty_view, name="places?"), - url(r'^places+/$', empty_view, name="places+"), - url(r'^places*/$', empty_view, name="places*"), - url(r'^(?:places/)?$', empty_view, name="places2?"), - url(r'^(?:places/)+$', empty_view, name="places2+"), - url(r'^(?:places/)*$', empty_view, name="places2*"), - url(r'^places/(\d+|[a-z_]+)/', empty_view, name="places3"), - url(r'^places/(?P<id>\d+)/$', empty_view, name="places4"), - url(r'^people/(?P<name>\w+)/$', empty_view, name="people"), - url(r'^people/(?:name/)', empty_view, name="people2"), - url(r'^people/(?:name/(\w+)/)?', empty_view, name="people2a"), - url(r'^optional/(?P<name>.*)/(?:.+/)?', empty_view, name="optional"), - url(r'^hardcoded/$', 'hardcoded/', empty_view, name="hardcoded"), - url(r'^hardcoded/doc\.pdf$', empty_view, name="hardcoded2"), - url(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name="people3"), - url(r'^people/(?P<state>\w\w)/(?P<name>\d)/$', empty_view, name="people4"), - url(r'^people/((?P<state>\w\w)/test)?/(\w+)/$', empty_view, name="people6"), - url(r'^character_set/[abcdef0-9]/$', empty_view, name="range"), - url(r'^character_set/[\w]/$', empty_view, name="range2"), - url(r'^price/\$(\d+)/$', empty_view, name="price"), - url(r'^price/[$](\d+)/$', empty_view, name="price2"), - url(r'^price/[\$](\d+)/$', empty_view, name="price3"), - url(r'^product/(?P<product>\w+)\+\(\$(?P<price>\d+(\.\d+)?)\)/$', - empty_view, name="product"), - url(r'^headlines/(?P<year>\d+)\.(?P<month>\d+)\.(?P<day>\d+)/$', empty_view, - name="headlines"), - url(r'^windows_path/(?P<drive_name>[A-Z]):\\(?P<path>.+)/$', empty_view, - name="windows"), - url(r'^special_chars/(.+)/$', empty_view, name="special"), - url(r'^(?P<name>.+)/\d+/$', empty_view, name="mixed"), - url(r'^repeats/a{1,2}/$', empty_view, name="repeats"), - url(r'^repeats/a{2,4}/$', empty_view, name="repeats2"), - url(r'^repeats/a{2}/$', empty_view, name="repeats3"), - url(r'^(?i)CaseInsensitive/(\w+)', empty_view, name="insensitive"), - url(r'^test/1/?', empty_view, name="test"), - url(r'^(?i)test/2/?$', empty_view, name="test2"), - url(r'^outer/(?P<outer>\d+)/', - include('regressiontests.urlpatterns_reverse.included_urls')), - url('', include('regressiontests.urlpatterns_reverse.extra_urls')), - - # This is non-reversible, but we shouldn't blow up when parsing it. - url(r'^(?:foo|bar)(\w+)/$', empty_view, name="disjunction"), - - # Regression views for #9038. See tests for more details - url(r'arg_view/$', 'kwargs_view'), - url(r'arg_view/(?P<arg1>\d+)/$', 'kwargs_view'), - url(r'absolute_arg_view/(?P<arg1>\d+)/$', absolute_kwargs_view), - url(r'absolute_arg_view/$', absolute_kwargs_view), - - url('^includes/', include(other_patterns)), - -) - - diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers.py b/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers.py deleted file mode 100644 index c2e0d32..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers.py +++ /dev/null @@ -1,8 +0,0 @@ -# Used by the ErrorHandlerResolutionTests test case. - -from django.conf.urls.defaults import patterns - -urlpatterns = patterns('') - -handler404 = 'regressiontests.urlpatterns_reverse.views.empty_view' -handler500 = 'regressiontests.urlpatterns_reverse.views.empty_view' diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers_callables.py b/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers_callables.py deleted file mode 100644 index 00f25a7..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/urls_error_handlers_callables.py +++ /dev/null @@ -1,9 +0,0 @@ -# Used by the ErrorHandlerResolutionTests test case. - -from django.conf.urls.defaults import patterns -from views import empty_view - -urlpatterns = patterns('') - -handler404 = empty_view -handler500 = empty_view diff --git a/parts/django/tests/regressiontests/urlpatterns_reverse/views.py b/parts/django/tests/regressiontests/urlpatterns_reverse/views.py deleted file mode 100644 index 99c00bd..0000000 --- a/parts/django/tests/regressiontests/urlpatterns_reverse/views.py +++ /dev/null @@ -1,8 +0,0 @@ -def empty_view(request, *args, **kwargs): - pass - -def kwargs_view(request, arg1=1, arg2=2): - pass - -def absolute_kwargs_view(request, arg1=1, arg2=2): - pass diff --git a/parts/django/tests/regressiontests/utils/__init__.py b/parts/django/tests/regressiontests/utils/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/utils/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/utils/checksums.py b/parts/django/tests/regressiontests/utils/checksums.py deleted file mode 100644 index cee6dca..0000000 --- a/parts/django/tests/regressiontests/utils/checksums.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest - -from django.utils import checksums - -class TestUtilsChecksums(unittest.TestCase): - - def check_output(self, function, value, output=None): - """ - Check that function(value) equals output. If output is None, - check that function(value) equals value. - """ - if output is None: - output = value - self.assertEqual(function(value), output) - - def test_luhn(self): - f = checksums.luhn - items = ( - (4111111111111111, True), ('4111111111111111', True), - (4222222222222, True), (378734493671000, True), - (5424000000000015, True), (5555555555554444, True), - (1008, True), ('0000001008', True), ('000000001008', True), - (4012888888881881, True), (1234567890123456789012345678909, True), - (4111111111211111, False), (42222222222224, False), - (100, False), ('100', False), ('0000100', False), - ('abc', False), (None, False), (object(), False), - ) - for value, output in items: - self.check_output(f, value, output) diff --git a/parts/django/tests/regressiontests/utils/datastructures.py b/parts/django/tests/regressiontests/utils/datastructures.py deleted file mode 100644 index a41281c..0000000 --- a/parts/django/tests/regressiontests/utils/datastructures.py +++ /dev/null @@ -1,256 +0,0 @@ -""" -Tests for stuff in django.utils.datastructures. -""" -import pickle -import unittest - -from django.utils.datastructures import * - - -class DatastructuresTestCase(unittest.TestCase): - def assertRaisesErrorWithMessage(self, error, message, callable, - *args, **kwargs): - self.assertRaises(error, callable, *args, **kwargs) - try: - callable(*args, **kwargs) - except error, e: - self.assertEqual(message, str(e)) - - -class SortedDictTests(DatastructuresTestCase): - def setUp(self): - self.d1 = SortedDict() - self.d1[7] = 'seven' - self.d1[1] = 'one' - self.d1[9] = 'nine' - - self.d2 = SortedDict() - self.d2[1] = 'one' - self.d2[9] = 'nine' - self.d2[0] = 'nil' - self.d2[7] = 'seven' - - def test_basic_methods(self): - self.assertEquals(self.d1.keys(), [7, 1, 9]) - self.assertEquals(self.d1.values(), ['seven', 'one', 'nine']) - self.assertEquals(self.d1.items(), [(7, 'seven'), (1, 'one'), (9, 'nine')]) - - def test_overwrite_ordering(self): - """ Overwriting an item keeps it's place. """ - self.d1[1] = 'ONE' - self.assertEquals(self.d1.values(), ['seven', 'ONE', 'nine']) - - def test_append_items(self): - """ New items go to the end. """ - self.d1[0] = 'nil' - self.assertEquals(self.d1.keys(), [7, 1, 9, 0]) - - def test_delete_and_insert(self): - """ - Deleting an item, then inserting the same key again will place it - at the end. - """ - del self.d2[7] - self.assertEquals(self.d2.keys(), [1, 9, 0]) - self.d2[7] = 'lucky number 7' - self.assertEquals(self.d2.keys(), [1, 9, 0, 7]) - - def test_change_keys(self): - """ - Changing the keys won't do anything, it's only a copy of the - keys dict. - """ - k = self.d2.keys() - k.remove(9) - self.assertEquals(self.d2.keys(), [1, 9, 0, 7]) - - def test_init_keys(self): - """ - Initialising a SortedDict with two keys will just take the first one. - - A real dict will actually take the second value so we will too, but - we'll keep the ordering from the first key found. - """ - tuples = ((2, 'two'), (1, 'one'), (2, 'second-two')) - d = SortedDict(tuples) - - self.assertEquals(d.keys(), [2, 1]) - - real_dict = dict(tuples) - self.assertEquals(sorted(real_dict.values()), ['one', 'second-two']) - - # Here the order of SortedDict values *is* what we are testing - self.assertEquals(d.values(), ['second-two', 'one']) - - def test_overwrite(self): - self.d1[1] = 'not one' - self.assertEqual(self.d1[1], 'not one') - self.assertEqual(self.d1.keys(), self.d1.copy().keys()) - - def test_append(self): - self.d1[13] = 'thirteen' - self.assertEquals( - repr(self.d1), - "{7: 'seven', 1: 'one', 9: 'nine', 13: 'thirteen'}" - ) - - def test_pop(self): - self.assertEquals(self.d1.pop(1, 'missing'), 'one') - self.assertEquals(self.d1.pop(1, 'missing'), 'missing') - - # We don't know which item will be popped in popitem(), so we'll - # just check that the number of keys has decreased. - l = len(self.d1) - self.d1.popitem() - self.assertEquals(l - len(self.d1), 1) - - def test_dict_equality(self): - d = SortedDict((i, i) for i in xrange(3)) - self.assertEquals(d, {0: 0, 1: 1, 2: 2}) - - def test_tuple_init(self): - d = SortedDict(((1, "one"), (0, "zero"), (2, "two"))) - self.assertEquals(repr(d), "{1: 'one', 0: 'zero', 2: 'two'}") - - def test_pickle(self): - self.assertEquals( - pickle.loads(pickle.dumps(self.d1, 2)), - {7: 'seven', 1: 'one', 9: 'nine'} - ) - - def test_clear(self): - self.d1.clear() - self.assertEquals(self.d1, {}) - self.assertEquals(self.d1.keyOrder, []) - -class MergeDictTests(DatastructuresTestCase): - - def test_simple_mergedict(self): - d1 = {'chris':'cool', 'camri':'cute', 'cotton':'adorable', - 'tulip':'snuggable', 'twoofme':'firstone'} - - d2 = {'chris2':'cool2', 'camri2':'cute2', 'cotton2':'adorable2', - 'tulip2':'snuggable2'} - - d3 = {'chris3':'cool3', 'camri3':'cute3', 'cotton3':'adorable3', - 'tulip3':'snuggable3'} - - d4 = {'twoofme': 'secondone'} - - md = MergeDict(d1, d2, d3) - - self.assertEquals(md['chris'], 'cool') - self.assertEquals(md['camri'], 'cute') - self.assertEquals(md['twoofme'], 'firstone') - - md2 = md.copy() - self.assertEquals(md2['chris'], 'cool') - - def test_mergedict_merges_multivaluedict(self): - """ MergeDict can merge MultiValueDicts """ - - multi1 = MultiValueDict({'key1': ['value1'], - 'key2': ['value2', 'value3']}) - - multi2 = MultiValueDict({'key2': ['value4'], - 'key4': ['value5', 'value6']}) - - mm = MergeDict(multi1, multi2) - - # Although 'key2' appears in both dictionaries, - # only the first value is used. - self.assertEquals(mm.getlist('key2'), ['value2', 'value3']) - self.assertEquals(mm.getlist('key4'), ['value5', 'value6']) - self.assertEquals(mm.getlist('undefined'), []) - - self.assertEquals(sorted(mm.keys()), ['key1', 'key2', 'key4']) - self.assertEquals(len(mm.values()), 3) - - self.assertTrue('value1' in mm.values()) - - self.assertEquals(sorted(mm.items(), key=lambda k: k[0]), - [('key1', 'value1'), ('key2', 'value3'), - ('key4', 'value6')]) - - self.assertEquals([(k,mm.getlist(k)) for k in sorted(mm)], - [('key1', ['value1']), - ('key2', ['value2', 'value3']), - ('key4', ['value5', 'value6'])]) - -class MultiValueDictTests(DatastructuresTestCase): - - def test_multivaluedict(self): - d = MultiValueDict({'name': ['Adrian', 'Simon'], - 'position': ['Developer']}) - - self.assertEquals(d['name'], 'Simon') - self.assertEquals(d.get('name'), 'Simon') - self.assertEquals(d.getlist('name'), ['Adrian', 'Simon']) - self.assertEquals(list(d.iteritems()), - [('position', 'Developer'), ('name', 'Simon')]) - - self.assertEquals(list(d.iterlists()), - [('position', ['Developer']), - ('name', ['Adrian', 'Simon'])]) - - # MultiValueDictKeyError: "Key 'lastname' not found in - # <MultiValueDict: {'position': ['Developer'], - # 'name': ['Adrian', 'Simon']}>" - self.assertRaisesErrorWithMessage(MultiValueDictKeyError, - '"Key \'lastname\' not found in <MultiValueDict: {\'position\':'\ - ' [\'Developer\'], \'name\': [\'Adrian\', \'Simon\']}>"', - d.__getitem__, 'lastname') - - self.assertEquals(d.get('lastname'), None) - self.assertEquals(d.get('lastname', 'nonexistent'), 'nonexistent') - self.assertEquals(d.getlist('lastname'), []) - - d.setlist('lastname', ['Holovaty', 'Willison']) - self.assertEquals(d.getlist('lastname'), ['Holovaty', 'Willison']) - self.assertEquals(d.values(), ['Developer', 'Simon', 'Willison']) - self.assertEquals(list(d.itervalues()), - ['Developer', 'Simon', 'Willison']) - - -class DotExpandedDictTests(DatastructuresTestCase): - - def test_dotexpandeddict(self): - - d = DotExpandedDict({'person.1.firstname': ['Simon'], - 'person.1.lastname': ['Willison'], - 'person.2.firstname': ['Adrian'], - 'person.2.lastname': ['Holovaty']}) - - self.assertEquals(d['person']['1']['lastname'], ['Willison']) - self.assertEquals(d['person']['2']['lastname'], ['Holovaty']) - self.assertEquals(d['person']['2']['firstname'], ['Adrian']) - - -class ImmutableListTests(DatastructuresTestCase): - - def test_sort(self): - d = ImmutableList(range(10)) - - # AttributeError: ImmutableList object is immutable. - self.assertRaisesErrorWithMessage(AttributeError, - 'ImmutableList object is immutable.', d.sort) - - self.assertEquals(repr(d), '(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)') - - def test_custom_warning(self): - d = ImmutableList(range(10), warning="Object is immutable!") - - self.assertEquals(d[1], 1) - - # AttributeError: Object is immutable! - self.assertRaisesErrorWithMessage(AttributeError, - 'Object is immutable!', d.__setitem__, 1, 'test') - - -class DictWrapperTests(DatastructuresTestCase): - - def test_dictwrapper(self): - f = lambda x: "*%s" % x - d = DictWrapper({'a': 'a'}, f, 'xx_') - self.assertEquals("Normal: %(a)s. Modified: %(xx_a)s" % d, - 'Normal: a. Modified: *a') diff --git a/parts/django/tests/regressiontests/utils/dateformat.py b/parts/django/tests/regressiontests/utils/dateformat.py deleted file mode 100644 index b312c8d..0000000 --- a/parts/django/tests/regressiontests/utils/dateformat.py +++ /dev/null @@ -1,129 +0,0 @@ -from datetime import datetime, date -import os -import time -import unittest - -from django.utils.dateformat import format -from django.utils import dateformat, translation -from django.utils.tzinfo import FixedOffset, LocalTimezone - -class DateFormatTests(unittest.TestCase): - def setUp(self): - self.old_TZ = os.environ.get('TZ') - os.environ['TZ'] = 'Europe/Copenhagen' - translation.activate('en-us') - - try: - # Check if a timezone has been set - time.tzset() - self.tz_tests = True - except AttributeError: - # No timezone available. Don't run the tests that require a TZ - self.tz_tests = False - - def tearDown(self): - if self.old_TZ is None: - del os.environ['TZ'] - else: - os.environ['TZ'] = self.old_TZ - - # Cleanup - force re-evaluation of TZ environment variable. - if self.tz_tests: - time.tzset() - - def test_date(self): - d = date(2009, 5, 16) - self.assertEquals(date.fromtimestamp(int(format(d, 'U'))), d) - - def test_naive_datetime(self): - dt = datetime(2009, 5, 16, 5, 30, 30) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U'))), dt) - - def test_datetime_with_local_tzinfo(self): - ltz = LocalTimezone(datetime.now()) - dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=ltz) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U'))), dt.replace(tzinfo=None)) - - def test_datetime_with_tzinfo(self): - tz = FixedOffset(-510) - ltz = LocalTimezone(datetime.now()) - dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U')), tz), dt) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U'))), dt.astimezone(ltz).replace(tzinfo=None)) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple(), dt.utctimetuple()) - self.assertEquals(datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple(), dt.utctimetuple()) - - def test_epoch(self): - utc = FixedOffset(0) - udt = datetime(1970, 1, 1, tzinfo=utc) - self.assertEquals(format(udt, 'U'), u'0') - - def test_empty_format(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - - self.assertEquals(dateformat.format(my_birthday, ''), u'') - - def test_am_pm(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - - self.assertEquals(dateformat.format(my_birthday, 'a'), u'p.m.') - - def test_date_formats(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456) - - self.assertEquals(dateformat.format(my_birthday, 'A'), u'PM') - self.assertEquals(dateformat.format(timestamp, 'c'), u'2008-05-19T11:45:23.123456') - self.assertEquals(dateformat.format(my_birthday, 'd'), u'08') - self.assertEquals(dateformat.format(my_birthday, 'j'), u'8') - self.assertEquals(dateformat.format(my_birthday, 'l'), u'Sunday') - self.assertEquals(dateformat.format(my_birthday, 'L'), u'False') - self.assertEquals(dateformat.format(my_birthday, 'm'), u'07') - self.assertEquals(dateformat.format(my_birthday, 'M'), u'Jul') - self.assertEquals(dateformat.format(my_birthday, 'b'), u'jul') - self.assertEquals(dateformat.format(my_birthday, 'n'), u'7') - self.assertEquals(dateformat.format(my_birthday, 'N'), u'July') - - def test_time_formats(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - - self.assertEquals(dateformat.format(my_birthday, 'P'), u'10 p.m.') - self.assertEquals(dateformat.format(my_birthday, 's'), u'00') - self.assertEquals(dateformat.format(my_birthday, 'S'), u'th') - self.assertEquals(dateformat.format(my_birthday, 't'), u'31') - self.assertEquals(dateformat.format(my_birthday, 'w'), u'0') - self.assertEquals(dateformat.format(my_birthday, 'W'), u'27') - self.assertEquals(dateformat.format(my_birthday, 'y'), u'79') - self.assertEquals(dateformat.format(my_birthday, 'Y'), u'1979') - self.assertEquals(dateformat.format(my_birthday, 'z'), u'189') - - def test_dateformat(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - - self.assertEquals(dateformat.format(my_birthday, r'Y z \C\E\T'), u'1979 189 CET') - - self.assertEquals(dateformat.format(my_birthday, r'jS o\f F'), u'8th of July') - - def test_futuredates(self): - the_future = datetime(2100, 10, 25, 0, 00) - self.assertEquals(dateformat.format(the_future, r'Y'), u'2100') - - def test_timezones(self): - my_birthday = datetime(1979, 7, 8, 22, 00) - summertime = datetime(2005, 10, 30, 1, 00) - wintertime = datetime(2005, 10, 30, 4, 00) - timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456) - - if self.tz_tests: - self.assertEquals(dateformat.format(my_birthday, 'O'), u'+0100') - self.assertEquals(dateformat.format(my_birthday, 'r'), u'Sun, 8 Jul 1979 22:00:00 +0100') - self.assertEquals(dateformat.format(my_birthday, 'T'), u'CET') - self.assertEquals(dateformat.format(my_birthday, 'U'), u'300315600') - self.assertEquals(dateformat.format(timestamp, 'u'), u'123456') - self.assertEquals(dateformat.format(my_birthday, 'Z'), u'3600') - self.assertEquals(dateformat.format(summertime, 'I'), u'1') - self.assertEquals(dateformat.format(summertime, 'O'), u'+0200') - self.assertEquals(dateformat.format(wintertime, 'I'), u'0') - self.assertEquals(dateformat.format(wintertime, 'O'), u'+0100') diff --git a/parts/django/tests/regressiontests/utils/datetime_safe.py b/parts/django/tests/regressiontests/utils/datetime_safe.py deleted file mode 100644 index 458a6b7..0000000 --- a/parts/django/tests/regressiontests/utils/datetime_safe.py +++ /dev/null @@ -1,42 +0,0 @@ -import unittest - -from datetime import date as original_date, datetime as original_datetime -from django.utils.datetime_safe import date, datetime - -class DatetimeTests(unittest.TestCase): - - def setUp(self): - self.just_safe = (1900, 1, 1) - self.just_unsafe = (1899, 12, 31, 23, 59, 59) - self.really_old = (20, 1, 1) - self.more_recent = (2006, 1, 1) - - def test_compare_datetimes(self): - self.assertEqual(original_datetime(*self.more_recent), datetime(*self.more_recent)) - self.assertEqual(original_datetime(*self.really_old), datetime(*self.really_old)) - self.assertEqual(original_date(*self.more_recent), date(*self.more_recent)) - self.assertEqual(original_date(*self.really_old), date(*self.really_old)) - - self.assertEqual(original_date(*self.just_safe).strftime('%Y-%m-%d'), date(*self.just_safe).strftime('%Y-%m-%d')) - self.assertEqual(original_datetime(*self.just_safe).strftime('%Y-%m-%d'), datetime(*self.just_safe).strftime('%Y-%m-%d')) - - def test_safe_strftime(self): - self.assertEquals(date(*self.just_unsafe[:3]).strftime('%Y-%m-%d (weekday %w)'), '1899-12-31 (weekday 0)') - self.assertEquals(date(*self.just_safe).strftime('%Y-%m-%d (weekday %w)'), '1900-01-01 (weekday 1)') - - self.assertEquals(datetime(*self.just_unsafe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)'), '1899-12-31 23:59:59 (weekday 0)') - self.assertEquals(datetime(*self.just_safe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)'), '1900-01-01 00:00:00 (weekday 1)') - - # %y will error before this date - self.assertEquals(date(*self.just_safe).strftime('%y'), '00') - self.assertEquals(datetime(*self.just_safe).strftime('%y'), '00') - - self.assertEquals(date(1850, 8, 2).strftime("%Y/%m/%d was a %A"), '1850/08/02 was a Friday') - - def test_zero_padding(self): - """ - Regression for #12524 - - Check that pre-1000AD dates are padded with zeros if necessary - """ - self.assertEquals(date(1, 1, 1).strftime("%Y/%m/%d was a %A"), '0001/01/01 was a Monday') diff --git a/parts/django/tests/regressiontests/utils/decorators.py b/parts/django/tests/regressiontests/utils/decorators.py deleted file mode 100644 index ca9214f..0000000 --- a/parts/django/tests/regressiontests/utils/decorators.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.test import TestCase - -class DecoratorFromMiddlewareTests(TestCase): - """ - Tests for view decorators created using - ``django.utils.decorators.decorator_from_middleware``. - """ - - def test_process_view_middleware(self): - """ - Test a middleware that implements process_view. - """ - self.client.get('/utils/xview/') - - def test_callable_process_view_middleware(self): - """ - Test a middleware that implements process_view, operating on a callable class. - """ - self.client.get('/utils/class_xview/') diff --git a/parts/django/tests/regressiontests/utils/eggs/test_egg.egg b/parts/django/tests/regressiontests/utils/eggs/test_egg.egg Binary files differdeleted file mode 100644 index 9b08cc1..0000000 --- a/parts/django/tests/regressiontests/utils/eggs/test_egg.egg +++ /dev/null diff --git a/parts/django/tests/regressiontests/utils/feedgenerator.py b/parts/django/tests/regressiontests/utils/feedgenerator.py deleted file mode 100644 index 9085d41..0000000 --- a/parts/django/tests/regressiontests/utils/feedgenerator.py +++ /dev/null @@ -1,63 +0,0 @@ -import datetime -import unittest - -from django.utils import feedgenerator, tzinfo - -class FeedgeneratorTest(unittest.TestCase): - """ - Tests for the low-level syndication feed framework. - """ - - def test_get_tag_uri(self): - """ - Test get_tag_uri() correctly generates TagURIs. - """ - self.assertEqual( - feedgenerator.get_tag_uri('http://example.org/foo/bar#headline', datetime.date(2004, 10, 25)), - u'tag:example.org,2004-10-25:/foo/bar/headline') - - def test_get_tag_uri_with_port(self): - """ - Test that get_tag_uri() correctly generates TagURIs from URLs with port - numbers. - """ - self.assertEqual( - feedgenerator.get_tag_uri('http://www.example.org:8000/2008/11/14/django#headline', datetime.datetime(2008, 11, 14, 13, 37, 0)), - u'tag:www.example.org,2008-11-14:/2008/11/14/django/headline') - - def test_rfc2822_date(self): - """ - Test rfc2822_date() correctly formats datetime objects. - """ - self.assertEqual( - feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0)), - "Fri, 14 Nov 2008 13:37:00 -0000" - ) - - def test_rfc2822_date_with_timezone(self): - """ - Test rfc2822_date() correctly formats datetime objects with tzinfo. - """ - self.assertEqual( - feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=60)))), - "Fri, 14 Nov 2008 13:37:00 +0100" - ) - - def test_rfc3339_date(self): - """ - Test rfc3339_date() correctly formats datetime objects. - """ - self.assertEqual( - feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0)), - "2008-11-14T13:37:00Z" - ) - - def test_rfc3339_date_with_timezone(self): - """ - Test rfc3339_date() correctly formats datetime objects with tzinfo. - """ - self.assertEqual( - feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=120)))), - "2008-11-14T13:37:00+02:00" - ) - diff --git a/parts/django/tests/regressiontests/utils/functional.py b/parts/django/tests/regressiontests/utils/functional.py deleted file mode 100644 index 206a583..0000000 --- a/parts/django/tests/regressiontests/utils/functional.py +++ /dev/null @@ -1,10 +0,0 @@ -import unittest - -from django.utils.functional import lazy - - -class FunctionalTestCase(unittest.TestCase): - def test_lazy(self): - t = lazy(lambda: tuple(range(3)), list, tuple) - for a, b in zip(t(), range(3)): - self.assertEqual(a, b) diff --git a/parts/django/tests/regressiontests/utils/html.py b/parts/django/tests/regressiontests/utils/html.py deleted file mode 100644 index a9b0d33..0000000 --- a/parts/django/tests/regressiontests/utils/html.py +++ /dev/null @@ -1,111 +0,0 @@ -import unittest - -from django.utils import html - -class TestUtilsHtml(unittest.TestCase): - - def check_output(self, function, value, output=None): - """ - Check that function(value) equals output. If output is None, - check that function(value) equals value. - """ - if output is None: - output = value - self.assertEqual(function(value), output) - - def test_escape(self): - f = html.escape - items = ( - ('&','&'), - ('<', '<'), - ('>', '>'), - ('"', '"'), - ("'", '''), - ) - # Substitution patterns for testing the above items. - patterns = ("%s", "asdf%sfdsa", "%s1", "1%sb") - for value, output in items: - for pattern in patterns: - self.check_output(f, pattern % value, pattern % output) - # Check repeated values. - self.check_output(f, value * 2, output * 2) - # Verify it doesn't double replace &. - self.check_output(f, '<&', '<&') - - def test_linebreaks(self): - f = html.linebreaks - items = ( - ("para1\n\npara2\r\rpara3", "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"), - ("para1\nsub1\rsub2\n\npara2", "<p>para1<br />sub1<br />sub2</p>\n\n<p>para2</p>"), - ("para1\r\n\r\npara2\rsub1\r\rpara4", "<p>para1</p>\n\n<p>para2<br />sub1</p>\n\n<p>para4</p>"), - ("para1\tmore\n\npara2", "<p>para1\tmore</p>\n\n<p>para2</p>"), - ) - for value, output in items: - self.check_output(f, value, output) - - def test_strip_tags(self): - f = html.strip_tags - items = ( - ('<adf>a', 'a'), - ('</adf>a', 'a'), - ('<asdf><asdf>e', 'e'), - ('<f', '<f'), - ('</fe', '</fe'), - ('<x>b<y>', 'b'), - ) - for value, output in items: - self.check_output(f, value, output) - - def test_strip_spaces_between_tags(self): - f = html.strip_spaces_between_tags - # Strings that should come out untouched. - items = (' <adf>', '<adf> ', ' </adf> ', ' <f> x</f>') - for value in items: - self.check_output(f, value) - # Strings that have spaces to strip. - items = ( - ('<d> </d>', '<d></d>'), - ('<p>hello </p>\n<p> world</p>', '<p>hello </p><p> world</p>'), - ('\n<p>\t</p>\n<p> </p>\n', '\n<p></p><p></p>\n'), - ) - for value, output in items: - self.check_output(f, value, output) - - def test_strip_entities(self): - f = html.strip_entities - # Strings that should come out untouched. - values = ("&", "&a", "&a", "a&#a") - for value in values: - self.check_output(f, value) - # Valid entities that should be stripped from the patterns. - entities = ("", "", "&a;", "&fdasdfasdfasdf;") - patterns = ( - ("asdf %(entity)s ", "asdf "), - ("%(entity)s%(entity)s", ""), - ("&%(entity)s%(entity)s", "&"), - ("%(entity)s3", "3"), - ) - for entity in entities: - for in_pattern, output in patterns: - self.check_output(f, in_pattern % {'entity': entity}, output) - - def test_fix_ampersands(self): - f = html.fix_ampersands - # Strings without ampersands or with ampersands already encoded. - values = ("a", "b", "&a;", "& &x; ", "asdf") - patterns = ( - ("%s", "%s"), - ("&%s", "&%s"), - ("&%s&", "&%s&"), - ) - for value in values: - for in_pattern, out_pattern in patterns: - self.check_output(f, in_pattern % value, out_pattern % value) - # Strings with ampersands that need encoding. - items = ( - ("&#;", "&#;"), - ("ͫ ;", "&#875 ;"), - ("abc;", "&#4abc;"), - ) - for value, output in items: - self.check_output(f, value, output) diff --git a/parts/django/tests/regressiontests/utils/models.py b/parts/django/tests/regressiontests/utils/models.py deleted file mode 100644 index 97a72ba..0000000 --- a/parts/django/tests/regressiontests/utils/models.py +++ /dev/null @@ -1 +0,0 @@ -# Test runner needs a models.py file. diff --git a/parts/django/tests/regressiontests/utils/module_loading.py b/parts/django/tests/regressiontests/utils/module_loading.py deleted file mode 100644 index 8cbefbb..0000000 --- a/parts/django/tests/regressiontests/utils/module_loading.py +++ /dev/null @@ -1,114 +0,0 @@ -import os -import sys -import unittest -from zipimport import zipimporter - -from django.utils.importlib import import_module -from django.utils.module_loading import module_has_submodule - -class DefaultLoader(unittest.TestCase): - def test_loader(self): - "Normal module existence can be tested" - test_module = import_module('regressiontests.utils.test_module') - - # An importable child - self.assertTrue(module_has_submodule(test_module, 'good_module')) - mod = import_module('regressiontests.utils.test_module.good_module') - self.assertEqual(mod.content, 'Good Module') - - # A child that exists, but will generate an import error if loaded - self.assertTrue(module_has_submodule(test_module, 'bad_module')) - self.assertRaises(ImportError, import_module, 'regressiontests.utils.test_module.bad_module') - - # A child that doesn't exist - self.assertFalse(module_has_submodule(test_module, 'no_such_module')) - self.assertRaises(ImportError, import_module, 'regressiontests.utils.test_module.no_such_module') - -class EggLoader(unittest.TestCase): - def setUp(self): - self.old_path = sys.path[:] - self.egg_dir = '%s/eggs' % os.path.dirname(__file__) - - def tearDown(self): - sys.path = self.old_path - sys.path_importer_cache.clear() - - sys.modules.pop('egg_module.sub1.sub2.bad_module', None) - sys.modules.pop('egg_module.sub1.sub2.good_module', None) - sys.modules.pop('egg_module.sub1.sub2', None) - sys.modules.pop('egg_module.sub1', None) - sys.modules.pop('egg_module.bad_module', None) - sys.modules.pop('egg_module.good_module', None) - sys.modules.pop('egg_module', None) - - def test_shallow_loader(self): - "Module existence can be tested inside eggs" - egg_name = '%s/test_egg.egg' % self.egg_dir - sys.path.append(egg_name) - egg_module = import_module('egg_module') - - # An importable child - self.assertTrue(module_has_submodule(egg_module, 'good_module')) - mod = import_module('egg_module.good_module') - self.assertEqual(mod.content, 'Good Module') - - # A child that exists, but will generate an import error if loaded - self.assertTrue(module_has_submodule(egg_module, 'bad_module')) - self.assertRaises(ImportError, import_module, 'egg_module.bad_module') - - # A child that doesn't exist - self.assertFalse(module_has_submodule(egg_module, 'no_such_module')) - self.assertRaises(ImportError, import_module, 'egg_module.no_such_module') - - def test_deep_loader(self): - "Modules deep inside an egg can still be tested for existence" - egg_name = '%s/test_egg.egg' % self.egg_dir - sys.path.append(egg_name) - egg_module = import_module('egg_module.sub1.sub2') - - # An importable child - self.assertTrue(module_has_submodule(egg_module, 'good_module')) - mod = import_module('egg_module.sub1.sub2.good_module') - self.assertEqual(mod.content, 'Deep Good Module') - - # A child that exists, but will generate an import error if loaded - self.assertTrue(module_has_submodule(egg_module, 'bad_module')) - self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.bad_module') - - # A child that doesn't exist - self.assertFalse(module_has_submodule(egg_module, 'no_such_module')) - self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.no_such_module') - -class TestFinder(object): - def __init__(self, *args, **kwargs): - self.importer = zipimporter(*args, **kwargs) - - def find_module(self, path): - importer = self.importer.find_module(path) - if importer is None: - return - return TestLoader(importer) - -class TestLoader(object): - def __init__(self, importer): - self.importer = importer - - def load_module(self, name): - mod = self.importer.load_module(name) - mod.__loader__ = self - return mod - -class CustomLoader(EggLoader): - """The Custom Loader test is exactly the same as the EggLoader, but - it uses a custom defined Loader and Finder that is intentionally - split into two classes. Although the EggLoader combines both functions - into one class, this isn't required. - """ - def setUp(self): - super(CustomLoader, self).setUp() - sys.path_hooks.insert(0, TestFinder) - sys.path_importer_cache.clear() - - def tearDown(self): - super(CustomLoader, self).tearDown() - sys.path_hooks.pop(0) diff --git a/parts/django/tests/regressiontests/utils/simplelazyobject.py b/parts/django/tests/regressiontests/utils/simplelazyobject.py deleted file mode 100644 index 4a930dd..0000000 --- a/parts/django/tests/regressiontests/utils/simplelazyobject.py +++ /dev/null @@ -1,77 +0,0 @@ -import unittest - -import django.utils.copycompat as copy -from django.utils.functional import SimpleLazyObject - -class _ComplexObject(object): - def __init__(self, name): - self.name = name - - def __eq__(self, other): - return self.name == other.name - - def __hash__(self): - return hash(self.name) - - def __str__(self): - return "I am _ComplexObject(%r)" % self.name - - def __unicode__(self): - return unicode(self.name) - - def __repr__(self): - return "_ComplexObject(%r)" % self.name - -complex_object = lambda: _ComplexObject("joe") - -class TestUtilsSimpleLazyObject(unittest.TestCase): - """ - Tests for SimpleLazyObject - """ - # Note that concrete use cases for SimpleLazyObject are also found in the - # auth context processor tests (unless the implementation of that function - # is changed). - - def test_equality(self): - self.assertEqual(complex_object(), SimpleLazyObject(complex_object)) - self.assertEqual(SimpleLazyObject(complex_object), complex_object()) - - def test_hash(self): - # hash() equality would not be true for many objects, but it should be - # for _ComplexObject - self.assertEqual(hash(complex_object()), - hash(SimpleLazyObject(complex_object))) - - def test_repr(self): - # For debugging, it will really confuse things if there is no clue that - # SimpleLazyObject is actually a proxy object. So we don't - # proxy __repr__ - self.assert_("SimpleLazyObject" in repr(SimpleLazyObject(complex_object))) - - def test_str(self): - self.assertEqual("I am _ComplexObject('joe')", str(SimpleLazyObject(complex_object))) - - def test_unicode(self): - self.assertEqual(u"joe", unicode(SimpleLazyObject(complex_object))) - - def test_class(self): - # This is important for classes that use __class__ in things like - # equality tests. - self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) - - def test_deepcopy(self): - # Check that we *can* do deep copy, and that it returns the right - # objects. - - # First, for an unevaluated SimpleLazyObject - s = SimpleLazyObject(complex_object) - assert s._wrapped is None - s2 = copy.deepcopy(s) - assert s._wrapped is None # something has gone wrong is s is evaluated - self.assertEqual(s2, complex_object()) - - # Second, for an evaluated SimpleLazyObject - name = s.name # evaluate - assert s._wrapped is not None - s3 = copy.deepcopy(s) - self.assertEqual(s3, complex_object()) diff --git a/parts/django/tests/regressiontests/utils/termcolors.py b/parts/django/tests/regressiontests/utils/termcolors.py deleted file mode 100644 index ccae32c..0000000 --- a/parts/django/tests/regressiontests/utils/termcolors.py +++ /dev/null @@ -1,149 +0,0 @@ -import unittest - -from django.utils.termcolors import parse_color_setting, PALETTES, DEFAULT_PALETTE, LIGHT_PALETTE, DARK_PALETTE, NOCOLOR_PALETTE - -class TermColorTests(unittest.TestCase): - - def test_empty_string(self): - self.assertEquals(parse_color_setting(''), PALETTES[DEFAULT_PALETTE]) - - def test_simple_palette(self): - self.assertEquals(parse_color_setting('light'), PALETTES[LIGHT_PALETTE]) - self.assertEquals(parse_color_setting('dark'), PALETTES[DARK_PALETTE]) - self.assertEquals(parse_color_setting('nocolor'), None) - - def test_fg(self): - self.assertEquals(parse_color_setting('error=green'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - - def test_fg_bg(self): - self.assertEquals(parse_color_setting('error=green/blue'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg':'blue'})) - - def test_fg_opts(self): - self.assertEquals(parse_color_setting('error=green,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink',)})) - self.assertEquals(parse_color_setting('error=green,bold,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink','bold')})) - - def test_fg_bg_opts(self): - self.assertEquals(parse_color_setting('error=green/blue,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg':'blue', 'opts': ('blink',)})) - self.assertEquals(parse_color_setting('error=green/blue,bold,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg':'blue', 'opts': ('blink','bold')})) - - def test_override_palette(self): - self.assertEquals(parse_color_setting('light;error=green'), - dict(PALETTES[LIGHT_PALETTE], - ERROR={'fg':'green'})) - - def test_override_nocolor(self): - self.assertEquals(parse_color_setting('nocolor;error=green'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg': 'green'})) - - def test_reverse_override(self): - self.assertEquals(parse_color_setting('error=green;light'), PALETTES[LIGHT_PALETTE]) - - def test_multiple_roles(self): - self.assertEquals(parse_color_setting('error=green;sql_field=blue'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'}, - SQL_FIELD={'fg':'blue'})) - - def test_override_with_multiple_roles(self): - self.assertEquals(parse_color_setting('light;error=green;sql_field=blue'), - dict(PALETTES[LIGHT_PALETTE], - ERROR={'fg':'green'}, - SQL_FIELD={'fg':'blue'})) - - def test_empty_definition(self): - self.assertEquals(parse_color_setting(';'), None) - self.assertEquals(parse_color_setting('light;'), PALETTES[LIGHT_PALETTE]) - self.assertEquals(parse_color_setting(';;;'), None) - - def test_empty_options(self): - self.assertEquals(parse_color_setting('error=green,'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=green,,,'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=green,,blink,,'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink',)})) - - def test_bad_palette(self): - self.assertEquals(parse_color_setting('unknown'), None) - - def test_bad_role(self): - self.assertEquals(parse_color_setting('unknown='), None) - self.assertEquals(parse_color_setting('unknown=green'), None) - self.assertEquals(parse_color_setting('unknown=green;sql_field=blue'), - dict(PALETTES[NOCOLOR_PALETTE], - SQL_FIELD={'fg':'blue'})) - - def test_bad_color(self): - self.assertEquals(parse_color_setting('error='), None) - self.assertEquals(parse_color_setting('error=;sql_field=blue'), - dict(PALETTES[NOCOLOR_PALETTE], - SQL_FIELD={'fg':'blue'})) - self.assertEquals(parse_color_setting('error=unknown'), None) - self.assertEquals(parse_color_setting('error=unknown;sql_field=blue'), - dict(PALETTES[NOCOLOR_PALETTE], - SQL_FIELD={'fg':'blue'})) - self.assertEquals(parse_color_setting('error=green/unknown'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=green/blue/something'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg': 'blue'})) - self.assertEquals(parse_color_setting('error=green/blue/something,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg': 'blue', 'opts': ('blink',)})) - - def test_bad_option(self): - self.assertEquals(parse_color_setting('error=green,unknown'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=green,unknown,blink'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink',)})) - - def test_role_case(self): - self.assertEquals(parse_color_setting('ERROR=green'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('eRrOr=green'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - - def test_color_case(self): - self.assertEquals(parse_color_setting('error=GREEN'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=GREEN/BLUE'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg':'blue'})) - - self.assertEquals(parse_color_setting('error=gReEn'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green'})) - self.assertEquals(parse_color_setting('error=gReEn/bLuE'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'bg':'blue'})) - - def test_opts_case(self): - self.assertEquals(parse_color_setting('error=green,BLINK'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink',)})) - - self.assertEquals(parse_color_setting('error=green,bLiNk'), - dict(PALETTES[NOCOLOR_PALETTE], - ERROR={'fg':'green', 'opts': ('blink',)})) diff --git a/parts/django/tests/regressiontests/utils/test_module/__init__.py b/parts/django/tests/regressiontests/utils/test_module/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/utils/test_module/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/utils/test_module/bad_module.py b/parts/django/tests/regressiontests/utils/test_module/bad_module.py deleted file mode 100644 index cc0cd16..0000000 --- a/parts/django/tests/regressiontests/utils/test_module/bad_module.py +++ /dev/null @@ -1,3 +0,0 @@ -import a_package_name_that_does_not_exist - -content = 'Bad Module'
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/utils/test_module/good_module.py b/parts/django/tests/regressiontests/utils/test_module/good_module.py deleted file mode 100644 index 0ca6898..0000000 --- a/parts/django/tests/regressiontests/utils/test_module/good_module.py +++ /dev/null @@ -1 +0,0 @@ -content = 'Good Module'
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/utils/tests.py b/parts/django/tests/regressiontests/utils/tests.py deleted file mode 100644 index 6d3bbfa..0000000 --- a/parts/django/tests/regressiontests/utils/tests.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Tests for django.utils. -""" - -from dateformat import * -from feedgenerator import * -from module_loading import * -from termcolors import * -from html import * -from checksums import * -from text import * -from simplelazyobject import * -from decorators import * -from functional import * -from timesince import * -from datastructures import * -from tzinfo import * -from datetime_safe import * diff --git a/parts/django/tests/regressiontests/utils/text.py b/parts/django/tests/regressiontests/utils/text.py deleted file mode 100644 index e7d2d38..0000000 --- a/parts/django/tests/regressiontests/utils/text.py +++ /dev/null @@ -1,20 +0,0 @@ -import unittest - -from django.utils import text - -class TestUtilsText(unittest.TestCase): - def test_truncate_words(self): - self.assertEqual(u'The quick brown fox jumped over the lazy dog.', - text.truncate_words(u'The quick brown fox jumped over the lazy dog.', 10)) - self.assertEqual(u'The quick brown fox ...', - text.truncate_words('The quick brown fox jumped over the lazy dog.', 4)) - self.assertEqual(u'The quick brown fox ....', - text.truncate_words('The quick brown fox jumped over the lazy dog.', 4, '....')) - self.assertEqual(u'<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', - text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 10)) - self.assertEqual(u'<p><strong><em>The quick brown fox ...</em></strong></p>', - text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4)) - self.assertEqual(u'<p><strong><em>The quick brown fox ....</em></strong></p>', - text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4, '....')) - self.assertEqual(u'<p><strong><em>The quick brown fox</em></strong></p>', - text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4, None)) diff --git a/parts/django/tests/regressiontests/utils/timesince.py b/parts/django/tests/regressiontests/utils/timesince.py deleted file mode 100644 index 774aa3f..0000000 --- a/parts/django/tests/regressiontests/utils/timesince.py +++ /dev/null @@ -1,107 +0,0 @@ -import datetime -import unittest - -from django.utils.timesince import timesince, timeuntil -from django.utils.tzinfo import LocalTimezone, FixedOffset - -class TimesinceTests(unittest.TestCase): - - def setUp(self): - self.t = datetime.datetime(2007, 8, 14, 13, 46, 0) - self.onemicrosecond = datetime.timedelta(microseconds=1) - self.onesecond = datetime.timedelta(seconds=1) - self.oneminute = datetime.timedelta(minutes=1) - self.onehour = datetime.timedelta(hours=1) - self.oneday = datetime.timedelta(days=1) - self.oneweek = datetime.timedelta(days=7) - self.onemonth = datetime.timedelta(days=30) - self.oneyear = datetime.timedelta(days=365) - - def test_equal_datetimes(self): - """ equal datetimes. """ - self.assertEquals(timesince(self.t, self.t), u'0 minutes') - - def test_ignore_microseconds_and_seconds(self): - """ Microseconds and seconds are ignored. """ - self.assertEquals(timesince(self.t, self.t+self.onemicrosecond), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t+self.onesecond), - u'0 minutes') - - def test_other_units(self): - """ Test other units. """ - self.assertEquals(timesince(self.t, self.t+self.oneminute), - u'1 minute') - self.assertEquals(timesince(self.t, self.t+self.onehour), u'1 hour') - self.assertEquals(timesince(self.t, self.t+self.oneday), u'1 day') - self.assertEquals(timesince(self.t, self.t+self.oneweek), u'1 week') - self.assertEquals(timesince(self.t, self.t+self.onemonth), - u'1 month') - self.assertEquals(timesince(self.t, self.t+self.oneyear), u'1 year') - - def test_multiple_units(self): - """ Test multiple units. """ - self.assertEquals(timesince(self.t, - self.t+2*self.oneday+6*self.onehour), u'2 days, 6 hours') - self.assertEquals(timesince(self.t, - self.t+2*self.oneweek+2*self.oneday), u'2 weeks, 2 days') - - def test_display_first_unit(self): - """ - If the two differing units aren't adjacent, only the first unit is - displayed. - """ - self.assertEquals(timesince(self.t, - self.t+2*self.oneweek+3*self.onehour+4*self.oneminute), - u'2 weeks') - - self.assertEquals(timesince(self.t, - self.t+4*self.oneday+5*self.oneminute), u'4 days') - - def test_display_second_before_first(self): - """ - When the second date occurs before the first, we should always - get 0 minutes. - """ - self.assertEquals(timesince(self.t, self.t-self.onemicrosecond), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.onesecond), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.oneminute), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.onehour), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.oneday), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.oneweek), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.onemonth), - u'0 minutes') - self.assertEquals(timesince(self.t, self.t-self.oneyear), - u'0 minutes') - self.assertEquals(timesince(self.t, - self.t-2*self.oneday-6*self.onehour), u'0 minutes') - self.assertEquals(timesince(self.t, - self.t-2*self.oneweek-2*self.oneday), u'0 minutes') - self.assertEquals(timesince(self.t, - self.t-2*self.oneweek-3*self.onehour-4*self.oneminute), - u'0 minutes') - self.assertEquals(timesince(self.t, - self.t-4*self.oneday-5*self.oneminute), u'0 minutes') - - def test_different_timezones(self): - """ When using two different timezones. """ - now = datetime.datetime.now() - now_tz = datetime.datetime.now(LocalTimezone(now)) - now_tz_i = datetime.datetime.now(FixedOffset((3 * 60) + 15)) - - self.assertEquals(timesince(now), u'0 minutes') - self.assertEquals(timesince(now_tz), u'0 minutes') - self.assertEquals(timeuntil(now_tz, now_tz_i), u'0 minutes') - - def test_both_date_objects(self): - """ Timesince should work with both date objects (#9672) """ - today = datetime.date.today() - self.assertEquals(timeuntil(today+self.oneday, today), u'1 day') - self.assertEquals(timeuntil(today-self.oneday, today), u'0 minutes') - self.assertEquals(timeuntil(today+self.oneweek, today), u'1 week') diff --git a/parts/django/tests/regressiontests/utils/tzinfo.py b/parts/django/tests/regressiontests/utils/tzinfo.py deleted file mode 100644 index edbb9a7..0000000 --- a/parts/django/tests/regressiontests/utils/tzinfo.py +++ /dev/null @@ -1,18 +0,0 @@ -import unittest - -from django.utils.tzinfo import FixedOffset - -class TzinfoTests(unittest.TestCase): - - def test_fixedoffset(self): - self.assertEquals(repr(FixedOffset(0)), '+0000') - self.assertEquals(repr(FixedOffset(60)), '+0100') - self.assertEquals(repr(FixedOffset(-60)), '-0100') - self.assertEquals(repr(FixedOffset(280)), '+0440') - self.assertEquals(repr(FixedOffset(-280)), '-0440') - self.assertEquals(repr(FixedOffset(-78.4)), '-0118') - self.assertEquals(repr(FixedOffset(78.4)), '+0118') - self.assertEquals(repr(FixedOffset(-5.5*60)), '-0530') - self.assertEquals(repr(FixedOffset(5.5*60)), '+0530') - self.assertEquals(repr(FixedOffset(-.5*60)), '-0030') - self.assertEquals(repr(FixedOffset(.5*60)), '+0030') diff --git a/parts/django/tests/regressiontests/utils/urls.py b/parts/django/tests/regressiontests/utils/urls.py deleted file mode 100644 index ba09d14..0000000 --- a/parts/django/tests/regressiontests/utils/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.conf.urls.defaults import * - -import views - -urlpatterns = patterns('', - (r'^xview/$', views.xview), - (r'^class_xview/$', views.class_xview), -) diff --git a/parts/django/tests/regressiontests/utils/views.py b/parts/django/tests/regressiontests/utils/views.py deleted file mode 100644 index ef97c65..0000000 --- a/parts/django/tests/regressiontests/utils/views.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.http import HttpResponse -from django.utils.decorators import decorator_from_middleware -from django.middleware.doc import XViewMiddleware - - -xview_dec = decorator_from_middleware(XViewMiddleware) - -def xview(request): - return HttpResponse() -xview = xview_dec(xview) - - -class ClassXView(object): - def __call__(self, request): - return HttpResponse() - -class_xview = xview_dec(ClassXView()) diff --git a/parts/django/tests/regressiontests/views/__init__.py b/parts/django/tests/regressiontests/views/__init__.py deleted file mode 100644 index d1c6e08..0000000 --- a/parts/django/tests/regressiontests/views/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf8 -*- - -class BrokenException(Exception): - pass - -except_args = ('Broken!', # plain exception with ASCII text - u'¡Broken!', # non-ASCII unicode data - '¡Broken!', # non-ASCII, utf-8 encoded bytestring - '\xa1Broken!', ) # non-ASCII, latin1 bytestring - diff --git a/parts/django/tests/regressiontests/views/app0/__init__.py b/parts/django/tests/regressiontests/views/app0/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/parts/django/tests/regressiontests/views/app0/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 662204a..0000000 --- a/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.po deleted file mode 100644 index a458935..0000000 --- a/parts/django/tests/regressiontests/views/app0/locale/en/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,20 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 12:41-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "il faut traduire cette chaîne de caractères de app0" -msgstr "this app0 string is to be translated" diff --git a/parts/django/tests/regressiontests/views/app1/__init__.py b/parts/django/tests/regressiontests/views/app1/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/parts/django/tests/regressiontests/views/app1/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 5d6aecb..0000000 --- a/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.po deleted file mode 100644 index a4627db..0000000 --- a/parts/django/tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,20 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 12:41-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "this app1 string is to be translated" -msgstr "il faut traduire cette chaîne de caractères de app1" diff --git a/parts/django/tests/regressiontests/views/app2/__init__.py b/parts/django/tests/regressiontests/views/app2/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/parts/django/tests/regressiontests/views/app2/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 17e1863..0000000 --- a/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.po deleted file mode 100644 index 637b9e6..0000000 --- a/parts/django/tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,20 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 22:05-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "this app2 string is to be translated" -msgstr "il faut traduire cette chaîne de caractères de app2" diff --git a/parts/django/tests/regressiontests/views/app3/__init__.py b/parts/django/tests/regressiontests/views/app3/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/parts/django/tests/regressiontests/views/app3/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 0c485a9..0000000 --- a/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.po deleted file mode 100644 index 1e3be0b..0000000 --- a/parts/django/tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,20 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 12:41-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "il faut traduire cette chaîne de caractères de app3" -msgstr "este texto de app3 debe ser traducido" diff --git a/parts/django/tests/regressiontests/views/app4/__init__.py b/parts/django/tests/regressiontests/views/app4/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/parts/django/tests/regressiontests/views/app4/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 581fbb0..0000000 --- a/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.po deleted file mode 100644 index 27403c0..0000000 --- a/parts/django/tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,20 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 12:41-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "il faut traduire cette chaîne de caractères de app4" -msgstr "este texto de app4 debe ser traducido" diff --git a/parts/django/tests/regressiontests/views/fixtures/testdata.json b/parts/django/tests/regressiontests/views/fixtures/testdata.json deleted file mode 100644 index ab68407..0000000 --- a/parts/django/tests/regressiontests/views/fixtures/testdata.json +++ /dev/null @@ -1,75 +0,0 @@ -[ - { - "pk": "1", - "model": "auth.user", - "fields": { - "username": "testclient", - "first_name": "Test", - "last_name": "Client", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": 1, - "model": "views.author", - "fields": { - "name": "Boris" - } - }, - { - "pk": 1, - "model": "views.article", - "fields": { - "author": 1, - "title": "Old Article", - "slug": "old_article", - "date_created": "2001-01-01 21:22:23" - } - }, - { - "pk": 2, - "model": "views.article", - "fields": { - "author": 1, - "title": "Current Article", - "slug": "current_article", - "date_created": "2007-09-17 21:22:23" - } - }, - { - "pk": 3, - "model": "views.article", - "fields": { - "author": 1, - "title": "Future Article", - "slug": "future_article", - "date_created": "3000-01-01 21:22:23" - } - }, - { - "pk": 1, - "model": "views.urlarticle", - "fields": { - "author": 1, - "title": "Old Article", - "slug": "old_article", - "date_created": "2001-01-01 21:22:23" - } - }, - { - "pk": 1, - "model": "sites.site", - "fields": { - "domain": "testserver", - "name": "testserver" - } - } -] diff --git a/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index b6b0887..0000000 --- a/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.po deleted file mode 100644 index 669af4b..0000000 --- a/parts/django/tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,25 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 16:45+0200\n" -"PO-Revision-Date: 2010-05-12 12:57-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: media/js/translate.js:1 -msgid "this is to be translated" -msgstr "esto tiene que ser traducido" - - -msgid "Choose a time" -msgstr "Elige una hora" diff --git a/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 356147c..0000000 --- a/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.po deleted file mode 100644 index 0d03f95..0000000 --- a/parts/django/tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,24 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 19:15+0200\n" -"PO-Revision-Date: 2010-05-12 12:41-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "this is to be translated" -msgstr "il faut le traduire" - - -msgid "Choose a time" -msgstr "Choisir une heure" diff --git a/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.mo b/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.mo Binary files differdeleted file mode 100644 index 21659a9..0000000 --- a/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.mo +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.po b/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.po deleted file mode 100644 index 4ea193a..0000000 --- a/parts/django/tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.po +++ /dev/null @@ -1,24 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-09-15 16:45+0200\n" -"PO-Revision-Date: 2010-05-12 12:57-0300\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "this is to be translated" -msgstr "перевод" - - -msgid "Choose a time" -msgstr "Выберите время" diff --git a/parts/django/tests/regressiontests/views/media/file.txt b/parts/django/tests/regressiontests/views/media/file.txt deleted file mode 100644 index f1fc82c..0000000 --- a/parts/django/tests/regressiontests/views/media/file.txt +++ /dev/null @@ -1 +0,0 @@ -An example media file.
\ No newline at end of file diff --git a/parts/django/tests/regressiontests/views/media/file.txt.gz b/parts/django/tests/regressiontests/views/media/file.txt.gz Binary files differdeleted file mode 100644 index 0ee7d18..0000000 --- a/parts/django/tests/regressiontests/views/media/file.txt.gz +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/media/file.unknown b/parts/django/tests/regressiontests/views/media/file.unknown deleted file mode 100644 index 77dcda8..0000000 --- a/parts/django/tests/regressiontests/views/media/file.unknown +++ /dev/null @@ -1 +0,0 @@ -An unknown file extension. diff --git a/parts/django/tests/regressiontests/views/models.py b/parts/django/tests/regressiontests/views/models.py deleted file mode 100644 index 54f5c1c..0000000 --- a/parts/django/tests/regressiontests/views/models.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Regression tests for Django built-in views. -""" - -from django.db import models - -class Author(models.Model): - name = models.CharField(max_length=100) - - def __unicode__(self): - return self.name - - def get_absolute_url(self): - return '/views/authors/%s/' % self.id - -class BaseArticle(models.Model): - """ - An abstract article Model so that we can create article models with and - without a get_absolute_url method (for create_update generic views tests). - """ - title = models.CharField(max_length=100) - slug = models.SlugField() - author = models.ForeignKey(Author) - - class Meta: - abstract = True - - def __unicode__(self): - return self.title - -class Article(BaseArticle): - date_created = models.DateTimeField() - -class UrlArticle(BaseArticle): - """ - An Article class with a get_absolute_url defined. - """ - date_created = models.DateTimeField() - - def get_absolute_url(self): - return '/urlarticles/%s/' % self.slug - get_absolute_url.purge = True - -class DateArticle(BaseArticle): - """ - An article Model with a DateField instead of DateTimeField, - for testing #7602 - """ - date_created = models.DateField() diff --git a/parts/django/tests/regressiontests/views/templates/debug/template_exception.html b/parts/django/tests/regressiontests/views/templates/debug/template_exception.html deleted file mode 100644 index c6b34a8..0000000 --- a/parts/django/tests/regressiontests/views/templates/debug/template_exception.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load debugtags %} -{% go_boom arg %} diff --git a/parts/django/tests/regressiontests/views/templatetags/__init__.py b/parts/django/tests/regressiontests/views/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/views/templatetags/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/templatetags/debugtags.py b/parts/django/tests/regressiontests/views/templatetags/debugtags.py deleted file mode 100644 index 9b2c661..0000000 --- a/parts/django/tests/regressiontests/views/templatetags/debugtags.py +++ /dev/null @@ -1,10 +0,0 @@ -from django import template - -from regressiontests.views import BrokenException - -register = template.Library() - -@register.simple_tag -def go_boom(arg): - raise BrokenException(arg) - diff --git a/parts/django/tests/regressiontests/views/tests/__init__.py b/parts/django/tests/regressiontests/views/tests/__init__.py deleted file mode 100644 index 697968e..0000000 --- a/parts/django/tests/regressiontests/views/tests/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from debug import * -from defaults import * -from generic.create_update import * -from generic.date_based import * -from i18n import * -from specials import * -from static import * diff --git a/parts/django/tests/regressiontests/views/tests/debug.py b/parts/django/tests/regressiontests/views/tests/debug.py deleted file mode 100644 index 4ebe37f..0000000 --- a/parts/django/tests/regressiontests/views/tests/debug.py +++ /dev/null @@ -1,50 +0,0 @@ -import inspect - -from django.conf import settings -from django.core.files.uploadedfile import SimpleUploadedFile -from django.test import TestCase -from django.core.urlresolvers import reverse -from django.template import TemplateSyntaxError - -from regressiontests.views import BrokenException, except_args - -class DebugViewTests(TestCase): - def setUp(self): - self.old_debug = settings.DEBUG - settings.DEBUG = True - self.old_template_debug = settings.TEMPLATE_DEBUG - settings.TEMPLATE_DEBUG = True - - def tearDown(self): - settings.DEBUG = self.old_debug - settings.TEMPLATE_DEBUG = self.old_template_debug - - def test_files(self): - response = self.client.get('/views/raises/') - self.assertEquals(response.status_code, 500) - - data = { - 'file_data.txt': SimpleUploadedFile('file_data.txt', 'haha'), - } - response = self.client.post('/views/raises/', data) - self.assertTrue('file_data.txt' in response.content) - self.assertFalse('haha' in response.content) - - def test_404(self): - response = self.client.get('/views/raises404/') - self.assertEquals(response.status_code, 404) - - def test_view_exceptions(self): - for n in range(len(except_args)): - self.assertRaises(BrokenException, self.client.get, - reverse('view_exception', args=(n,))) - - def test_template_exceptions(self): - for n in range(len(except_args)): - try: - self.client.get(reverse('template_exception', args=(n,))) - except TemplateSyntaxError, e: - raising_loc = inspect.trace()[-1][-2][0].strip() - self.assertFalse(raising_loc.find('raise BrokenException') == -1, - "Failed to find 'raise BrokenException' in last frame of traceback, instead found: %s" % - raising_loc) diff --git a/parts/django/tests/regressiontests/views/tests/defaults.py b/parts/django/tests/regressiontests/views/tests/defaults.py deleted file mode 100644 index ffc3471..0000000 --- a/parts/django/tests/regressiontests/views/tests/defaults.py +++ /dev/null @@ -1,85 +0,0 @@ -from os import path - -from django.conf import settings -from django.test import TestCase -from django.contrib.contenttypes.models import ContentType - -from regressiontests.views.models import Author, Article, UrlArticle - -class DefaultsTests(TestCase): - """Test django views in django/views/defaults.py""" - fixtures = ['testdata.json'] - non_existing_urls = ['/views/non_existing_url/', # this is in urls.py - '/views/other_non_existing_url/'] # this NOT in urls.py - - def test_shortcut_with_absolute_url(self): - "Can view a shortcut for an Author object that has a get_absolute_url method" - for obj in Author.objects.all(): - short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk) - response = self.client.get(short_url) - self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(), - status_code=302, target_status_code=404) - - def test_shortcut_no_absolute_url(self): - "Shortcuts for an object that has no get_absolute_url method raises 404" - for obj in Article.objects.all(): - short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk) - response = self.client.get(short_url) - self.assertEquals(response.status_code, 404) - - def test_wrong_type_pk(self): - short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, 'nobody/expects') - response = self.client.get(short_url) - self.assertEquals(response.status_code, 404) - - def test_shortcut_bad_pk(self): - short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, '42424242') - response = self.client.get(short_url) - self.assertEquals(response.status_code, 404) - - def test_nonint_content_type(self): - an_author = Author.objects.all()[0] - short_url = '/views/shortcut/%s/%s/' % ('spam', an_author.pk) - response = self.client.get(short_url) - self.assertEquals(response.status_code, 404) - - def test_bad_content_type(self): - an_author = Author.objects.all()[0] - short_url = '/views/shortcut/%s/%s/' % (42424242, an_author.pk) - response = self.client.get(short_url) - self.assertEquals(response.status_code, 404) - - def test_page_not_found(self): - "A 404 status is returned by the page_not_found view" - for url in self.non_existing_urls: - response = self.client.get(url) - self.assertEquals(response.status_code, 404) - - def test_csrf_token_in_404(self): - """ - The 404 page should have the csrf_token available in the context - """ - # See ticket #14565 - old_DEBUG = settings.DEBUG - try: - settings.DEBUG = False # so we get real 404, not technical - for url in self.non_existing_urls: - response = self.client.get(url) - csrf_token = response.context['csrf_token'] - self.assertNotEqual(str(csrf_token), 'NOTPROVIDED') - self.assertNotEqual(str(csrf_token), '') - finally: - settings.DEBUG = old_DEBUG - - def test_server_error(self): - "The server_error view raises a 500 status" - response = self.client.get('/views/server_error/') - self.assertEquals(response.status_code, 500) - - def test_get_absolute_url_attributes(self): - "A model can set attributes on the get_absolute_url method" - self.assertTrue(getattr(UrlArticle.get_absolute_url, 'purge', False), - 'The attributes of the original get_absolute_url must be added.') - article = UrlArticle.objects.get(pk=1) - self.assertTrue(getattr(article.get_absolute_url, 'purge', False), - 'The attributes of the original get_absolute_url must be added.') diff --git a/parts/django/tests/regressiontests/views/tests/generic/__init__.py b/parts/django/tests/regressiontests/views/tests/generic/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/tests/regressiontests/views/tests/generic/__init__.py +++ /dev/null diff --git a/parts/django/tests/regressiontests/views/tests/generic/create_update.py b/parts/django/tests/regressiontests/views/tests/generic/create_update.py deleted file mode 100644 index 4ba1c35..0000000 --- a/parts/django/tests/regressiontests/views/tests/generic/create_update.py +++ /dev/null @@ -1,211 +0,0 @@ -import datetime - -from django.test import TestCase -from django.core.exceptions import ImproperlyConfigured -from regressiontests.views.models import Article, UrlArticle - -class CreateObjectTest(TestCase): - - fixtures = ['testdata.json'] - - def test_login_required_view(self): - """ - Verifies that an unauthenticated user attempting to access a - login_required view gets redirected to the login page and that - an authenticated user is let through. - """ - view_url = '/views/create_update/member/create/article/' - response = self.client.get(view_url) - self.assertRedirects(response, '/accounts/login/?next=%s' % view_url) - # Now login and try again. - login = self.client.login(username='testclient', password='password') - self.assertTrue(login, 'Could not log in') - response = self.client.get(view_url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'views/article_form.html') - - def test_create_article_display_page(self): - """ - Ensures the generic view returned the page and contains a form. - """ - view_url = '/views/create_update/create/article/' - response = self.client.get(view_url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'views/article_form.html') - if not response.context.get('form'): - self.fail('No form found in the response.') - - def test_create_article_with_errors(self): - """ - POSTs a form that contains validation errors. - """ - view_url = '/views/create_update/create/article/' - num_articles = Article.objects.count() - response = self.client.post(view_url, { - 'title': 'My First Article', - }) - self.assertFormError(response, 'form', 'slug', [u'This field is required.']) - self.assertTemplateUsed(response, 'views/article_form.html') - self.assertEqual(num_articles, Article.objects.count(), - "Number of Articles should not have changed.") - - def test_create_custom_save_article(self): - """ - Creates a new article using a custom form class with a save method - that alters the slug entered. - """ - view_url = '/views/create_update/create_custom/article/' - response = self.client.post(view_url, { - 'title': 'Test Article', - 'slug': 'this-should-get-replaced', - 'author': 1, - 'date_created': datetime.datetime(2007, 6, 25), - }) - self.assertRedirects(response, - '/views/create_update/view/article/some-other-slug/', - target_status_code=404) - -class UpdateDeleteObjectTest(TestCase): - - fixtures = ['testdata.json'] - - def test_update_object_form_display(self): - """ - Verifies that the form was created properly and with initial values. - """ - response = self.client.get('/views/create_update/update/article/old_article/') - self.assertTemplateUsed(response, 'views/article_form.html') - self.assertEquals(unicode(response.context['form']['title']), - u'<input id="id_title" type="text" name="title" value="Old Article" maxlength="100" />') - - def test_update_object(self): - """ - Verifies the updating of an Article. - """ - response = self.client.post('/views/create_update/update/article/old_article/', { - 'title': 'Another Article', - 'slug': 'another-article-slug', - 'author': 1, - 'date_created': datetime.datetime(2007, 6, 25), - }) - article = Article.objects.get(pk=1) - self.assertEquals(article.title, "Another Article") - - def test_delete_object_confirm(self): - """ - Verifies the confirm deletion page is displayed using a GET. - """ - response = self.client.get('/views/create_update/delete/article/old_article/') - self.assertTemplateUsed(response, 'views/article_confirm_delete.html') - - def test_delete_object(self): - """ - Verifies the object actually gets deleted on a POST. - """ - view_url = '/views/create_update/delete/article/old_article/' - response = self.client.post(view_url) - try: - Article.objects.get(slug='old_article') - except Article.DoesNotExist: - pass - else: - self.fail('Object was not deleted.') - -class PostSaveRedirectTests(TestCase): - """ - Verifies that the views redirect to the correct locations depending on - if a post_save_redirect was passed and a get_absolute_url method exists - on the Model. - """ - - fixtures = ['testdata.json'] - article_model = Article - - create_url = '/views/create_update/create/article/' - update_url = '/views/create_update/update/article/old_article/' - delete_url = '/views/create_update/delete/article/old_article/' - - create_redirect = '/views/create_update/view/article/my-first-article/' - update_redirect = '/views/create_update/view/article/another-article-slug/' - delete_redirect = '/views/create_update/' - - def test_create_article(self): - num_articles = self.article_model.objects.count() - response = self.client.post(self.create_url, { - 'title': 'My First Article', - 'slug': 'my-first-article', - 'author': '1', - 'date_created': datetime.datetime(2007, 6, 25), - }) - self.assertRedirects(response, self.create_redirect, - target_status_code=404) - self.assertEqual(num_articles + 1, self.article_model.objects.count(), - "A new Article should have been created.") - - def test_update_article(self): - num_articles = self.article_model.objects.count() - response = self.client.post(self.update_url, { - 'title': 'Another Article', - 'slug': 'another-article-slug', - 'author': 1, - 'date_created': datetime.datetime(2007, 6, 25), - }) - self.assertRedirects(response, self.update_redirect, - target_status_code=404) - self.assertEqual(num_articles, self.article_model.objects.count(), - "A new Article should not have been created.") - - def test_delete_article(self): - num_articles = self.article_model.objects.count() - response = self.client.post(self.delete_url) - self.assertRedirects(response, self.delete_redirect, - target_status_code=404) - self.assertEqual(num_articles - 1, self.article_model.objects.count(), - "An Article should have been deleted.") - -class NoPostSaveNoAbsoluteUrl(PostSaveRedirectTests): - """ - Tests that when no post_save_redirect is passed and no get_absolute_url - method exists on the Model that the view raises an ImproperlyConfigured - error. - """ - - create_url = '/views/create_update/no_redirect/create/article/' - update_url = '/views/create_update/no_redirect/update/article/old_article/' - - def test_create_article(self): - self.assertRaises(ImproperlyConfigured, - super(NoPostSaveNoAbsoluteUrl, self).test_create_article) - - def test_update_article(self): - self.assertRaises(ImproperlyConfigured, - super(NoPostSaveNoAbsoluteUrl, self).test_update_article) - - def test_delete_article(self): - """ - The delete_object view requires a post_delete_redirect, so skip testing - here. - """ - pass - -class AbsoluteUrlNoPostSave(PostSaveRedirectTests): - """ - Tests that the views redirect to the Model's get_absolute_url when no - post_save_redirect is passed. - """ - - # Article model with get_absolute_url method. - article_model = UrlArticle - - create_url = '/views/create_update/no_url/create/article/' - update_url = '/views/create_update/no_url/update/article/old_article/' - - create_redirect = '/urlarticles/my-first-article/' - update_redirect = '/urlarticles/another-article-slug/' - - def test_delete_article(self): - """ - The delete_object view requires a post_delete_redirect, so skip testing - here. - """ - pass diff --git a/parts/django/tests/regressiontests/views/tests/generic/date_based.py b/parts/django/tests/regressiontests/views/tests/generic/date_based.py deleted file mode 100644 index c6ba562..0000000 --- a/parts/django/tests/regressiontests/views/tests/generic/date_based.py +++ /dev/null @@ -1,140 +0,0 @@ -# coding: utf-8 -from django.test import TestCase -from datetime import datetime, date -from datetime import timedelta -from regressiontests.views.models import Article, Author, DateArticle - -class ObjectDetailTest(TestCase): - fixtures = ['testdata.json'] - def setUp(self): - # Correct the date for the current article - current_article = Article.objects.get(title="Current Article") - current_article.date_created = datetime.now() - current_article.save() - - def test_finds_past(self): - "date_based.object_detail can view a page in the past" - response = self.client.get('/views/date_based/object_detail/2001/01/01/old_article/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['object'].title, "Old Article") - - def test_object_detail_finds_today(self): - "date_based.object_detail can view a page from today" - today_url = datetime.now().strftime('%Y/%m/%d') - response = self.client.get('/views/date_based/object_detail/%s/current_article/' % today_url) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['object'].title, "Current Article") - - def test_object_detail_ignores_future(self): - "date_based.object_detail can view a page from the future, but only if allowed." - response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/') - self.assertEqual(response.status_code, 404) - - def test_object_detail_allowed_future_if_enabled(self): - "date_based.object_detail can view a page from the future if explicitly allowed." - response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/allow_future/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['object'].title, "Future Article") - -class MonthArchiveTest(TestCase): - def test_archive_month_includes_only_month(self): - "Regression for #3031: Archives around Feburary include only one month" - author = Author(name="John Smith") - author.save() - - # 2004 was a leap year, so it should be weird enough to not cheat - first_second_of_feb = datetime(2004, 2, 1, 0, 0, 1) - first_second_of_mar = datetime(2004, 3, 1, 0, 0, 1) - two_seconds = timedelta(0, 2, 0) - article = Article(title="example", author=author) - - article.date_created = first_second_of_feb - article.save() - response = self.client.get('/views/date_based/archive_month/2004/02/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['next_month'], date(2004, 3, 1)) - self.assertEqual(response.context['previous_month'], date(2004, 1, 1)) - - article.date_created = first_second_of_feb-two_seconds - article.save() - response = self.client.get('/views/date_based/archive_month/2004/02/') - self.assertEqual(response.status_code, 404) - - article.date_created = first_second_of_mar-two_seconds - article.save() - response = self.client.get('/views/date_based/archive_month/2004/02/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['next_month'], date(2004, 3, 1)) - self.assertEqual(response.context['previous_month'], date(2004, 1, 1)) - - article.date_created = first_second_of_mar - article.save() - response = self.client.get('/views/date_based/archive_month/2004/02/') - self.assertEqual(response.status_code, 404) - - article2 = DateArticle(title="example", author=author) - - article2.date_created = first_second_of_feb.date() - article2.save() - response = self.client.get('/views/date_based/datefield/archive_month/2004/02/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['next_month'], date(2004, 3, 1)) - self.assertEqual(response.context['previous_month'], date(2004, 1, 1)) - - article2.date_created = (first_second_of_feb-two_seconds).date() - article2.save() - response = self.client.get('/views/date_based/datefield/archive_month/2004/02/') - self.assertEqual(response.status_code, 404) - - article2.date_created = (first_second_of_mar-two_seconds).date() - article2.save() - response = self.client.get('/views/date_based/datefield/archive_month/2004/02/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['next_month'], date(2004, 3, 1)) - self.assertEqual(response.context['previous_month'], date(2004, 1, 1)) - - article2.date_created = first_second_of_mar.date() - article2.save() - response = self.client.get('/views/date_based/datefield/archive_month/2004/02/') - self.assertEqual(response.status_code, 404) - - now = datetime.now() - prev_month = now.date().replace(day=1) - if prev_month.month == 1: - prev_month = prev_month.replace(year=prev_month.year-1, month=12) - else: - prev_month = prev_month.replace(month=prev_month.month-1) - article2.date_created = now - article2.save() - response = self.client.get('/views/date_based/datefield/archive_month/%s/' % now.strftime('%Y/%m')) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['next_month'], None) - self.assertEqual(response.context['previous_month'], prev_month) - - def test_archive_month_date_list(self): - author = Author(name="John Smith") - author.save() - date1 = datetime(2010, 1, 1, 0, 0, 0) - date2 = datetime(2010, 1, 2, 0, 0, 0) - Article.objects.create(title='example1', author=author, date_created=date1) - Article.objects.create(title='example2', author=author, date_created=date2) - response = self.client.get('/views/date_based/archive_month/2010/1/') - self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['date_list']), 2) - self.assertEqual(response.context['date_list'][0], date1) - # Checks that the same date is not included more than once in the list - Article.objects.create(title='example2', author=author, date_created=date2) - response = self.client.get('/views/date_based/archive_month/2010/1/') - self.assertEqual(len(response.context['date_list']), 2) - -class DayArchiveTests(TestCase): - - def test_year_month_day_format(self): - """ - Make sure day views don't get confused with numeric month formats (#7944) - """ - author = Author.objects.create(name="John Smith") - article = Article.objects.create(title="example", author=author, date_created=datetime(2004, 1, 21, 0, 0, 1)) - response = self.client.get('/views/date_based/archive_day/2004/1/21/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['object_list'][0], article) diff --git a/parts/django/tests/regressiontests/views/tests/i18n.py b/parts/django/tests/regressiontests/views/tests/i18n.py deleted file mode 100644 index 24aa933..0000000 --- a/parts/django/tests/regressiontests/views/tests/i18n.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding:utf-8 -*- -import gettext - -from django.conf import settings -from django.test import TestCase -from django.utils.translation import activate, deactivate -from django.utils.text import javascript_quote - -from regressiontests.views.urls import locale_dir - -class I18NTests(TestCase): - """ Tests django views in django/views/i18n.py """ - - def test_setlang(self): - """The set_language view can be used to change the session language""" - for lang_code, lang_name in settings.LANGUAGES: - post_data = dict(language=lang_code, next='/views/') - response = self.client.post('/views/i18n/setlang/', data=post_data) - self.assertRedirects(response, 'http://testserver/views/') - self.assertEquals(self.client.session['django_language'], lang_code) - - def test_jsi18n(self): - """The javascript_catalog can be deployed with language settings""" - for lang_code in ['es', 'fr', 'ru']: - activate(lang_code) - catalog = gettext.translation('djangojs', locale_dir, [lang_code]) - trans_txt = catalog.ugettext('this is to be translated') - response = self.client.get('/views/jsi18n/') - # in response content must to be a line like that: - # catalog['this is to be translated'] = 'same_that_trans_txt' - # javascript_quote is used to be able to check unicode strings - self.assertContains(response, javascript_quote(trans_txt), 1) - - -class JsI18NTests(TestCase): - """ - Tests django views in django/views/i18n.py that need to change - settings.LANGUAGE_CODE. - """ - - def setUp(self): - self.old_language_code = settings.LANGUAGE_CODE - self.old_installed_apps = settings.INSTALLED_APPS - - def tearDown(self): - deactivate() - settings.LANGUAGE_CODE = self.old_language_code - settings.INSTALLED_APPS = self.old_installed_apps - - def test_jsi18n_with_missing_en_files(self): - """ - The javascript_catalog shouldn't load the fallback language in the - case that the current selected language is actually the one translated - from, and hence missing translation files completely. - - This happens easily when you're translating from English to other - languages and you've set settings.LANGUAGE_CODE to some other language - than English. - """ - settings.LANGUAGE_CODE = 'es' - activate('en-us') - response = self.client.get('/views/jsi18n/') - self.assertNotContains(response, 'esto tiene que ser traducido') - - def test_jsi18n_fallback_language(self): - """ - Let's make sure that the fallback language is still working properly - in cases where the selected language cannot be found. - """ - settings.LANGUAGE_CODE = 'fr' - activate('fi') - response = self.client.get('/views/jsi18n/') - self.assertContains(response, 'il faut le traduire') - - def testI18NLanguageNonEnglishDefault(self): - """ - Check if the Javascript i18n view returns an empty language catalog - if the default language is non-English, the selected language - is English and there is not 'en' translation available. See #13388, - #3594 and #13726 for more details. - """ - settings.LANGUAGE_CODE = 'fr' - activate('en-us') - response = self.client.get('/views/jsi18n/') - self.assertNotContains(response, 'Choisir une heure') - - def test_nonenglish_default_english_userpref(self): - """ - Same as above with the difference that there IS an 'en' translation - available. The Javascript i18n view must return a NON empty language catalog - with the proper English translations. See #13726 for more details. - """ - settings.LANGUAGE_CODE = 'fr' - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.views.app0'] - activate('en-us') - response = self.client.get('/views/jsi18n_english_translation/') - self.assertContains(response, javascript_quote('this app0 string is to be translated')) - - def testI18NLanguageNonEnglishFallback(self): - """ - Makes sure that the fallback language is still working properly - in cases where the selected language cannot be found. - """ - settings.LANGUAGE_CODE = 'fr' - activate('none') - response = self.client.get('/views/jsi18n/') - self.assertContains(response, 'Choisir une heure') - - -class JsI18NTestsMultiPackage(TestCase): - """ - Tests for django views in django/views/i18n.py that need to change - settings.LANGUAGE_CODE and merge JS translation from several packages. - """ - - def setUp(self): - self.old_language_code = settings.LANGUAGE_CODE - self.old_installed_apps = settings.INSTALLED_APPS - - def tearDown(self): - settings.LANGUAGE_CODE = self.old_language_code - settings.INSTALLED_APPS = self.old_installed_apps - - def testI18NLanguageEnglishDefault(self): - """ - Check if the JavaScript i18n view returns a complete language catalog - if the default language is en-us, the selected language has a - translation available and a catalog composed by djangojs domain - translations of multiple Python packages is requested. See #13388, - #3594 and #13514 for more details. - """ - settings.LANGUAGE_CODE = 'en-us' - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.views.app1', 'regressiontests.views.app2'] - activate('fr') - response = self.client.get('/views/jsi18n_multi_packages1/') - self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1')) - deactivate() - - def testI18NDifferentNonEnLangs(self): - """ - Similar to above but with neither default or requested language being - English. - """ - settings.LANGUAGE_CODE = 'fr' - settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.views.app3', 'regressiontests.views.app4'] - activate('es-ar') - response = self.client.get('/views/jsi18n_multi_packages2/') - self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido')) - deactivate() diff --git a/parts/django/tests/regressiontests/views/tests/specials.py b/parts/django/tests/regressiontests/views/tests/specials.py deleted file mode 100644 index bcdffca..0000000 --- a/parts/django/tests/regressiontests/views/tests/specials.py +++ /dev/null @@ -1,35 +0,0 @@ -# coding: utf-8 -from django.test import TestCase - -class URLHandling(TestCase): - """ - Tests for URL handling in views and responses. - """ - redirect_target = "/views/%E4%B8%AD%E6%96%87/target/" - - def test_combining_redirect(self): - """ - Tests that redirecting to an IRI, requiring encoding before we use it - in an HTTP response, is handled correctly. In this case the arg to - HttpRedirect is ASCII but the current request path contains non-ASCII - characters so this test ensures the creation of the full path with a - base non-ASCII part is handled correctly. - """ - response = self.client.get(u'/views/中文/') - self.assertRedirects(response, self.redirect_target) - - def test_nonascii_redirect(self): - """ - Tests that a non-ASCII argument to HttpRedirect is handled properly. - """ - response = self.client.get('/views/nonascii_redirect/') - self.assertRedirects(response, self.redirect_target) - - def test_permanent_nonascii_redirect(self): - """ - Tests that a non-ASCII argument to HttpPermanentRedirect is handled - properly. - """ - response = self.client.get('/views/permanent_nonascii_redirect/') - self.assertRedirects(response, self.redirect_target, status_code=301) - diff --git a/parts/django/tests/regressiontests/views/tests/static.py b/parts/django/tests/regressiontests/views/tests/static.py deleted file mode 100644 index de0bd51..0000000 --- a/parts/django/tests/regressiontests/views/tests/static.py +++ /dev/null @@ -1,77 +0,0 @@ -import mimetypes -from os import path - -from django.test import TestCase -from django.http import HttpResponseNotModified -from regressiontests.views.urls import media_dir - -class StaticTests(TestCase): - """Tests django views in django/views/static.py""" - - def test_serve(self): - "The static view can serve static media" - media_files = ['file.txt', 'file.txt.gz'] - for filename in media_files: - response = self.client.get('/views/site_media/%s' % filename) - file_path = path.join(media_dir, filename) - self.assertEquals(open(file_path).read(), response.content) - self.assertEquals(len(response.content), int(response['Content-Length'])) - self.assertEquals(mimetypes.guess_type(file_path)[1], response.get('Content-Encoding', None)) - - def test_unknown_mime_type(self): - response = self.client.get('/views/site_media/file.unknown') - self.assertEquals('application/octet-stream', response['Content-Type']) - - def test_copes_with_empty_path_component(self): - file_name = 'file.txt' - response = self.client.get('/views/site_media//%s' % file_name) - file = open(path.join(media_dir, file_name)) - self.assertEquals(file.read(), response.content) - - def test_is_modified_since(self): - file_name = 'file.txt' - response = self.client.get( - '/views/site_media/%s' % file_name, - HTTP_IF_MODIFIED_SINCE='Thu, 1 Jan 1970 00:00:00 GMT') - file = open(path.join(media_dir, file_name)) - self.assertEquals(file.read(), response.content) - - def test_not_modified_since(self): - file_name = 'file.txt' - response = self.client.get( - '/views/site_media/%s' % file_name, - HTTP_IF_MODIFIED_SINCE='Mon, 18 Jan 2038 05:14:07 UTC' - # This is 24h before max Unix time. Remember to fix Django and - # update this test well before 2038 :) - ) - self.assertTrue(isinstance(response, HttpResponseNotModified)) - - def test_invalid_if_modified_since(self): - """Handle bogus If-Modified-Since values gracefully - - Assume that a file is modified since an invalid timestamp as per RFC - 2616, section 14.25. - """ - file_name = 'file.txt' - invalid_date = 'Mon, 28 May 999999999999 28:25:26 GMT' - response = self.client.get('/views/site_media/%s' % file_name, - HTTP_IF_MODIFIED_SINCE=invalid_date) - file = open(path.join(media_dir, file_name)) - self.assertEquals(file.read(), response.content) - self.assertEquals(len(response.content), - int(response['Content-Length'])) - - def test_invalid_if_modified_since2(self): - """Handle even more bogus If-Modified-Since values gracefully - - Assume that a file is modified since an invalid timestamp as per RFC - 2616, section 14.25. - """ - file_name = 'file.txt' - invalid_date = ': 1291108438, Wed, 20 Oct 2010 14:05:00 GMT' - response = self.client.get('/views/site_media/%s' % file_name, - HTTP_IF_MODIFIED_SINCE=invalid_date) - file = open(path.join(media_dir, file_name)) - self.assertEquals(file.read(), response.content) - self.assertEquals(len(response.content), - int(response['Content-Length'])) diff --git a/parts/django/tests/regressiontests/views/urls.py b/parts/django/tests/regressiontests/views/urls.py deleted file mode 100644 index 0ccb988..0000000 --- a/parts/django/tests/regressiontests/views/urls.py +++ /dev/null @@ -1,131 +0,0 @@ -# coding: utf-8 -from os import path - -from django.conf.urls.defaults import * - -from models import * -import views - - -base_dir = path.dirname(path.abspath(__file__)) -media_dir = path.join(base_dir, 'media') -locale_dir = path.join(base_dir, 'locale') - -js_info_dict = { - 'domain': 'djangojs', - 'packages': ('regressiontests.views',), -} - -js_info_dict_english_translation = { - 'domain': 'djangojs', - 'packages': ('regressiontests.views.app0',), -} - -js_info_dict_multi_packages1 = { - 'domain': 'djangojs', - 'packages': ('regressiontests.views.app1', 'regressiontests.views.app2'), -} - -js_info_dict_multi_packages2 = { - 'domain': 'djangojs', - 'packages': ('regressiontests.views.app3', 'regressiontests.views.app4'), -} - -date_based_info_dict = { - 'queryset': Article.objects.all(), - 'date_field': 'date_created', - 'month_format': '%m', -} -numeric_days_info_dict = dict(date_based_info_dict, day_format='%d') - -date_based_datefield_info_dict = dict(date_based_info_dict, queryset=DateArticle.objects.all()) - -urlpatterns = patterns('', - (r'^$', views.index_page), - - # Default views - (r'^shortcut/(\d+)/(.*)/$', 'django.views.defaults.shortcut'), - (r'^non_existing_url/', 'django.views.defaults.page_not_found'), - (r'^server_error/', 'django.views.defaults.server_error'), - - # i18n views - (r'^i18n/', include('django.conf.urls.i18n')), - (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), - (r'^jsi18n_english_translation/$', 'django.views.i18n.javascript_catalog', js_info_dict_english_translation), - (r'^jsi18n_multi_packages1/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages1), - (r'^jsi18n_multi_packages2/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages2), - - # Static views - (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': media_dir}), - - # Special URLs for particular regression cases. - url(u'^中文/$', 'regressiontests.views.views.redirect'), - url(u'^中文/target/$', 'regressiontests.views.views.index_page'), -) - -# Date-based generic views. -urlpatterns += patterns('django.views.generic.date_based', - (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$', - 'object_detail', - dict(slug_field='slug', **date_based_info_dict)), - (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/allow_future/$', - 'object_detail', - dict(allow_future=True, slug_field='slug', **date_based_info_dict)), - (r'^date_based/archive_day/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', - 'archive_day', - numeric_days_info_dict), - (r'^date_based/archive_month/(?P<year>\d{4})/(?P<month>\d{1,2})/$', - 'archive_month', - date_based_info_dict), - (r'^date_based/datefield/archive_month/(?P<year>\d{4})/(?P<month>\d{1,2})/$', - 'archive_month', - date_based_datefield_info_dict), -) - -# crud generic views. - -urlpatterns += patterns('django.views.generic.create_update', - (r'^create_update/member/create/article/$', 'create_object', - dict(login_required=True, model=Article)), - (r'^create_update/create/article/$', 'create_object', - dict(post_save_redirect='/views/create_update/view/article/%(slug)s/', - model=Article)), - (r'^create_update/update/article/(?P<slug>[-\w]+)/$', 'update_object', - dict(post_save_redirect='/views/create_update/view/article/%(slug)s/', - slug_field='slug', model=Article)), - (r'^create_update/create_custom/article/$', views.custom_create), - (r'^create_update/delete/article/(?P<slug>[-\w]+)/$', 'delete_object', - dict(post_delete_redirect='/views/create_update/', slug_field='slug', - model=Article)), - - # No post_save_redirect and no get_absolute_url on model. - (r'^create_update/no_redirect/create/article/$', 'create_object', - dict(model=Article)), - (r'^create_update/no_redirect/update/article/(?P<slug>[-\w]+)/$', - 'update_object', dict(slug_field='slug', model=Article)), - - # get_absolute_url on model, but no passed post_save_redirect. - (r'^create_update/no_url/create/article/$', 'create_object', - dict(model=UrlArticle)), - (r'^create_update/no_url/update/article/(?P<slug>[-\w]+)/$', - 'update_object', dict(slug_field='slug', model=UrlArticle)), -) - -# a view that raises an exception for the debug view -urlpatterns += patterns('', - (r'^raises/$', views.raises), - (r'^raises404/$', views.raises404), -) - -# rediriects, both temporary and permanent, with non-ASCII targets -urlpatterns += patterns('django.views.generic.simple', - ('^nonascii_redirect/$', 'redirect_to', - {'url': u'/views/中文/target/', 'permanent': False}), - ('^permanent_nonascii_redirect/$', 'redirect_to', - {'url': u'/views/中文/target/', 'permanent': True}), -) - -urlpatterns += patterns('regressiontests.views.views', - url(r'view_exception/(?P<n>\d+)/$', 'view_exception', name='view_exception'), - url(r'template_exception/(?P<n>\d+)/$', 'template_exception', name='template_exception'), -) diff --git a/parts/django/tests/regressiontests/views/views.py b/parts/django/tests/regressiontests/views/views.py deleted file mode 100644 index 445b4ed..0000000 --- a/parts/django/tests/regressiontests/views/views.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys - -from django.http import HttpResponse, HttpResponseRedirect -from django import forms -from django.views.debug import technical_500_response -from django.views.generic.create_update import create_object -from django.core.urlresolvers import get_resolver -from django.shortcuts import render_to_response - -from regressiontests.views import BrokenException, except_args - -from models import Article - - -def index_page(request): - """Dummy index page""" - return HttpResponse('<html><body>Dummy page</body></html>') - -def custom_create(request): - """ - Calls create_object generic view with a custom form class. - """ - class SlugChangingArticleForm(forms.ModelForm): - """Custom form class to overwrite the slug.""" - - class Meta: - model = Article - - def save(self, *args, **kwargs): - self.instance.slug = 'some-other-slug' - return super(SlugChangingArticleForm, self).save(*args, **kwargs) - - return create_object(request, - post_save_redirect='/views/create_update/view/article/%(slug)s/', - form_class=SlugChangingArticleForm) - -def raises(request): - try: - raise Exception - except Exception: - return technical_500_response(request, *sys.exc_info()) - -def raises404(request): - resolver = get_resolver(None) - resolver.resolve('') - -def redirect(request): - """ - Forces an HTTP redirect. - """ - return HttpResponseRedirect("target/") - -def view_exception(request, n): - raise BrokenException(except_args[int(n)]) - -def template_exception(request, n): - return render_to_response('debug/template_exception.html', - {'arg': except_args[int(n)]}) - diff --git a/parts/django/tests/runtests.py b/parts/django/tests/runtests.py deleted file mode 100755 index 3dde214..0000000 --- a/parts/django/tests/runtests.py +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/env python - -import os, subprocess, sys, traceback -import unittest - -import django.contrib as contrib - -CONTRIB_DIR_NAME = 'django.contrib' -MODEL_TESTS_DIR_NAME = 'modeltests' -REGRESSION_TESTS_DIR_NAME = 'regressiontests' - -TEST_TEMPLATE_DIR = 'templates' - -CONTRIB_DIR = os.path.dirname(contrib.__file__) -MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME) -REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME) - -REGRESSION_SUBDIRS_TO_SKIP = ['locale'] - -ALWAYS_INSTALLED_APPS = [ - 'django.contrib.contenttypes', - 'django.contrib.auth', - 'django.contrib.sites', - 'django.contrib.flatpages', - 'django.contrib.redirects', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.comments', - 'django.contrib.admin', - 'django.contrib.admindocs', -] - -def geodjango(settings): - # All databases must have spatial backends to run GeoDjango tests. - spatial_dbs = [name for name, db_dict in settings.DATABASES.items() - if db_dict['ENGINE'].startswith('django.contrib.gis')] - return len(spatial_dbs) == len(settings.DATABASES) - -def get_test_models(): - models = [] - for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR): - for f in os.listdir(dirpath): - if f.startswith('__init__') or f.startswith('.') or \ - f.startswith('sql') or f.startswith('invalid') or \ - os.path.basename(f) in REGRESSION_SUBDIRS_TO_SKIP: - continue - models.append((loc, f)) - return models - -def get_invalid_models(): - models = [] - for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR): - for f in os.listdir(dirpath): - if f.startswith('__init__') or f.startswith('.') or f.startswith('sql'): - continue - if f.startswith('invalid'): - models.append((loc, f)) - return models - -class InvalidModelTestCase(unittest.TestCase): - def __init__(self, model_label): - unittest.TestCase.__init__(self) - self.model_label = model_label - - def runTest(self): - from django.core.management.validation import get_validation_errors - from django.db.models.loading import load_app - from cStringIO import StringIO - - try: - module = load_app(self.model_label) - except Exception, e: - self.fail('Unable to load invalid model module') - - # Make sure sys.stdout is not a tty so that we get errors without - # coloring attached (makes matching the results easier). We restore - # sys.stderr afterwards. - orig_stdout = sys.stdout - s = StringIO() - sys.stdout = s - count = get_validation_errors(s, module) - sys.stdout = orig_stdout - s.seek(0) - error_log = s.read() - actual = error_log.split('\n') - expected = module.model_errors.split('\n') - - unexpected = [err for err in actual if err not in expected] - missing = [err for err in expected if err not in actual] - - self.assert_(not unexpected, "Unexpected Errors: " + '\n'.join(unexpected)) - self.assert_(not missing, "Missing Errors: " + '\n'.join(missing)) - -def setup(verbosity, test_labels): - from django.conf import settings - state = { - 'INSTALLED_APPS': settings.INSTALLED_APPS, - 'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""), - 'TEMPLATE_DIRS': settings.TEMPLATE_DIRS, - 'USE_I18N': settings.USE_I18N, - 'LOGIN_URL': settings.LOGIN_URL, - 'LANGUAGE_CODE': settings.LANGUAGE_CODE, - 'MIDDLEWARE_CLASSES': settings.MIDDLEWARE_CLASSES, - } - - # Redirect some settings for the duration of these tests. - settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS - settings.ROOT_URLCONF = 'urls' - settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), TEST_TEMPLATE_DIR),) - settings.USE_I18N = True - settings.LANGUAGE_CODE = 'en' - settings.LOGIN_URL = '/accounts/login/' - settings.MIDDLEWARE_CLASSES = ( - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.common.CommonMiddleware', - ) - settings.SITE_ID = 1 - # For testing comment-utils, we require the MANAGERS attribute - # to be set, so that a test email is sent out which we catch - # in our tests. - settings.MANAGERS = ("admin@djangoproject.com",) - - # Load all the ALWAYS_INSTALLED_APPS. - # (This import statement is intentionally delayed until after we - # access settings because of the USE_I18N dependency.) - from django.db.models.loading import get_apps, load_app - get_apps() - - # Load all the test model apps. - test_labels_set = set([label.split('.')[0] for label in test_labels]) - test_models = get_test_models() - - # If GeoDjango, then we'll want to add in the test applications - # that are a part of its test suite. - if geodjango(settings): - from django.contrib.gis.tests import geo_apps - test_models.extend(geo_apps(runtests=True)) - - for model_dir, model_name in test_models: - model_label = '.'.join([model_dir, model_name]) - # if the model was named on the command line, or - # no models were named (i.e., run all), import - # this model and add it to the list to test. - if not test_labels or model_name in test_labels_set: - if verbosity >= 1: - print "Importing model %s" % model_name - mod = load_app(model_label) - if mod: - if model_label not in settings.INSTALLED_APPS: - settings.INSTALLED_APPS.append(model_label) - - return state - -def teardown(state): - from django.conf import settings - # Restore the old settings. - for key, value in state.items(): - setattr(settings, key, value) - -def django_tests(verbosity, interactive, failfast, test_labels): - from django.conf import settings - state = setup(verbosity, test_labels) - - # Add tests for invalid models. - extra_tests = [] - for model_dir, model_name in get_invalid_models(): - model_label = '.'.join([model_dir, model_name]) - if not test_labels or model_name in test_labels: - extra_tests.append(InvalidModelTestCase(model_label)) - try: - # Invalid models are not working apps, so we cannot pass them into - # the test runner with the other test_labels - test_labels.remove(model_name) - except ValueError: - pass - - # If GeoDjango is used, add it's tests that aren't a part of - # an application (e.g., GEOS, GDAL, Distance objects). - if geodjango(settings): - from django.contrib.gis.tests import geodjango_suite - extra_tests.append(geodjango_suite(apps=False)) - - # Run the test suite, including the extra validation tests. - from django.test.utils import get_runner - if not hasattr(settings, 'TEST_RUNNER'): - settings.TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner' - TestRunner = get_runner(settings) - - if hasattr(TestRunner, 'func_name'): - # Pre 1.2 test runners were just functions, - # and did not support the 'failfast' option. - import warnings - warnings.warn( - 'Function-based test runners are deprecated. Test runners should be classes with a run_tests() method.', - PendingDeprecationWarning - ) - failures = TestRunner(test_labels, verbosity=verbosity, interactive=interactive, - extra_tests=extra_tests) - else: - test_runner = TestRunner(verbosity=verbosity, interactive=interactive, failfast=failfast) - failures = test_runner.run_tests(test_labels, extra_tests=extra_tests) - - teardown(state) - return failures - - -def bisect_tests(bisection_label, options, test_labels): - state = setup(int(options.verbosity), test_labels) - - if not test_labels: - # Get the full list of test labels to use for bisection - from django.db.models.loading import get_apps - test_labels = [app.__name__.split('.')[-2] for app in get_apps()] - - print '***** Bisecting test suite:',' '.join(test_labels) - - # Make sure the bisection point isn't in the test list - # Also remove tests that need to be run in specific combinations - for label in [bisection_label, 'model_inheritance_same_model_name']: - try: - test_labels.remove(label) - except ValueError: - pass - - subprocess_args = ['python','runtests.py', '--settings=%s' % options.settings] - if options.failfast: - subprocess_args.append('--failfast') - if options.verbosity: - subprocess_args.append('--verbosity=%s' % options.verbosity) - if not options.interactive: - subprocess_args.append('--noinput') - - iteration = 1 - while len(test_labels) > 1: - midpoint = len(test_labels)/2 - test_labels_a = test_labels[:midpoint] + [bisection_label] - test_labels_b = test_labels[midpoint:] + [bisection_label] - print '***** Pass %da: Running the first half of the test suite' % iteration - print '***** Test labels:',' '.join(test_labels_a) - failures_a = subprocess.call(subprocess_args + test_labels_a) - - print '***** Pass %db: Running the second half of the test suite' % iteration - print '***** Test labels:',' '.join(test_labels_b) - print - failures_b = subprocess.call(subprocess_args + test_labels_b) - - if failures_a and not failures_b: - print "***** Problem found in first half. Bisecting again..." - iteration = iteration + 1 - test_labels = test_labels_a[:-1] - elif failures_b and not failures_a: - print "***** Problem found in second half. Bisecting again..." - iteration = iteration + 1 - test_labels = test_labels_b[:-1] - elif failures_a and failures_b: - print "***** Multiple sources of failure found" - break - else: - print "***** No source of failure found... try pair execution (--pair)" - break - - if len(test_labels) == 1: - print "***** Source of error:",test_labels[0] - teardown(state) - -def paired_tests(paired_test, options, test_labels): - state = setup(int(options.verbosity), test_labels) - - if not test_labels: - print "" - # Get the full list of test labels to use for bisection - from django.db.models.loading import get_apps - test_labels = [app.__name__.split('.')[-2] for app in get_apps()] - - print '***** Trying paired execution' - - # Make sure the bisection point isn't in the test list - # Also remove tests that need to be run in specific combinations - for label in [paired_test, 'model_inheritance_same_model_name']: - try: - test_labels.remove(label) - except ValueError: - pass - - subprocess_args = ['python','runtests.py', '--settings=%s' % options.settings] - if options.failfast: - subprocess_args.append('--failfast') - if options.verbosity: - subprocess_args.append('--verbosity=%s' % options.verbosity) - if not options.interactive: - subprocess_args.append('--noinput') - - for i, label in enumerate(test_labels): - print '***** %d of %d: Check test pairing with %s' % (i+1, len(test_labels), label) - failures = subprocess.call(subprocess_args + [label, paired_test]) - if failures: - print '***** Found problem pair with',label - return - - print '***** No problem pair found' - teardown(state) - -if __name__ == "__main__": - from optparse import OptionParser - usage = "%prog [options] [model model model ...]" - parser = OptionParser(usage=usage) - parser.add_option('-v','--verbosity', action='store', dest='verbosity', default='0', - type='choice', choices=['0', '1', '2'], - help='Verbosity level; 0=minimal output, 1=normal output, 2=all output') - parser.add_option('--noinput', action='store_false', dest='interactive', default=True, - help='Tells Django to NOT prompt the user for input of any kind.') - parser.add_option('--failfast', action='store_true', dest='failfast', default=False, - help='Tells Django to stop running the test suite after first failed test.') - parser.add_option('--settings', - help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') - parser.add_option('--bisect', action='store', dest='bisect', default=None, - help="Bisect the test suite to discover a test that causes a test failure when combined with the named test.") - parser.add_option('--pair', action='store', dest='pair', default=None, - help="Run the test suite in pairs with the named test to find problem pairs.") - options, args = parser.parse_args() - if options.settings: - os.environ['DJANGO_SETTINGS_MODULE'] = options.settings - elif "DJANGO_SETTINGS_MODULE" not in os.environ: - parser.error("DJANGO_SETTINGS_MODULE is not set in the environment. " - "Set it or use --settings.") - - if options.bisect: - bisect_tests(options.bisect, options, args) - elif options.pair: - paired_tests(options.pair, options, args) - else: - failures = django_tests(int(options.verbosity), options.interactive, options.failfast, args) - if failures: - sys.exit(bool(failures)) diff --git a/parts/django/tests/templates/404.html b/parts/django/tests/templates/404.html deleted file mode 100644 index da627e2..0000000 --- a/parts/django/tests/templates/404.html +++ /dev/null @@ -1 +0,0 @@ -Django Internal Tests: 404 Error
\ No newline at end of file diff --git a/parts/django/tests/templates/500.html b/parts/django/tests/templates/500.html deleted file mode 100644 index ff028cb..0000000 --- a/parts/django/tests/templates/500.html +++ /dev/null @@ -1 +0,0 @@ -Django Internal Tests: 500 Error
\ No newline at end of file diff --git a/parts/django/tests/templates/base.html b/parts/django/tests/templates/base.html deleted file mode 100644 index 611bc09..0000000 --- a/parts/django/tests/templates/base.html +++ /dev/null @@ -1,8 +0,0 @@ -<html> -<head></head> -<body> -<h1>Django Internal Tests: {% block title %}{% endblock %}</h1> -{% block content %} -{% endblock %} -</body> -</html>
\ No newline at end of file diff --git a/parts/django/tests/templates/comments/comment_notification_email.txt b/parts/django/tests/templates/comments/comment_notification_email.txt deleted file mode 100644 index 63f1493..0000000 --- a/parts/django/tests/templates/comments/comment_notification_email.txt +++ /dev/null @@ -1,3 +0,0 @@ -A comment has been posted on {{ content_object }}. -The comment reads as follows: -{{ comment }} diff --git a/parts/django/tests/templates/custom_admin/add_form.html b/parts/django/tests/templates/custom_admin/add_form.html deleted file mode 100644 index f42ba4b..0000000 --- a/parts/django/tests/templates/custom_admin/add_form.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "admin/change_form.html" %} diff --git a/parts/django/tests/templates/custom_admin/change_form.html b/parts/django/tests/templates/custom_admin/change_form.html deleted file mode 100644 index f42ba4b..0000000 --- a/parts/django/tests/templates/custom_admin/change_form.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "admin/change_form.html" %} diff --git a/parts/django/tests/templates/custom_admin/change_list.html b/parts/django/tests/templates/custom_admin/change_list.html deleted file mode 100644 index eebc9c7..0000000 --- a/parts/django/tests/templates/custom_admin/change_list.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "admin/change_list.html" %} - -{% block extrahead %} -<script type="text/javascript"> -var hello = '{{ extra_var }}'; -</script> -{% endblock %} diff --git a/parts/django/tests/templates/custom_admin/delete_confirmation.html b/parts/django/tests/templates/custom_admin/delete_confirmation.html deleted file mode 100644 index 9353c5b..0000000 --- a/parts/django/tests/templates/custom_admin/delete_confirmation.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "admin/delete_confirmation.html" %} diff --git a/parts/django/tests/templates/custom_admin/delete_selected_confirmation.html b/parts/django/tests/templates/custom_admin/delete_selected_confirmation.html deleted file mode 100644 index 9268536..0000000 --- a/parts/django/tests/templates/custom_admin/delete_selected_confirmation.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "admin/delete_selected_confirmation.html" %} diff --git a/parts/django/tests/templates/custom_admin/index.html b/parts/django/tests/templates/custom_admin/index.html deleted file mode 100644 index 75b6ca3..0000000 --- a/parts/django/tests/templates/custom_admin/index.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "admin/index.html" %} - -{% block content %} -Hello from a custom index template {{ foo }} -{{ block.super }} -{% endblock %} diff --git a/parts/django/tests/templates/custom_admin/login.html b/parts/django/tests/templates/custom_admin/login.html deleted file mode 100644 index e10a269..0000000 --- a/parts/django/tests/templates/custom_admin/login.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "admin/login.html" %} - -{% block content %} -Hello from a custom login template -{{ block.super }} -{% endblock %} diff --git a/parts/django/tests/templates/custom_admin/logout.html b/parts/django/tests/templates/custom_admin/logout.html deleted file mode 100644 index 3a9301b..0000000 --- a/parts/django/tests/templates/custom_admin/logout.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "registration/logged_out.html" %} - -{% block content %} -Hello from a custom logout template -{{ block.super }} -{% endblock %} diff --git a/parts/django/tests/templates/custom_admin/object_history.html b/parts/django/tests/templates/custom_admin/object_history.html deleted file mode 100644 index aee3b5b..0000000 --- a/parts/django/tests/templates/custom_admin/object_history.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "admin/object_history.html" %} diff --git a/parts/django/tests/templates/custom_admin/password_change_done.html b/parts/django/tests/templates/custom_admin/password_change_done.html deleted file mode 100644 index 0e4a7f2..0000000 --- a/parts/django/tests/templates/custom_admin/password_change_done.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "registration/password_change_done.html" %} - -{% block content %} -Hello from a custom password change done template -{{ block.super }} -{% endblock %} diff --git a/parts/django/tests/templates/custom_admin/password_change_form.html b/parts/django/tests/templates/custom_admin/password_change_form.html deleted file mode 100644 index 1c42493..0000000 --- a/parts/django/tests/templates/custom_admin/password_change_form.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "registration/password_change_form.html" %} - -{% block content %} -Hello from a custom password change form template -{{ block.super }} -{% endblock %} diff --git a/parts/django/tests/templates/extended.html b/parts/django/tests/templates/extended.html deleted file mode 100644 index e0d8a13..0000000 --- a/parts/django/tests/templates/extended.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "base.html" %} -{% block title %}Extended template{% endblock %} -{% block content %} -This is just a template extending the base. -{% endblock %}
\ No newline at end of file diff --git a/parts/django/tests/templates/form_view.html b/parts/django/tests/templates/form_view.html deleted file mode 100644 index 1487217..0000000 --- a/parts/django/tests/templates/form_view.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "base.html" %} -{% block title %}Submit data{% endblock %} -{% block content %} -<h1>{{ message }}</h1> -<form method='post' action='.'> -{% if form.errors %} -<p class='warning'>Please correct the errors below:</p> -{% endif %} -<ul class='form'> -{{ form }} -<li><input type='submit' value='Submit'></li> -</ul> -</form> - -{% endblock %}
\ No newline at end of file diff --git a/parts/django/tests/templates/login.html b/parts/django/tests/templates/login.html deleted file mode 100644 index d55e9dd..0000000 --- a/parts/django/tests/templates/login.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "base.html" %} -{% block title %}Login{% endblock %} -{% block content %} -{% if form.has_errors %} -<p>Your username and password didn't match. Please try again.</p> -{% endif %} - -<form method="post" action="."> -<table> -<tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr> -<tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr> -</table> - -<input type="submit" value="login" /> -<input type="hidden" name="next" value="{{ next }}" /> -</form> -{% endblock %}
\ No newline at end of file diff --git a/parts/django/tests/templates/views/article_archive_day.html b/parts/django/tests/templates/views/article_archive_day.html deleted file mode 100644 index bd2d67f..0000000 --- a/parts/django/tests/templates/views/article_archive_day.html +++ /dev/null @@ -1 +0,0 @@ -This template intentionally left blank diff --git a/parts/django/tests/templates/views/article_archive_month.html b/parts/django/tests/templates/views/article_archive_month.html deleted file mode 100644 index 3f8ff55..0000000 --- a/parts/django/tests/templates/views/article_archive_month.html +++ /dev/null @@ -1 +0,0 @@ -This template intentionally left blank
\ No newline at end of file diff --git a/parts/django/tests/templates/views/article_confirm_delete.html b/parts/django/tests/templates/views/article_confirm_delete.html deleted file mode 100644 index 3f8ff55..0000000 --- a/parts/django/tests/templates/views/article_confirm_delete.html +++ /dev/null @@ -1 +0,0 @@ -This template intentionally left blank
\ No newline at end of file diff --git a/parts/django/tests/templates/views/article_detail.html b/parts/django/tests/templates/views/article_detail.html deleted file mode 100644 index 952299d..0000000 --- a/parts/django/tests/templates/views/article_detail.html +++ /dev/null @@ -1 +0,0 @@ -Article detail template. diff --git a/parts/django/tests/templates/views/article_form.html b/parts/django/tests/templates/views/article_form.html deleted file mode 100644 index e2aa1f9..0000000 --- a/parts/django/tests/templates/views/article_form.html +++ /dev/null @@ -1,3 +0,0 @@ -Article form template. - -{{ form.errors }} diff --git a/parts/django/tests/templates/views/datearticle_archive_month.html b/parts/django/tests/templates/views/datearticle_archive_month.html deleted file mode 100644 index 3f8ff55..0000000 --- a/parts/django/tests/templates/views/datearticle_archive_month.html +++ /dev/null @@ -1 +0,0 @@ -This template intentionally left blank
\ No newline at end of file diff --git a/parts/django/tests/templates/views/urlarticle_detail.html b/parts/django/tests/templates/views/urlarticle_detail.html deleted file mode 100644 index 924f310..0000000 --- a/parts/django/tests/templates/views/urlarticle_detail.html +++ /dev/null @@ -1 +0,0 @@ -UrlArticle detail template. diff --git a/parts/django/tests/templates/views/urlarticle_form.html b/parts/django/tests/templates/views/urlarticle_form.html deleted file mode 100644 index 578dd98..0000000 --- a/parts/django/tests/templates/views/urlarticle_form.html +++ /dev/null @@ -1,3 +0,0 @@ -UrlArticle form template. - -{{ form.errors }} diff --git a/parts/django/tests/test_sqlite.py b/parts/django/tests/test_sqlite.py deleted file mode 100644 index de8bf93..0000000 --- a/parts/django/tests/test_sqlite.py +++ /dev/null @@ -1,22 +0,0 @@ -# This is an example test settings file for use with the Django test suite. -# -# The 'sqlite3' backend requires only the ENGINE setting (an in- -# memory database will be used). All other backends will require a -# NAME and potentially authentication information. See the -# following section in the docs for more information: -# -# http://docs.djangoproject.com/en/dev/internals/contributing/#unit-tests -# -# The different databases that Django supports behave differently in certain -# situations, so it is recommended to run the test suite against as many -# database backends as possible. You may want to create a separate settings -# file for each of the backends you test against. - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3' - }, - 'other': { - 'ENGINE': 'django.db.backends.sqlite3', - } -} diff --git a/parts/django/tests/urls.py b/parts/django/tests/urls.py deleted file mode 100644 index 01d6408..0000000 --- a/parts/django/tests/urls.py +++ /dev/null @@ -1,44 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('', - # test_client modeltest urls - (r'^test_client/', include('modeltests.test_client.urls')), - (r'^test_client_regress/', include('regressiontests.test_client_regress.urls')), - - # File upload test views - (r'^file_uploads/', include('regressiontests.file_uploads.urls')), - - # Always provide the auth system login and logout views - (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), - (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), - - # test urlconf for {% url %} template tag - (r'^url_tag/', include('regressiontests.templates.urls')), - - # django built-in views - (r'^views/', include('regressiontests.views.urls')), - - # test urlconf for middleware tests - (r'^middleware/', include('regressiontests.middleware.urls')), - - # admin view tests - (r'^test_admin/', include('regressiontests.admin_views.urls')), - (r'^generic_inline_admin/', include('regressiontests.generic_inline_admin.urls')), - - # admin widget tests - (r'widget_admin/', include('regressiontests.admin_widgets.urls')), - - (r'^utils/', include('regressiontests.utils.urls')), - - # test urlconf for syndication tests - (r'^syndication/', include('regressiontests.syndication.urls')), - - # conditional get views - (r'condition/', include('regressiontests.conditional_processing.urls')), - - # middleware exceptions tests - (r'middleware_exceptions/', include('regressiontests.middleware_exceptions.urls')), - - # special headers views - (r'special_headers/', include('regressiontests.special_headers.urls')), -) |