Ticket #2333: revised-tests.patch
File revised-tests.patch, 164.4 KB (added by , 18 years ago) |
---|
-
tests/modeltests/basic/models.py
13 13 def __str__(self): 14 14 return self.headline 15 15 16 API_TESTS = """ 17 16 __test__ = {'API_TESTS': """ 18 17 # No articles are in the system yet. 19 18 >>> Article.objects.all() 20 19 [] … … 314 313 >>> Article.objects.all() 315 314 [<Article: Article 6>, <Article: Default headline>, <Article: Article 7>, <Article: Updated article 8>] 316 315 317 """ 316 """} 318 317 319 318 from django.conf import settings 320 319 321 320 building_docs = getattr(settings, 'BUILDING_DOCS', False) 322 321 323 322 if building_docs or settings.DATABASE_ENGINE == 'postgresql': 324 API_TESTS+= """323 __test__['API_TESTS'] += """ 325 324 # In PostgreSQL, microsecond-level precision is available. 326 325 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) 327 326 >>> a9.save() … … 330 329 """ 331 330 332 331 if building_docs or settings.DATABASE_ENGINE == 'mysql': 333 API_TESTS+= """332 __test__['API_TESTS'] += """ 334 333 # In MySQL, microsecond-level precision isn't available. You'll lose 335 334 # microsecond-level precision once the data is saved. 336 335 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) … … 339 338 datetime.datetime(2005, 7, 31, 12, 30, 45) 340 339 """ 341 340 342 API_TESTS+= """341 __test__['API_TESTS'] += """ 343 342 344 343 # You can manually specify the primary key when creating a new object. 345 344 >>> a101 = Article(id=101, headline='Article 101', pub_date=datetime(2005, 7, 31, 12, 30, 45)) -
tests/modeltests/m2m_recursive/models.py
22 22 def __str__(self): 23 23 return self.name 24 24 25 API_TESTS ="""25 __test__ = {'API_TESTS':""" 26 26 >>> a = Person(name='Anne') 27 27 >>> a.save() 28 28 >>> b = Person(name='Bill') … … 189 189 >>> d.stalkers.all() 190 190 [<Person: Chuck>] 191 191 192 """ 192 """} -
tests/modeltests/one_to_one/models.py
30 30 def __str__(self): 31 31 return "%s the waiter at %s" % (self.name, self.restaurant) 32 32 33 API_TESTS ="""33 __test__ = {'API_TESTS':""" 34 34 # Create a couple of Places. 35 35 >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton') 36 36 >>> p1.save() … … 151 151 # Delete the restaurant; the waiter should also be removed 152 152 >>> r = Restaurant.objects.get(pk=1) 153 153 >>> r.delete() 154 """ 154 """} -
tests/modeltests/m2o_recursive/models.py
19 19 def __str__(self): 20 20 return self.name 21 21 22 API_TESTS ="""22 __test__ = {'API_TESTS':""" 23 23 # Create a few Category objects. 24 24 >>> r = Category(id=None, name='Root category', parent=None) 25 25 >>> r.save() … … 37 37 [] 38 38 >>> c.parent 39 39 <Category: Root category> 40 """ 40 """} -
tests/modeltests/custom_managers/models.py
58 58 def __str__(self): 59 59 return self.name 60 60 61 API_TESTS ="""61 __test__ = {'API_TESTS':""" 62 62 >>> p1 = Person(first_name='Bugs', last_name='Bunny', fun=True) 63 63 >>> p1.save() 64 64 >>> p2 = Person(first_name='Droopy', last_name='Dog', fun=False) … … 104 104 # to the first manager defined in the class. In this case, it's "cars". 105 105 >>> Car._default_manager.order_by('name') 106 106 [<Car: Corvette>, <Car: Neon>] 107 """ 107 """} -
tests/modeltests/invalid_models/models.py
78 78 79 79 80 80 81 error_log= """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute.81 model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute. 82 82 invalid_models.fielderrors: "floatfield": FloatFields require a "decimal_places" attribute. 83 83 invalid_models.fielderrors: "floatfield": FloatFields require a "max_digits" attribute. 84 84 invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute. -
tests/modeltests/many_to_many/models.py
28 28 class Meta: 29 29 ordering = ('headline',) 30 30 31 API_TESTS ="""31 __test__ = {'API_TESTS':""" 32 32 # Create a couple of Publications. 33 33 >>> p1 = Publication(id=None, title='The Python Journal') 34 34 >>> p1.save() … … 231 231 >>> p1.article_set.all() 232 232 [<Article: NASA uses Python>] 233 233 234 """ 234 """} -
tests/modeltests/m2m_and_m2o/models.py
21 21 ordering = ('num',) 22 22 23 23 24 API_TESTS ="""24 __test__ = {'API_TESTS':""" 25 25 >>> Issue.objects.all() 26 26 [] 27 27 >>> r = User(username='russell') … … 62 62 [<Issue: 1>, <Issue: 2>, <Issue: 3>] 63 63 >>> Issue.objects.filter(Q(client=r.id) | Q(cc__id__exact=r.id)) 64 64 [<Issue: 1>, <Issue: 2>, <Issue: 3>] 65 """ 65 """} -
tests/modeltests/validation/models.py
20 20 def __str__(self): 21 21 return self.name 22 22 23 API_TESTS ="""23 __test__ = {'API_TESTS':""" 24 24 25 25 >>> import datetime 26 26 >>> valid_params = { … … 146 146 >>> p.validate() 147 147 {'email': ['Enter a valid e-mail address.']} 148 148 149 """ 149 """} -
tests/modeltests/or_lookups/models.py
23 23 def __str__(self): 24 24 return self.headline 25 25 26 API_TESTS ="""26 __test__ = {'API_TESTS':""" 27 27 >>> from datetime import datetime 28 28 >>> from django.db.models import Q 29 29 … … 101 101 [<Article: Hello>] 102 102 >>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2)) 103 103 [<Article: Hello>, <Article: Goodbye>] 104 """ 104 """} -
tests/modeltests/mutually_referential/models.py
14 14 name = CharField(maxlength=100) 15 15 parent = ForeignKey(Parent) 16 16 17 API_TESTS ="""17 __test__ = {'API_TESTS':""" 18 18 # Create a Parent 19 19 >>> q = Parent(name='Elizabeth') 20 20 >>> q.save() … … 29 29 30 30 >>> q.delete() 31 31 32 """ 33 No newline at end of file 32 """} 33 No newline at end of file -
tests/modeltests/custom_methods/models.py
36 36 # positional arguments to Article(). 37 37 return [self.__class__(*row) for row in cursor.fetchall()] 38 38 39 API_TESTS ="""39 __test__ = {'API_TESTS':""" 40 40 # Create a couple of Articles. 41 41 >>> from datetime import date 42 42 >>> a = Article(id=None, headline='Area man programs in Python', pub_date=date(2005, 7, 27)) … … 55 55 [<Article: Area man programs in Python>] 56 56 >>> b.articles_from_same_day_2() 57 57 [<Article: Area man programs in Python>] 58 """ 58 """} -
tests/modeltests/empty/models.py
10 10 class Empty(models.Model): 11 11 pass 12 12 13 API_TESTS ="""13 __test__ = {'API_TESTS':""" 14 14 >>> m = Empty() 15 15 >>> m.id 16 16 >>> m.save() … … 23 23 >>> existing = Empty(m.id) 24 24 >>> existing.save() 25 25 26 """ 26 """} -
tests/modeltests/many_to_one_null/models.py
23 23 def __str__(self): 24 24 return self.headline 25 25 26 API_TESTS ="""26 __test__ = {'API_TESTS':""" 27 27 # Create a Reporter. 28 28 >>> r = Reporter(name='John Smith') 29 29 >>> r.save() … … 121 121 >>> Article.objects.filter(reporter__isnull=True) 122 122 [<Article: First>, <Article: Fourth>] 123 123 124 """ 124 """} -
tests/modeltests/get_or_create/models.py
15 15 def __str__(self): 16 16 return '%s %s' % (self.first_name, self.last_name) 17 17 18 API_TESTS ="""18 __test__ = {'API_TESTS':""" 19 19 # Acting as a divine being, create an Person. 20 20 >>> from datetime import date 21 21 >>> p = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) … … 49 49 False 50 50 >>> Person.objects.count() 51 51 2 52 """ 52 """} -
tests/modeltests/custom_pk/models.py
27 27 def __str__(self): 28 28 return self.name 29 29 30 API_TESTS ="""30 __test__ = {'API_TESTS':""" 31 31 >>> dan = Employee(employee_code='ABC123', first_name='Dan', last_name='Jones') 32 32 >>> dan.save() 33 33 >>> Employee.objects.all() … … 88 88 >>> Business.objects.filter(employees__first_name__startswith='Fran') 89 89 [<Business: Sears>] 90 90 91 """ 91 """} -
tests/modeltests/reverse_lookup/models.py
27 27 def __str(self): 28 28 return self.name 29 29 30 API_TESTS ="""30 __test__ = {'API_TESTS':""" 31 31 >>> john = User(name="John Doe") 32 32 >>> john.save() 33 33 >>> jim = User(name="Jim Bo") … … 56 56 Traceback (most recent call last): 57 57 ... 58 58 TypeError: Cannot resolve keyword 'choice' into field 59 """ 59 """} -
tests/modeltests/m2o_recursive2/models.py
17 17 def __str__(self): 18 18 return self.full_name 19 19 20 API_TESTS ="""20 __test__ = {'API_TESTS':""" 21 21 # Create two Person objects -- the mom and dad in our family. 22 22 >>> dad = Person(full_name='John Smith Senior', mother=None, father=None) 23 23 >>> dad.save() … … 40 40 [] 41 41 >>> kid.fathers_child_set.all() 42 42 [] 43 """ 43 """} -
tests/modeltests/m2m_multiple/models.py
28 28 def __str__(self): 29 29 return self.headline 30 30 31 API_TESTS ="""31 __test__ = {'API_TESTS':""" 32 32 >>> from datetime import datetime 33 33 34 34 >>> c1 = Category(name='Sports') … … 76 76 [] 77 77 >>> c4.secondary_article_set.all() 78 78 [<Article: Area man steals>, <Article: Area man runs>] 79 """ 79 """} -
tests/modeltests/m2m_intermediary/models.py
34 34 def __str__(self): 35 35 return '%s (%s)' % (self.reporter, self.position) 36 36 37 API_TESTS ="""37 __test__ = {'API_TESTS':""" 38 38 # Create a few Reporters. 39 39 >>> r1 = Reporter(first_name='John', last_name='Smith') 40 40 >>> r1.save() … … 65 65 <Article: This is a test> 66 66 >>> r1.writer_set.all() 67 67 [<Writer: John Smith (Main writer)>] 68 """ 68 """} -
tests/modeltests/str/models.py
17 17 def __str__(self): 18 18 return self.headline 19 19 20 API_TESTS ="""20 __test__ = {'API_TESTS':""" 21 21 # Create an Article. 22 22 >>> from datetime import datetime 23 23 >>> a = Article(headline='Area man programs in Python', pub_date=datetime(2005, 7, 28)) … … 28 28 29 29 >>> a 30 30 <Article: Area man programs in Python> 31 """ 31 """} -
tests/modeltests/transactions/models.py
17 17 def __str__(self): 18 18 return "%s %s" % (self.first_name, self.last_name) 19 19 20 API_TESTS ="""20 __test__ = {'API_TESTS':""" 21 21 >>> from django.db import connection, transaction 22 """ 22 """} 23 23 24 24 from django.conf import settings 25 25 26 26 building_docs = getattr(settings, 'BUILDING_DOCS', False) 27 27 28 28 if building_docs or settings.DATABASE_ENGINE != 'mysql': 29 API_TESTS+= """29 __test__['API_TESTS'] += """ 30 30 # the default behavior is to autocommit after each save() action 31 31 >>> def create_a_reporter_then_fail(first, last): 32 32 ... a = Reporter(first_name=first, last_name=last) -
tests/modeltests/model_inheritance/models.py
26 26 def __str__(self): 27 27 return "%s the italian restaurant" % self.name 28 28 29 API_TESTS ="""29 __test__ = {'API_TESTS':""" 30 30 # Make sure Restaurant has the right fields in the right order. 31 31 >>> [f.name for f in Restaurant._meta.fields] 32 32 ['id', 'name', 'address', 'serves_hot_dogs', 'serves_pizza'] … … 50 50 >>> ir.save() 51 51 52 52 53 """ 53 """} -
tests/modeltests/lookup/models.py
15 15 def __str__(self): 16 16 return self.headline 17 17 18 API_TESTS ="""18 __test__ = {'API_TESTS':""" 19 19 # Create a couple of Articles. 20 20 >>> from datetime import datetime 21 21 >>> a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) … … 182 182 [<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>] 183 183 >>> Article.objects.exclude(headline="Article 7") 184 184 [<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>] 185 """ 185 """} -
tests/modeltests/choices/models.py
23 23 def __str__(self): 24 24 return self.name 25 25 26 API_TESTS ="""26 __test__ = {'API_TESTS':""" 27 27 >>> a = Person(name='Adrian', gender='M') 28 28 >>> a.save() 29 29 >>> s = Person(name='Sara', gender='F') … … 36 36 'Male' 37 37 >>> s.get_gender_display() 38 38 'Female' 39 """ 39 """} -
tests/modeltests/save_delete_hooks/models.py
24 24 super(Person, self).delete() # Call the "real" delete() method 25 25 print "After deletion" 26 26 27 API_TESTS ="""27 __test__ = {'API_TESTS':""" 28 28 >>> p1 = Person(first_name='John', last_name='Smith') 29 29 >>> p1.save() 30 30 Before save … … 39 39 40 40 >>> Person.objects.all() 41 41 [] 42 """ 42 """} -
tests/modeltests/pagination/models.py
15 15 def __str__(self): 16 16 return self.headline 17 17 18 API_TESTS ="""18 __test__ = {'API_TESTS':""" 19 19 # prepare a list of objects for pagination 20 20 >>> from datetime import datetime 21 21 >>> for x in range(1, 10): … … 64 64 >>> paginator.last_on_page(1) 65 65 9 66 66 67 """ 67 """} -
tests/modeltests/get_latest/models.py
29 29 def __str__(self): 30 30 return self.name 31 31 32 API_TESTS ="""32 __test__ = {'API_TESTS':""" 33 33 # Because no Articles exist yet, get_latest() raises ArticleDoesNotExist. 34 34 >>> Article.objects.latest() 35 35 Traceback (most recent call last): … … 76 76 77 77 >>> Person.objects.latest('birthday') 78 78 <Person: Stephanie> 79 """ 79 """} -
tests/modeltests/properties/models.py
20 20 21 21 full_name_2 = property(_get_full_name, _set_full_name) 22 22 23 API_TESTS ="""23 __test__ = {'API_TESTS':""" 24 24 >>> a = Person(first_name='John', last_name='Lennon') 25 25 >>> a.save() 26 26 >>> a.full_name … … 37 37 >>> a2.save() 38 38 >>> a2.first_name 39 39 'Paul' 40 """ 40 """} -
tests/modeltests/generic_relations/models.py
53 53 def __str__(self): 54 54 return self.name 55 55 56 API_TESTS ="""56 __test__ = {'API_TESTS':""" 57 57 # Create the world in 7 lines of code... 58 58 >>> lion = Animal(common_name="Lion", latin_name="Panthera leo") 59 59 >>> platypus = Animal(common_name="Platypus", latin_name="Ornithorhynchus anatinus") … … 105 105 [<TaggedItem: shiny>] 106 106 >>> TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=quartz.id) 107 107 [<TaggedItem: clearish>] 108 """ 108 """} -
tests/modeltests/serializers/models.py
37 37 def __str__(self): 38 38 return self.headline 39 39 40 API_TESTS ="""40 __test__ = {'API_TESTS':""" 41 41 # Create some data: 42 42 >>> from datetime import datetime 43 43 >>> sports = Category(name="Sports") … … 118 118 >>> Article.objects.all() 119 119 [<Article: Just kidding; I love TV poker>, <Article: Time to reform copyright>] 120 120 121 """ 121 """} -
tests/modeltests/reserved_names/models.py
24 24 def __str__(self): 25 25 return self.when 26 26 27 API_TESTS ="""27 __test__ = {'API_TESTS':""" 28 28 >>> import datetime 29 29 >>> day1 = datetime.date(2005, 1, 1) 30 30 >>> day2 = datetime.date(2006, 2, 2) … … 53 53 54 54 >>> Thing.objects.filter(where__month=1) 55 55 [<Thing: a>] 56 """ 56 """} -
tests/modeltests/many_to_one/models.py
25 25 class Meta: 26 26 ordering = ('headline',) 27 27 28 API_TESTS ="""28 __test__ = {'API_TESTS':""" 29 29 # Create a few Reporters. 30 30 >>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com') 31 31 >>> r.save() … … 263 263 >>> Article.objects.all() 264 264 [] 265 265 266 """ 266 """} -
tests/modeltests/ordering/models.py
24 24 def __str__(self): 25 25 return self.headline 26 26 27 API_TESTS ="""27 __test__ = {'API_TESTS':""" 28 28 # Create a couple of Articles. 29 29 >>> from datetime import datetime 30 30 >>> a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) … … 64 64 # don't know what order the output will be in. 65 65 >>> Article.objects.order_by('?') 66 66 [...] 67 """ 67 """} -
tests/modeltests/custom_columns/models.py
15 15 def __str__(self): 16 16 return '%s %s' % (self.first_name, self.last_name) 17 17 18 API_TESTS ="""18 __test__ = {'API_TESTS':""" 19 19 # Create a Person. 20 20 >>> p = Person(first_name='John', last_name='Smith') 21 21 >>> p.save() … … 50 50 Traceback (most recent call last): 51 51 ... 52 52 AttributeError: 'Person' object has no attribute 'last' 53 """ 53 """} -
tests/modeltests/field_defaults/models.py
19 19 def __str__(self): 20 20 return self.headline 21 21 22 API_TESTS ="""22 __test__ = {'API_TESTS':""" 23 23 >>> from datetime import datetime 24 24 25 25 # No articles are in the system yet. … … 48 48 >>> d = now - a.pub_date 49 49 >>> d.seconds < 5 50 50 True 51 """ 51 """} -
tests/modeltests/manipulators/models.py
21 21 def __str__(self): 22 22 return self.name 23 23 24 API_TESTS ="""24 __test__ = {'API_TESTS':""" 25 25 >>> from django.utils.datastructures import MultiValueDict 26 26 27 27 # Create a Musician object via the default AddManipulator. … … 88 88 <Album: Ultimate Ella> 89 89 >>> a2.release_date 90 90 datetime.date(2005, 2, 13) 91 """ 91 """} -
tests/regressiontests/string_lookup/models.py
34 34 def __str__(self): 35 35 return "Base %s" % self.name 36 36 37 API_TESTS ="""37 __test__ = {'API_TESTS':""" 38 38 # Regression test for #1661 and #1662: Check that string form referencing of models works, 39 39 # both as pre and post reference, on all RelatedField types. 40 40 … … 66 66 67 67 >>> child1.parent 68 68 <Base: Base Base1> 69 """ 69 """} -
tests/regressiontests/markup/tests.py
1 # Quick tests for the markup templatetags (django.contrib.markup) 2 3 from django.template import Template, Context, add_to_builtins 4 import re 5 import unittest 6 7 add_to_builtins('django.contrib.markup.templatetags.markup') 8 9 class Templates(unittest.TestCase): 10 def test_textile(self): 11 try: 12 import textile 13 except ImportError: 14 textile = None 15 16 ### test textile 17 18 textile_content = """Paragraph 1 19 20 Paragraph 2 with "quotes" and @code@""" 21 22 t = Template("{{ textile_content|textile }}") 23 rendered = t.render(Context(locals())).strip() 24 if textile: 25 self.assertEqual(rendered,"""<p>Paragraph 1</p> 26 27 <p>Paragraph 2 with “quotes” and <code>code</code></p>""") 28 else: 29 self.assertEqual(rendered, textile_content) 30 31 def test_markdown(self): 32 try: 33 import markdown 34 except ImportError: 35 markdown = None 36 37 ### test markdown 38 39 markdown_content = """Paragraph 1 40 41 ## An h2""" 42 43 t = Template("{{ markdown_content|markdown }}") 44 rendered = t.render(Context(locals())).strip() 45 if markdown: 46 pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""") 47 self.assert_(pattern.match(rendered)) 48 else: 49 self.assertEqual(rendered, markdown_content) 50 51 def test_rest(self): 52 try: 53 import docutils 54 except ImportError: 55 docutils = None 56 57 ### test rest 58 59 rest_content = """Paragraph 1 60 61 Paragraph 2 with a link_ 62 63 .. _link: http://www.example.com/""" 64 65 t = Template("{{ rest_content|restructuredtext }}") 66 rendered = t.render(Context(locals())).strip() 67 if docutils: 68 self.assertEqual(rendered, """<p>Paragraph 1</p> 69 <p>Paragraph 2 with a <a class="reference" href="http://www.example.com/">link</a></p>""") 70 else: 71 self.assertEqual(rendered, rest_content) 72 73 if __name__ == '__main__': 74 unittest.main() -
tests/regressiontests/many_to_one_regress/models.py
10 10 # created (the field names being lower-cased versions of their opposite 11 11 # classes is important here). 12 12 13 API_TESTS = "" 13 __test__ = {'API_TESTS':""} -
tests/regressiontests/initial_sql_regress/models.py
7 7 class Simple(models.Model): 8 8 name = models.CharField(maxlength = 50) 9 9 10 API_TESTS = "" 10 __test__ = {'API_TESTS':""} 11 11 12 12 # NOTE: The format of the included SQL file for this test suite is important. 13 13 # It must end with a trailing newline in order to test the fix for #2161. -
tests/regressiontests/cache/tests.py
1 # Unit tests for cache framework 2 # Uses whatever cache backend is set in the test settings file. 3 4 from django.core.cache import cache 5 import time, unittest 6 7 # functions/classes for complex data type tests 8 def f(): 9 return 42 10 class C: 11 def m(n): 12 return 24 13 14 class Cache(unittest.TestCase): 15 def test_simple(self): 16 # simple set/get 17 cache.set("key", "value") 18 self.assertEqual(cache.get("key"), "value") 19 20 def test_non_existent(self): 21 # get with non-existent keys 22 self.assertEqual(cache.get("does not exist"), None) 23 self.assertEqual(cache.get("does not exist", "bang!"), "bang!") 24 25 def test_get_many(self): 26 # get_many 27 cache.set('a', 'a') 28 cache.set('b', 'b') 29 cache.set('c', 'c') 30 cache.set('d', 'd') 31 32 self.assertEqual(cache.get_many(['a', 'c', 'd']), {'a' : 'a', 'c' : 'c', 'd' : 'd'}) 33 self.assertEqual(cache.get_many(['a', 'b', 'e']), {'a' : 'a', 'b' : 'b'}) 34 35 def test_delete(self): 36 # delete 37 cache.set("key1", "spam") 38 cache.set("key2", "eggs") 39 self.assertEqual(cache.get("key1"), "spam") 40 cache.delete("key1") 41 self.assertEqual(cache.get("key1"), None) 42 self.assertEqual(cache.get("key2"), "eggs") 43 44 def test_has_key(self): 45 # has_key 46 cache.set("hello", "goodbye") 47 self.assertEqual(cache.has_key("hello"), True) 48 self.assertEqual(cache.has_key("goodbye"), False) 49 50 def test_data_types(self): 51 # test data types 52 stuff = { 53 'string' : 'this is a string', 54 'int' : 42, 55 'list' : [1, 2, 3, 4], 56 'tuple' : (1, 2, 3, 4), 57 'dict' : {'A': 1, 'B' : 2}, 58 'function' : f, 59 'class' : C, 60 } 61 for (key, value) in stuff.items(): 62 cache.set(key, value) 63 self.assertEqual(cache.get(key), value) 64 65 # expiration 66 cache.set('expire', 'very quickly', 1) 67 time.sleep(2) 68 self.assertEqual(cache.get("expire"), None) 69 70 if __name__ == '__main__': 71 unittest.main() 72 No newline at end of file -
tests/regressiontests/httpwrappers/tests.py
1 """ 2 ################### 3 # Empty QueryDict # 4 ################### 5 6 >>> q = QueryDict('') 7 8 >>> q['foo'] 9 Traceback (most recent call last): 10 ... 11 MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>" 12 13 >>> q['something'] = 'bar' 14 Traceback (most recent call last): 15 ... 16 AttributeError: This QueryDict instance is immutable 17 18 >>> q.get('foo', 'default') 19 'default' 20 21 >>> q.getlist('foo') 22 [] 23 24 >>> q.setlist('foo', ['bar', 'baz']) 25 Traceback (most recent call last): 26 ... 27 AttributeError: This QueryDict instance is immutable 28 29 >>> q.appendlist('foo', ['bar']) 30 Traceback (most recent call last): 31 ... 32 AttributeError: This QueryDict instance is immutable 33 34 >>> q.has_key('foo') 35 False 36 37 >>> q.items() 38 [] 39 40 >>> q.lists() 41 [] 42 43 >>> q.keys() 44 [] 45 46 >>> q.values() 47 [] 48 49 >>> len(q) 50 0 51 52 >>> q.update({'foo': 'bar'}) 53 Traceback (most recent call last): 54 ... 55 AttributeError: This QueryDict instance is immutable 56 57 >>> q.pop('foo') 58 Traceback (most recent call last): 59 ... 60 AttributeError: This QueryDict instance is immutable 61 62 >>> q.popitem() 63 Traceback (most recent call last): 64 ... 65 AttributeError: This QueryDict instance is immutable 66 67 >>> q.clear() 68 Traceback (most recent call last): 69 ... 70 AttributeError: This QueryDict instance is immutable 71 72 >>> q.setdefault('foo', 'bar') 73 Traceback (most recent call last): 74 ... 75 AttributeError: This QueryDict instance is immutable 76 77 >>> q.urlencode() 78 '' 79 80 ################################### 81 # Mutable copy of empty QueryDict # 82 ################################### 83 84 >>> q = q.copy() 85 86 >>> q['foo'] 87 Traceback (most recent call last): 88 ... 89 MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>" 90 91 >>> q['name'] = 'john' 92 93 >>> q['name'] 94 'john' 95 96 >>> q.get('foo', 'default') 97 'default' 98 99 >>> q.get('name', 'default') 100 'john' 101 102 >>> q.getlist('name') 103 ['john'] 104 105 >>> q.getlist('foo') 106 [] 107 108 >>> q.setlist('foo', ['bar', 'baz']) 109 110 >>> q.get('foo', 'default') 111 'baz' 112 113 >>> q.getlist('foo') 114 ['bar', 'baz'] 115 116 >>> q.appendlist('foo', 'another') 117 118 >>> q.getlist('foo') 119 ['bar', 'baz', 'another'] 120 121 >>> q['foo'] 122 'another' 123 124 >>> q.has_key('foo') 125 True 126 127 >>> q.items() 128 [('foo', 'another'), ('name', 'john')] 129 130 >>> q.lists() 131 [('foo', ['bar', 'baz', 'another']), ('name', ['john'])] 132 133 >>> q.keys() 134 ['foo', 'name'] 135 136 >>> q.values() 137 ['another', 'john'] 138 139 >>> len(q) 140 2 141 142 >>> q.update({'foo': 'hello'}) 143 144 # Displays last value 145 >>> q['foo'] 146 'hello' 147 148 >>> q.get('foo', 'not available') 149 'hello' 150 151 >>> q.getlist('foo') 152 ['bar', 'baz', 'another', 'hello'] 153 154 >>> q.pop('foo') 155 ['bar', 'baz', 'another', 'hello'] 156 157 >>> q.get('foo', 'not there') 158 'not there' 159 160 >>> q.setdefault('foo', 'bar') 161 'bar' 162 163 >>> q['foo'] 164 'bar' 165 166 >>> q.getlist('foo') 167 ['bar'] 168 169 >>> q.urlencode() 170 'foo=bar&name=john' 171 172 >>> q.clear() 173 174 >>> len(q) 175 0 176 177 ##################################### 178 # QueryDict with one key/value pair # 179 ##################################### 180 181 >>> q = QueryDict('foo=bar') 182 183 >>> q['foo'] 184 'bar' 185 186 >>> q['bar'] 187 Traceback (most recent call last): 188 ... 189 MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {'foo': ['bar']}>" 190 191 >>> q['something'] = 'bar' 192 Traceback (most recent call last): 193 ... 194 AttributeError: This QueryDict instance is immutable 195 196 >>> q.get('foo', 'default') 197 'bar' 198 199 >>> q.get('bar', 'default') 200 'default' 201 202 >>> q.getlist('foo') 203 ['bar'] 204 205 >>> q.getlist('bar') 206 [] 207 208 >>> q.setlist('foo', ['bar', 'baz']) 209 Traceback (most recent call last): 210 ... 211 AttributeError: This QueryDict instance is immutable 212 213 >>> q.appendlist('foo', ['bar']) 214 Traceback (most recent call last): 215 ... 216 AttributeError: This QueryDict instance is immutable 217 218 >>> q.has_key('foo') 219 True 220 221 >>> q.has_key('bar') 222 False 223 224 >>> q.items() 225 [('foo', 'bar')] 226 227 >>> q.lists() 228 [('foo', ['bar'])] 229 230 >>> q.keys() 231 ['foo'] 232 233 >>> q.values() 234 ['bar'] 235 236 >>> len(q) 237 1 238 239 >>> q.update({'foo': 'bar'}) 240 Traceback (most recent call last): 241 ... 242 AttributeError: This QueryDict instance is immutable 243 244 >>> q.pop('foo') 245 Traceback (most recent call last): 246 ... 247 AttributeError: This QueryDict instance is immutable 248 249 >>> q.popitem() 250 Traceback (most recent call last): 251 ... 252 AttributeError: This QueryDict instance is immutable 253 254 >>> q.clear() 255 Traceback (most recent call last): 256 ... 257 AttributeError: This QueryDict instance is immutable 258 259 >>> q.setdefault('foo', 'bar') 260 Traceback (most recent call last): 261 ... 262 AttributeError: This QueryDict instance is immutable 263 264 >>> q.urlencode() 265 'foo=bar' 266 267 ##################################################### 268 # QueryDict with two key/value pairs with same keys # 269 ##################################################### 270 271 >>> q = QueryDict('vote=yes&vote=no') 272 273 >>> q['vote'] 274 'no' 275 276 >>> q['something'] = 'bar' 277 Traceback (most recent call last): 278 ... 279 AttributeError: This QueryDict instance is immutable 280 281 >>> q.get('vote', 'default') 282 'no' 283 284 >>> q.get('foo', 'default') 285 'default' 286 287 >>> q.getlist('vote') 288 ['yes', 'no'] 289 290 >>> q.getlist('foo') 291 [] 292 293 >>> q.setlist('foo', ['bar', 'baz']) 294 Traceback (most recent call last): 295 ... 296 AttributeError: This QueryDict instance is immutable 297 298 >>> q.appendlist('foo', ['bar']) 299 Traceback (most recent call last): 300 ... 301 AttributeError: This QueryDict instance is immutable 302 303 >>> q.has_key('vote') 304 True 305 306 >>> q.has_key('foo') 307 False 308 309 >>> q.items() 310 [('vote', 'no')] 311 312 >>> q.lists() 313 [('vote', ['yes', 'no'])] 314 315 >>> q.keys() 316 ['vote'] 317 318 >>> q.values() 319 ['no'] 320 321 >>> len(q) 322 1 323 324 >>> q.update({'foo': 'bar'}) 325 Traceback (most recent call last): 326 ... 327 AttributeError: This QueryDict instance is immutable 328 329 >>> q.pop('foo') 330 Traceback (most recent call last): 331 ... 332 AttributeError: This QueryDict instance is immutable 333 334 >>> q.popitem() 335 Traceback (most recent call last): 336 ... 337 AttributeError: This QueryDict instance is immutable 338 339 >>> q.clear() 340 Traceback (most recent call last): 341 ... 342 AttributeError: This QueryDict instance is immutable 343 344 >>> q.setdefault('foo', 'bar') 345 Traceback (most recent call last): 346 ... 347 AttributeError: This QueryDict instance is immutable 348 349 >>> q.urlencode() 350 'vote=yes&vote=no' 351 352 """ 353 354 from django.http import QueryDict 355 356 if __name__ == "__main__": 357 import doctest 358 doctest.testmod() -
tests/regressiontests/db_typecasts/tests.py
1 # Unit tests for typecast functions in django.db.backends.util 2 3 from django.db.backends import util as typecasts 4 import datetime, unittest 5 6 TEST_CASES = { 7 'typecast_date': ( 8 ('', None), 9 (None, None), 10 ('2005-08-11', datetime.date(2005, 8, 11)), 11 ('1990-01-01', datetime.date(1990, 1, 1)), 12 ), 13 'typecast_time': ( 14 ('', None), 15 (None, None), 16 ('0:00:00', datetime.time(0, 0)), 17 ('0:30:00', datetime.time(0, 30)), 18 ('8:50:00', datetime.time(8, 50)), 19 ('08:50:00', datetime.time(8, 50)), 20 ('12:00:00', datetime.time(12, 00)), 21 ('12:30:00', datetime.time(12, 30)), 22 ('13:00:00', datetime.time(13, 00)), 23 ('23:59:00', datetime.time(23, 59)), 24 ('00:00:12', datetime.time(0, 0, 12)), 25 ('00:00:12.5', datetime.time(0, 0, 12, 500000)), 26 ('7:22:13.312', datetime.time(7, 22, 13, 312000)), 27 ), 28 'typecast_timestamp': ( 29 ('', None), 30 (None, None), 31 ('2005-08-11 0:00:00', datetime.datetime(2005, 8, 11)), 32 ('2005-08-11 0:30:00', datetime.datetime(2005, 8, 11, 0, 30)), 33 ('2005-08-11 8:50:30', datetime.datetime(2005, 8, 11, 8, 50, 30)), 34 ('2005-08-11 8:50:30.123', datetime.datetime(2005, 8, 11, 8, 50, 30, 123000)), 35 ('2005-08-11 8:50:30.9', datetime.datetime(2005, 8, 11, 8, 50, 30, 900000)), 36 ('2005-08-11 8:50:30.312-05', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), 37 ('2005-08-11 8:50:30.312+02', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), 38 ), 39 'typecast_boolean': ( 40 (None, None), 41 ('', False), 42 ('t', True), 43 ('f', False), 44 ('x', False), 45 ), 46 } 47 48 class DBTypeCasts(unittest.TestCase): 49 def test_typeCasts(self): 50 for k, v in TEST_CASES.items(): 51 for inpt, expected in v: 52 got = getattr(typecasts, k)(inpt) 53 self.assertEqual(got, expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got)) 54 55 if __name__ == '__main__': 56 unittest.main() 57 No newline at end of file -
tests/regressiontests/dateformat/tests.py
1 r""" 2 >>> format(my_birthday, '') 3 '' 4 >>> format(my_birthday, 'a') 5 'p.m.' 6 >>> format(my_birthday, 'A') 7 'PM' 8 >>> format(my_birthday, 'd') 9 '08' 10 >>> format(my_birthday, 'j') 11 '8' 12 >>> format(my_birthday, 'l') 13 'Sunday' 14 >>> format(my_birthday, 'L') 15 'False' 16 >>> format(my_birthday, 'm') 17 '07' 18 >>> format(my_birthday, 'M') 19 'Jul' 20 >>> format(my_birthday, 'n') 21 '7' 22 >>> format(my_birthday, 'N') 23 'July' 24 >>> format(my_birthday, 'O') 25 '+0100' 26 >>> format(my_birthday, 'P') 27 '10 p.m.' 28 >>> format(my_birthday, 'r') 29 'Sun, 8 Jul 1979 22:00:00 +0100' 30 >>> format(my_birthday, 's') 31 '00' 32 >>> format(my_birthday, 'S') 33 'th' 34 >>> format(my_birthday, 't') 35 '31' 36 >>> format(my_birthday, 'T') 37 'CET' 38 >>> format(my_birthday, 'U') 39 '300531600' 40 >>> format(my_birthday, 'w') 41 '0' 42 >>> format(my_birthday, 'W') 43 '27' 44 >>> format(my_birthday, 'y') 45 '79' 46 >>> format(my_birthday, 'Y') 47 '1979' 48 >>> format(my_birthday, 'z') 49 '189' 50 >>> format(my_birthday, 'Z') 51 '3600' 52 53 >>> format(summertime, 'I') 54 '1' 55 >>> format(summertime, 'O') 56 '+0200' 57 >>> format(wintertime, 'I') 58 '0' 59 >>> format(wintertime, 'O') 60 '+0100' 61 62 >>> format(my_birthday, r'Y z \C\E\T') 63 '1979 189 CET' 64 65 >>> format(my_birthday, r'jS o\f F') 66 '8th of July' 67 """ 68 69 from django.utils import dateformat, translation 70 import datetime, os, time 71 72 format = dateformat.format 73 os.environ['TZ'] = 'Europe/Copenhagen' 74 translation.activate('en-us') 75 76 #time.tzset() 77 78 my_birthday = datetime.datetime(1979, 7, 8, 22, 00) 79 summertime = datetime.datetime(2005, 10, 30, 1, 00) 80 wintertime = datetime.datetime(2005, 10, 30, 4, 00) 81 82 83 if __name__ == '__main__': 84 import doctest 85 doctest.testmod() -
tests/regressiontests/defaultfilters/tests.py
1 r""" 2 >>> floatformat(7.7) 3 '7.7' 4 >>> floatformat(7.0) 5 '7' 6 >>> floatformat(0.7) 7 '0.7' 8 >>> floatformat(0.07) 9 '0.1' 10 >>> floatformat(0.007) 11 '0.0' 12 >>> floatformat(0.0) 13 '0' 14 15 >>> addslashes('"double quotes" and \'single quotes\'') 16 '\\"double quotes\\" and \\\'single quotes\\\'' 17 18 >>> capfirst('hello world') 19 'Hello world' 20 21 >>> fix_ampersands('Jack & Jill & Jeroboam') 22 'Jack & Jill & Jeroboam' 23 24 >>> linenumbers('line 1\nline 2') 25 '1. line 1\n2. line 2' 26 27 >>> linenumbers('\n'.join(['x'] * 10)) 28 '01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. x\n08. x\n09. x\n10. x' 29 30 >>> lower('TEST') 31 'test' 32 33 >>> lower(u'\xcb') # uppercase E umlaut 34 u'\xeb' 35 36 >>> make_list('abc') 37 ['a', 'b', 'c'] 38 39 >>> make_list(1234) 40 ['1', '2', '3', '4'] 41 42 >>> slugify(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/') 43 'jack-jill-like-numbers-123-and-4-and-silly-characters' 44 45 >>> stringformat(1, '03d') 46 '001' 47 48 >>> stringformat(1, 'z') 49 '' 50 51 >>> title('a nice title, isn\'t it?') 52 "A Nice Title, Isn't It?" 53 54 55 >>> truncatewords('A sentence with a few words in it', 1) 56 'A ...' 57 58 >>> truncatewords('A sentence with a few words in it', 5) 59 'A sentence with a few ...' 60 61 >>> truncatewords('A sentence with a few words in it', 100) 62 'A sentence with a few words in it' 63 64 >>> truncatewords('A sentence with a few words in it', 'not a number') 65 'A sentence with a few words in it' 66 67 68 >>> upper('Mixed case input') 69 'MIXED CASE INPUT' 70 71 >>> upper(u'\xeb') # lowercase e umlaut 72 u'\xcb' 73 74 75 >>> urlencode('jack & jill') 76 'jack%20%26%20jill' 77 78 79 >>> urlizetrunc('http://short.com/', 20) 80 '<a href="http://short.com/" rel="nofollow">http://short.com/</a>' 81 82 >>> urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20) 83 '<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=" rel="nofollow">http://www.google.co...</a>' 84 85 >>> wordcount('') 86 0 87 88 >>> wordcount('oneword') 89 1 90 91 >>> wordcount('lots of words') 92 3 93 94 >>> wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14) 95 "this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid" 96 97 >>> ljust('test', 10) 98 'test ' 99 100 >>> ljust('test', 3) 101 'test' 102 103 >>> rjust('test', 10) 104 ' test' 105 106 >>> rjust('test', 3) 107 'test' 108 109 >>> center('test', 6) 110 ' test ' 111 112 >>> cut('a string to be mangled', 'a') 113 ' string to be mngled' 114 115 >>> cut('a string to be mangled', 'ng') 116 'a stri to be maled' 117 118 >>> cut('a string to be mangled', 'strings') 119 'a string to be mangled' 120 121 >>> escape('<some html & special characters > here') 122 '<some html & special characters > here' 123 124 >>> linebreaks('line 1') 125 '<p>line 1</p>' 126 127 >>> linebreaks('line 1\nline 2') 128 '<p>line 1<br />line 2</p>' 129 130 >>> removetags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img') 131 'some <b>html</b> with alert("You smell") disallowed tags' 132 133 >>> striptags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags') 134 'some html with alert("You smell") disallowed tags' 135 136 >>> dictsort([{'age': 23, 'name': 'Barbara-Ann'}, 137 ... {'age': 63, 'name': 'Ra Ra Rasputin'}, 138 ... {'name': 'Jonny B Goode', 'age': 18}], 'age') 139 [{'age': 18, 'name': 'Jonny B Goode'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 63, 'name': 'Ra Ra Rasputin'}] 140 141 >>> dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'}, 142 ... {'age': 63, 'name': 'Ra Ra Rasputin'}, 143 ... {'name': 'Jonny B Goode', 'age': 18}], 'age') 144 [{'age': 63, 'name': 'Ra Ra Rasputin'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 18, 'name': 'Jonny B Goode'}] 145 146 >>> first([0,1,2]) 147 0 148 149 >>> first('') 150 '' 151 152 >>> first('test') 153 't' 154 155 >>> join([0,1,2], 'glue') 156 '0glue1glue2' 157 158 >>> length('1234') 159 4 160 161 >>> length([1,2,3,4]) 162 4 163 164 >>> length_is([], 0) 165 True 166 167 >>> length_is([], 1) 168 False 169 170 >>> length_is('a', 1) 171 True 172 173 >>> length_is('a', 10) 174 False 175 176 >>> slice_('abcdefg', '0') 177 '' 178 179 >>> slice_('abcdefg', '1') 180 'a' 181 182 >>> slice_('abcdefg', '-1') 183 'abcdef' 184 185 >>> slice_('abcdefg', '1:2') 186 'b' 187 188 >>> slice_('abcdefg', '1:3') 189 'bc' 190 191 >>> slice_('abcdefg', '0::2') 192 'aceg' 193 194 >>> unordered_list(['item 1', []]) 195 '\t<li>item 1</li>' 196 197 >>> unordered_list(['item 1', [['item 1.1', []]]]) 198 '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>' 199 200 >>> unordered_list(['item 1', [['item 1.1', []], ['item 1.2', []]]]) 201 '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>' 202 203 >>> add('1', '2') 204 3 205 206 >>> get_digit(123, 1) 207 3 208 209 >>> get_digit(123, 2) 210 2 211 212 >>> get_digit(123, 3) 213 1 214 215 >>> get_digit(123, 4) 216 0 217 218 >>> get_digit(123, 0) 219 123 220 221 >>> get_digit('xyz', 0) 222 'xyz' 223 224 # real testing of date() is in dateformat.py 225 >>> date(datetime.datetime(2005, 12, 29), "d F Y") 226 '29 December 2005' 227 >>> date(datetime.datetime(2005, 12, 29), r'jS o\f F') 228 '29th of December' 229 230 # real testing of time() is done in dateformat.py 231 >>> time(datetime.time(13), "h") 232 '01' 233 234 # real testing is done in timesince.py, where we can provide our own 'now' 235 >>> timesince(datetime.datetime.now() - datetime.timedelta(1)) 236 '1 day' 237 238 >>> default("val", "default") 239 'val' 240 241 >>> default(None, "default") 242 'default' 243 244 >>> default('', "default") 245 'default' 246 247 >>> default_if_none("val", "default") 248 'val' 249 250 >>> default_if_none(None, "default") 251 'default' 252 253 >>> default_if_none('', "default") 254 '' 255 256 >>> divisibleby(4, 2) 257 True 258 259 >>> divisibleby(4, 3) 260 False 261 262 >>> yesno(True) 263 'yes' 264 265 >>> yesno(False) 266 'no' 267 268 >>> yesno(None) 269 'maybe' 270 271 >>> yesno(True, 'certainly,get out of town,perhaps') 272 'certainly' 273 274 >>> yesno(False, 'certainly,get out of town,perhaps') 275 'get out of town' 276 277 >>> yesno(None, 'certainly,get out of town,perhaps') 278 'perhaps' 279 280 >>> yesno(None, 'certainly,get out of town') 281 'get out of town' 282 283 >>> filesizeformat(1023) 284 '1023 bytes' 285 286 >>> filesizeformat(1024) 287 '1.0 KB' 288 289 >>> filesizeformat(10*1024) 290 '10.0 KB' 291 292 >>> filesizeformat(1024*1024-1) 293 '1024.0 KB' 294 295 >>> filesizeformat(1024*1024) 296 '1.0 MB' 297 298 >>> filesizeformat(1024*1024*50) 299 '50.0 MB' 300 301 >>> filesizeformat(1024*1024*1024-1) 302 '1024.0 MB' 303 304 >>> filesizeformat(1024*1024*1024) 305 '1.0 GB' 306 307 >>> pluralize(1) 308 '' 309 310 >>> pluralize(0) 311 's' 312 313 >>> pluralize(2) 314 's' 315 316 >>> pluralize([1]) 317 '' 318 319 >>> pluralize([]) 320 's' 321 322 >>> pluralize([1,2,3]) 323 's' 324 325 >>> pluralize(1,'es') 326 '' 327 328 >>> pluralize(0,'es') 329 'es' 330 331 >>> pluralize(2,'es') 332 'es' 333 334 >>> pluralize(1,'y,ies') 335 'y' 336 337 >>> pluralize(0,'y,ies') 338 'ies' 339 340 >>> pluralize(2,'y,ies') 341 'ies' 342 343 >>> pluralize(0,'y,ies,error') 344 '' 345 346 >>> phone2numeric('0800 flowers') 347 '0800 3569377' 348 349 350 351 """ 352 353 from django.template.defaultfilters import * 354 import datetime 355 356 if __name__ == '__main__': 357 import doctest 358 doctest.testmod() -
tests/regressiontests/one_to_one_regress/models.py
22 22 def __str__(self): 23 23 return "Favorites for %s" % self.name 24 24 25 API_TESTS ="""25 __test__ = {'API_TESTS':""" 26 26 # Regression test for #1064 and #1506: Check that we create models via the m2m 27 27 # relation if the remote model has a OneToOneField. 28 28 >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton') … … 34 34 >>> f.restaurants = [r] 35 35 >>> f.restaurants.all() 36 36 [<Restaurant: Demon Dogs the restaurant>] 37 """ 37 """} -
tests/regressiontests/templates/tests.py
1 from django.conf import settings 2 3 if __name__ == '__main__': 4 # When running this file in isolation, we need to set up the configuration 5 # before importing 'template'. 6 settings.configure() 7 8 from django import template 9 from django.template import loader 10 from django.utils.translation import activate, deactivate, install 11 from django.utils.tzinfo import LocalTimezone 12 from datetime import datetime, timedelta 13 import unittest 14 15 ################################# 16 # Custom template tag for tests # 17 ################################# 18 19 register = template.Library() 20 21 class EchoNode(template.Node): 22 def __init__(self, contents): 23 self.contents = contents 24 25 def render(self, context): 26 return " ".join(self.contents) 27 28 def do_echo(parser, token): 29 return EchoNode(token.contents.split()[1:]) 30 31 register.tag("echo", do_echo) 32 33 template.libraries['django.templatetags.testtags'] = register 34 35 ##################################### 36 # Helper objects for template tests # 37 ##################################### 38 39 class SomeException(Exception): 40 silent_variable_failure = True 41 42 class SomeOtherException(Exception): 43 pass 44 45 class SomeClass: 46 def __init__(self): 47 self.otherclass = OtherClass() 48 49 def method(self): 50 return "SomeClass.method" 51 52 def method2(self, o): 53 return o 54 55 def method3(self): 56 raise SomeException 57 58 def method4(self): 59 raise SomeOtherException 60 61 class OtherClass: 62 def method(self): 63 return "OtherClass.method" 64 65 class Templates(unittest.TestCase): 66 def test_templates(self): 67 # NOW and NOW_tz are used by timesince tag tests. 68 NOW = datetime.now() 69 NOW_tz = datetime.now(LocalTimezone(datetime.now())) 70 71 # SYNTAX -- 72 # 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class) 73 TEMPLATE_TESTS = { 74 75 ### BASIC SYNTAX ########################################################## 76 77 # Plain text should go through the template parser untouched 78 'basic-syntax01': ("something cool", {}, "something cool"), 79 80 # Variables should be replaced with their value in the current context 81 'basic-syntax02': ("{{ headline }}", {'headline':'Success'}, "Success"), 82 83 # More than one replacement variable is allowed in a template 84 'basic-syntax03': ("{{ first }} --- {{ second }}", {"first" : 1, "second" : 2}, "1 --- 2"), 85 86 # Fail silently when a variable is not found in the current context 87 'basic-syntax04': ("as{{ missing }}df", {}, "asINVALIDdf"), 88 89 # A variable may not contain more than one word 90 'basic-syntax06': ("{{ multi word variable }}", {}, template.TemplateSyntaxError), 91 92 # Raise TemplateSyntaxError for empty variable tags 93 'basic-syntax07': ("{{ }}", {}, template.TemplateSyntaxError), 94 'basic-syntax08': ("{{ }}", {}, template.TemplateSyntaxError), 95 96 # Attribute syntax allows a template to call an object's attribute 97 'basic-syntax09': ("{{ var.method }}", {"var": SomeClass()}, "SomeClass.method"), 98 99 # Multiple levels of attribute access are allowed 100 'basic-syntax10': ("{{ var.otherclass.method }}", {"var": SomeClass()}, "OtherClass.method"), 101 102 # Fail silently when a variable's attribute isn't found 103 'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, "INVALID"), 104 105 # Raise TemplateSyntaxError when trying to access a variable beginning with an underscore 106 'basic-syntax12': ("{{ var.__dict__ }}", {"var": SomeClass()}, template.TemplateSyntaxError), 107 108 # Raise TemplateSyntaxError when trying to access a variable containing an illegal character 109 'basic-syntax13': ("{{ va>r }}", {}, template.TemplateSyntaxError), 110 'basic-syntax14': ("{{ (var.r) }}", {}, template.TemplateSyntaxError), 111 'basic-syntax15': ("{{ sp%am }}", {}, template.TemplateSyntaxError), 112 'basic-syntax16': ("{{ eggs! }}", {}, template.TemplateSyntaxError), 113 'basic-syntax17': ("{{ moo? }}", {}, template.TemplateSyntaxError), 114 115 # Attribute syntax allows a template to call a dictionary key's value 116 'basic-syntax18': ("{{ foo.bar }}", {"foo" : {"bar" : "baz"}}, "baz"), 117 118 # Fail silently when a variable's dictionary key isn't found 119 'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, "INVALID"), 120 121 # Fail silently when accessing a non-simple method 122 'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, "INVALID"), 123 124 # Basic filter usage 125 'basic-syntax21': ("{{ var|upper }}", {"var": "Django is the greatest!"}, "DJANGO IS THE GREATEST!"), 126 127 # Chained filters 128 'basic-syntax22': ("{{ var|upper|lower }}", {"var": "Django is the greatest!"}, "django is the greatest!"), 129 130 # Raise TemplateSyntaxError for space between a variable and filter pipe 131 'basic-syntax23': ("{{ var |upper }}", {}, template.TemplateSyntaxError), 132 133 # Raise TemplateSyntaxError for space after a filter pipe 134 'basic-syntax24': ("{{ var| upper }}", {}, template.TemplateSyntaxError), 135 136 # Raise TemplateSyntaxError for a nonexistent filter 137 'basic-syntax25': ("{{ var|does_not_exist }}", {}, template.TemplateSyntaxError), 138 139 # Raise TemplateSyntaxError when trying to access a filter containing an illegal character 140 'basic-syntax26': ("{{ var|fil(ter) }}", {}, template.TemplateSyntaxError), 141 142 # Raise TemplateSyntaxError for invalid block tags 143 'basic-syntax27': ("{% nothing_to_see_here %}", {}, template.TemplateSyntaxError), 144 145 # Raise TemplateSyntaxError for empty block tags 146 'basic-syntax28': ("{% %}", {}, template.TemplateSyntaxError), 147 148 # Chained filters, with an argument to the first one 149 'basic-syntax29': ('{{ var|removetags:"b i"|upper|lower }}', {"var": "<b><i>Yes</i></b>"}, "yes"), 150 151 # Escaped string as argument 152 'basic-syntax30': (r'{{ var|default_if_none:" endquote\" hah" }}', {"var": None}, ' endquote" hah'), 153 154 # Variable as argument 155 'basic-syntax31': (r'{{ var|default_if_none:var2 }}', {"var": None, "var2": "happy"}, 'happy'), 156 157 # Default argument testing 158 'basic-syntax32': (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'), 159 160 # Fail silently for methods that raise an exception with a "silent_variable_failure" attribute 161 'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, "1INVALID2"), 162 163 # In methods that raise an exception without a "silent_variable_attribute" set to True, 164 # the exception propogates 165 'basic-syntax34': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException), 166 167 # Escaped backslash in argument 168 'basic-syntax35': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'), 169 170 # Escaped backslash using known escape char 171 'basic-syntax35': (r'{{ var|default_if_none:"foo\now" }}', {"var": None}, r'foo\now'), 172 173 ### COMMENT TAG ########################################################### 174 'comment-tag01': ("{% comment %}this is hidden{% endcomment %}hello", {}, "hello"), 175 'comment-tag02': ("{% comment %}this is hidden{% endcomment %}hello{% comment %}foo{% endcomment %}", {}, "hello"), 176 177 # Comment tag can contain invalid stuff. 178 'comment-tag03': ("foo{% comment %} {% if %} {% endcomment %}", {}, "foo"), 179 'comment-tag04': ("foo{% comment %} {% endblock %} {% endcomment %}", {}, "foo"), 180 'comment-tag05': ("foo{% comment %} {% somerandomtag %} {% endcomment %}", {}, "foo"), 181 182 ### CYCLE TAG ############################################################# 183 'cycle01': ('{% cycle a %}', {}, template.TemplateSyntaxError), 184 'cycle02': ('{% cycle a,b,c as abc %}{% cycle abc %}', {}, 'ab'), 185 'cycle03': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}', {}, 'abc'), 186 'cycle04': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}', {}, 'abca'), 187 'cycle05': ('{% cycle %}', {}, template.TemplateSyntaxError), 188 'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError), 189 'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError), 190 191 ### EXCEPTIONS ############################################################ 192 193 # Raise exception for invalid template name 194 'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateSyntaxError), 195 196 # Raise exception for invalid template name (in variable) 197 'exception02': ("{% extends nonexistent %}", {}, template.TemplateSyntaxError), 198 199 # Raise exception for extra {% extends %} tags 200 'exception03': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% extends 'inheritance16' %}", {}, template.TemplateSyntaxError), 201 202 # Raise exception for custom tags used in child with {% load %} tag in parent, not in child 203 'exception04': ("{% extends 'inheritance17' %}{% block first %}{% echo 400 %}5678{% endblock %}", {}, template.TemplateSyntaxError), 204 205 ### FILTER TAG ############################################################ 206 'filter01': ('{% filter upper %}{% endfilter %}', {}, ''), 207 'filter02': ('{% filter upper %}django{% endfilter %}', {}, 'DJANGO'), 208 'filter03': ('{% filter upper|lower %}django{% endfilter %}', {}, 'django'), 209 210 ### FIRSTOF TAG ########################################################### 211 'firstof01': ('{% firstof a b c %}', {'a':0,'b':0,'c':0}, ''), 212 'firstof02': ('{% firstof a b c %}', {'a':1,'b':0,'c':0}, '1'), 213 'firstof03': ('{% firstof a b c %}', {'a':0,'b':2,'c':0}, '2'), 214 'firstof04': ('{% firstof a b c %}', {'a':0,'b':0,'c':3}, '3'), 215 'firstof05': ('{% firstof a b c %}', {'a':1,'b':2,'c':3}, '1'), 216 'firstof06': ('{% firstof %}', {}, template.TemplateSyntaxError), 217 218 ### FOR TAG ############################################################### 219 'for-tag01': ("{% for val in values %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "123"), 220 'for-tag02': ("{% for val in values reversed %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "321"), 221 'for-tag-vars01': ("{% for val in values %}{{ forloop.counter }}{% endfor %}", {"values": [6, 6, 6]}, "123"), 222 'for-tag-vars02': ("{% for val in values %}{{ forloop.counter0 }}{% endfor %}", {"values": [6, 6, 6]}, "012"), 223 'for-tag-vars03': ("{% for val in values %}{{ forloop.revcounter }}{% endfor %}", {"values": [6, 6, 6]}, "321"), 224 'for-tag-vars04': ("{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}", {"values": [6, 6, 6]}, "210"), 225 226 ### IF TAG ################################################################ 227 'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"), 228 'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"), 229 'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"), 230 231 # AND 232 'if-tag-and01': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), 233 'if-tag-and02': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), 234 'if-tag-and03': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), 235 'if-tag-and04': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), 236 'if-tag-and05': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'), 237 'if-tag-and06': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'), 238 'if-tag-and07': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True}, 'no'), 239 'if-tag-and08': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': True}, 'no'), 240 241 # OR 242 'if-tag-or01': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), 243 'if-tag-or02': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), 244 'if-tag-or03': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), 245 'if-tag-or04': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), 246 'if-tag-or05': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'), 247 'if-tag-or06': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'), 248 'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'), 249 'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'), 250 251 # TODO: multiple ORs 252 253 # NOT 254 'if-tag-not01': ("{% if not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'yes'), 255 'if-tag-not02': ("{% if not %}yes{% else %}no{% endif %}", {'foo': True}, 'no'), 256 'if-tag-not03': ("{% if not %}yes{% else %}no{% endif %}", {'not': True}, 'yes'), 257 'if-tag-not04': ("{% if not not %}no{% else %}yes{% endif %}", {'not': True}, 'yes'), 258 'if-tag-not05': ("{% if not not %}no{% else %}yes{% endif %}", {}, 'no'), 259 260 'if-tag-not06': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {}, 'no'), 261 'if-tag-not07': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), 262 'if-tag-not08': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), 263 'if-tag-not09': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), 264 'if-tag-not10': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), 265 266 'if-tag-not11': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {}, 'no'), 267 'if-tag-not12': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), 268 'if-tag-not13': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), 269 'if-tag-not14': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), 270 'if-tag-not15': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'), 271 272 'if-tag-not16': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'), 273 'if-tag-not17': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), 274 'if-tag-not18': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), 275 'if-tag-not19': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), 276 'if-tag-not20': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), 277 278 'if-tag-not21': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {}, 'yes'), 279 'if-tag-not22': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'), 280 'if-tag-not23': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), 281 'if-tag-not24': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), 282 'if-tag-not25': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), 283 284 'if-tag-not26': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {}, 'yes'), 285 'if-tag-not27': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), 286 'if-tag-not28': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'), 287 'if-tag-not29': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'), 288 'if-tag-not30': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), 289 290 'if-tag-not31': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'), 291 'if-tag-not32': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'), 292 'if-tag-not33': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'), 293 'if-tag-not34': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'), 294 'if-tag-not35': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'), 295 296 # AND and OR raises a TemplateSyntaxError 297 'if-tag-error01': ("{% if foo or bar and baz %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, template.TemplateSyntaxError), 298 'if-tag-error02': ("{% if foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), 299 'if-tag-error03': ("{% if foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), 300 'if-tag-error04': ("{% if not foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), 301 'if-tag-error05': ("{% if not foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError), 302 303 ### IFCHANGED TAG ######################################################### 304 'ifchanged01': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,2,3) }, '123'), 305 'ifchanged02': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,1,3) }, '13'), 306 'ifchanged03': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,1,1) }, '1'), 307 308 ### IFEQUAL TAG ########################################################### 309 'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""), 310 'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"), 311 'ifequal03': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 2}, "no"), 312 'ifequal04': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 1}, "yes"), 313 'ifequal05': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "test"}, "yes"), 314 'ifequal06': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "no"}, "no"), 315 'ifequal07': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "test"}, "yes"), 316 'ifequal08': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "no"}, "no"), 317 'ifequal09': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {}, "no"), 318 'ifequal10': ('{% ifequal a b %}yes{% else %}no{% endifequal %}', {}, "yes"), 319 320 # SMART SPLITTING 321 'ifequal-split01': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {}, "no"), 322 'ifequal-split02': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'foo'}, "no"), 323 'ifequal-split03': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'test man'}, "yes"), 324 'ifequal-split04': ("{% ifequal a 'test man' %}yes{% else %}no{% endifequal %}", {'a': 'test man'}, "yes"), 325 'ifequal-split05': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': ''}, "no"), 326 'ifequal-split06': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i "love" you'}, "yes"), 327 'ifequal-split07': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i love you'}, "no"), 328 'ifequal-split08': (r"{% ifequal a 'I\'m happy' %}yes{% else %}no{% endifequal %}", {'a': "I'm happy"}, "yes"), 329 'ifequal-split09': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slash\man"}, "yes"), 330 'ifequal-split10': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slashman"}, "no"), 331 332 ### IFNOTEQUAL TAG ######################################################## 333 'ifnotequal01': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 2}, "yes"), 334 'ifnotequal02': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 1}, ""), 335 'ifnotequal03': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 2}, "yes"), 336 'ifnotequal04': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 1}, "no"), 337 338 ### INCLUDE TAG ########################################################### 339 'include01': ('{% include "basic-syntax01" %}', {}, "something cool"), 340 'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"), 341 'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"), 342 'include04': ('a{% include "nonexistent" %}b', {}, "ab"), 343 344 ### INHERITANCE ########################################################### 345 346 # Standard template with no inheritance 347 'inheritance01': ("1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", {}, '1_3_'), 348 349 # Standard two-level inheritance 350 'inheritance02': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'), 351 352 # Three-level with no redefinitions on third level 353 'inheritance03': ("{% extends 'inheritance02' %}", {}, '1234'), 354 355 # Two-level with no redefinitions on second level 356 'inheritance04': ("{% extends 'inheritance01' %}", {}, '1_3_'), 357 358 # Two-level with double quotes instead of single quotes 359 'inheritance05': ('{% extends "inheritance02" %}', {}, '1234'), 360 361 # Three-level with variable parent-template name 362 'inheritance06': ("{% extends foo %}", {'foo': 'inheritance02'}, '1234'), 363 364 # Two-level with one block defined, one block not defined 365 'inheritance07': ("{% extends 'inheritance01' %}{% block second %}5{% endblock %}", {}, '1_35'), 366 367 # Three-level with one block defined on this level, two blocks defined next level 368 'inheritance08': ("{% extends 'inheritance02' %}{% block second %}5{% endblock %}", {}, '1235'), 369 370 # Three-level with second and third levels blank 371 'inheritance09': ("{% extends 'inheritance04' %}", {}, '1_3_'), 372 373 # Three-level with space NOT in a block -- should be ignored 374 'inheritance10': ("{% extends 'inheritance04' %} ", {}, '1_3_'), 375 376 # Three-level with both blocks defined on this level, but none on second level 377 'inheritance11': ("{% extends 'inheritance04' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'), 378 379 # Three-level with this level providing one and second level providing the other 380 'inheritance12': ("{% extends 'inheritance07' %}{% block first %}2{% endblock %}", {}, '1235'), 381 382 # Three-level with this level overriding second level 383 'inheritance13': ("{% extends 'inheritance02' %}{% block first %}a{% endblock %}{% block second %}b{% endblock %}", {}, '1a3b'), 384 385 # A block defined only in a child template shouldn't be displayed 386 'inheritance14': ("{% extends 'inheritance01' %}{% block newblock %}NO DISPLAY{% endblock %}", {}, '1_3_'), 387 388 # A block within another block 389 'inheritance15': ("{% extends 'inheritance01' %}{% block first %}2{% block inner %}inner{% endblock %}{% endblock %}", {}, '12inner3_'), 390 391 # A block within another block (level 2) 392 'inheritance16': ("{% extends 'inheritance15' %}{% block inner %}out{% endblock %}", {}, '12out3_'), 393 394 # {% load %} tag (parent -- setup for exception04) 395 'inheritance17': ("{% load testtags %}{% block first %}1234{% endblock %}", {}, '1234'), 396 397 # {% load %} tag (standard usage, without inheritance) 398 'inheritance18': ("{% load testtags %}{% echo this that theother %}5678", {}, 'this that theother5678'), 399 400 # {% load %} tag (within a child template) 401 'inheritance19': ("{% extends 'inheritance01' %}{% block first %}{% load testtags %}{% echo 400 %}5678{% endblock %}", {}, '140056783_'), 402 403 # Two-level inheritance with {{ block.super }} 404 'inheritance20': ("{% extends 'inheritance01' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'), 405 406 # Three-level inheritance with {{ block.super }} from parent 407 'inheritance21': ("{% extends 'inheritance02' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '12a34'), 408 409 # Three-level inheritance with {{ block.super }} from grandparent 410 'inheritance22': ("{% extends 'inheritance04' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'), 411 412 # Three-level inheritance with {{ block.super }} from parent and grandparent 413 'inheritance23': ("{% extends 'inheritance20' %}{% block first %}{{ block.super }}b{% endblock %}", {}, '1_ab3_'), 414 415 # Inheritance from local context without use of template loader 416 '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'), 417 418 # Inheritance from local context with variable parent template 419 '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'), 420 421 ### I18N ################################################################## 422 423 # {% spaceless %} tag 424 'spaceless01': ("{% spaceless %} <b> <i> text </i> </b> {% endspaceless %}", {}, "<b> <i> text </i> </b>"), 425 'spaceless02': ("{% spaceless %} <b> \n <i> text </i> \n </b> {% endspaceless %}", {}, "<b> <i> text </i> </b>"), 426 'spaceless03': ("{% spaceless %}<b><i>text</i></b>{% endspaceless %}", {}, "<b><i>text</i></b>"), 427 428 # simple translation of a string delimited by ' 429 'i18n01': ("{% load i18n %}{% trans 'xxxyyyxxx' %}", {}, "xxxyyyxxx"), 430 431 # simple translation of a string delimited by " 432 'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, "xxxyyyxxx"), 433 434 # simple translation of a variable 435 'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"), 436 437 # simple translation of a variable and filter 438 'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"), 439 440 # simple translation of a string with interpolation 441 'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"), 442 443 # simple translation of a string to german 444 'i18n06': ('{% load i18n %}{% trans "Page not found" %}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"), 445 446 # translation of singular form 447 'i18n07': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 1}, "singular"), 448 449 # translation of plural form 450 'i18n08': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 2}, "plural"), 451 452 # simple non-translation (only marking) of a string to german 453 'i18n09': ('{% load i18n %}{% trans "Page not found" noop %}', {'LANGUAGE_CODE': 'de'}, "Page not found"), 454 455 # translation of a variable with a translated filter 456 'i18n10': ('{{ bool|yesno:_("ja,nein") }}', {'bool': True}, 'ja'), 457 458 # translation of a variable with a non-translated filter 459 'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'), 460 461 # usage of the get_available_languages tag 462 'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'), 463 464 # translation of a constant string 465 'i18n13': ('{{ _("Page not found") }}', {'LANGUAGE_CODE': 'de'}, 'Seite nicht gefunden'), 466 467 ### MULTILINE ############################################################# 468 469 'multiline01': (""" 470 Hello, 471 boys. 472 How 473 are 474 you 475 gentlemen. 476 """, 477 {}, 478 """ 479 Hello, 480 boys. 481 How 482 are 483 you 484 gentlemen. 485 """), 486 487 ### REGROUP TAG ########################################################### 488 'regroup01': ('{% regroup data by bar as grouped %}' + \ 489 '{% for group in grouped %}' + \ 490 '{{ group.grouper }}:' + \ 491 '{% for item in group.list %}' + \ 492 '{{ item.foo }}' + \ 493 '{% endfor %},' + \ 494 '{% endfor %}', 495 {'data': [ {'foo':'c', 'bar':1}, 496 {'foo':'d', 'bar':1}, 497 {'foo':'a', 'bar':2}, 498 {'foo':'b', 'bar':2}, 499 {'foo':'x', 'bar':3} ]}, 500 '1:cd,2:ab,3:x,'), 501 502 # Test for silent failure when target variable isn't found 503 'regroup02': ('{% regroup data by bar as grouped %}' + \ 504 '{% for group in grouped %}' + \ 505 '{{ group.grouper }}:' + \ 506 '{% for item in group.list %}' + \ 507 '{{ item.foo }}' + \ 508 '{% endfor %},' + \ 509 '{% endfor %}', 510 {}, 'INVALID:INVALIDINVALIDINVALIDINVALIDINVALIDINVALIDINVALID,'), 511 512 ### TEMPLATETAG TAG ####################################################### 513 'templatetag01': ('{% templatetag openblock %}', {}, '{%'), 514 'templatetag02': ('{% templatetag closeblock %}', {}, '%}'), 515 'templatetag03': ('{% templatetag openvariable %}', {}, '{{'), 516 'templatetag04': ('{% templatetag closevariable %}', {}, '}}'), 517 'templatetag05': ('{% templatetag %}', {}, template.TemplateSyntaxError), 518 'templatetag06': ('{% templatetag foo %}', {}, template.TemplateSyntaxError), 519 'templatetag07': ('{% templatetag openbrace %}', {}, '{'), 520 'templatetag08': ('{% templatetag closebrace %}', {}, '}'), 521 'templatetag09': ('{% templatetag openbrace %}{% templatetag openbrace %}', {}, '{{'), 522 'templatetag10': ('{% templatetag closebrace %}{% templatetag closebrace %}', {}, '}}'), 523 524 ### WIDTHRATIO TAG ######################################################## 525 'widthratio01': ('{% widthratio a b 0 %}', {'a':50,'b':100}, '0'), 526 'widthratio02': ('{% widthratio a b 100 %}', {'a':0,'b':0}, ''), 527 'widthratio03': ('{% widthratio a b 100 %}', {'a':0,'b':100}, '0'), 528 'widthratio04': ('{% widthratio a b 100 %}', {'a':50,'b':100}, '50'), 529 'widthratio05': ('{% widthratio a b 100 %}', {'a':100,'b':100}, '100'), 530 531 # 62.5 should round to 63 532 'widthratio06': ('{% widthratio a b 100 %}', {'a':50,'b':80}, '63'), 533 534 # 71.4 should round to 71 535 'widthratio07': ('{% widthratio a b 100 %}', {'a':50,'b':70}, '71'), 536 537 # Raise exception if we don't have 3 args, last one an integer 538 'widthratio08': ('{% widthratio %}', {}, template.TemplateSyntaxError), 539 'widthratio09': ('{% widthratio a b %}', {'a':50,'b':100}, template.TemplateSyntaxError), 540 'widthratio10': ('{% widthratio a b 100.0 %}', {'a':50,'b':100}, template.TemplateSyntaxError), 541 542 ### NOW TAG ######################################################## 543 # Simple case 544 'now01' : ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)), 545 546 # Check parsing of escaped and special characters 547 'now02' : ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError), 548 # 'now03' : ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)), 549 # 'now04' : ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year)) 550 551 ### TIMESINCE TAG ################################################## 552 # Default compare with datetime.now() 553 'timesince01' : ('{{ a|timesince }}', {'a':datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1 minute'), 554 'timesince02' : ('{{ a|timesince }}', {'a':(datetime.now() - timedelta(days=1, minutes = 1))}, '1 day'), 555 'timesince03' : ('{{ a|timesince }}', {'a':(datetime.now() - 556 timedelta(hours=1, minutes=25, seconds = 10))}, '1 hour, 25 minutes'), 557 558 # Compare to a given parameter 559 'timesince04' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2), 'b':NOW + timedelta(days=1)}, '1 day'), 560 'timesince05' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2, minutes=1), 'b':NOW + timedelta(days=2)}, '1 minute'), 561 562 # Check that timezone is respected 563 'timesince06' : ('{{ a|timesince:b }}', {'a':NOW_tz + timedelta(hours=8), 'b':NOW_tz}, '8 hours'), 564 565 ### TIMEUNTIL TAG ################################################## 566 # Default compare with datetime.now() 567 'timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'), 568 'timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1 day'), 569 'timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8 hours, 10 minutes'), 570 571 # Compare to a given parameter 572 'timeuntil04' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=1), 'b':NOW - timedelta(days=2)}, '1 day'), 573 'timeuntil05' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=2), 'b':NOW - timedelta(days=2, minutes=1)}, '1 minute'), 574 } 575 576 # Register our custom template loader. 577 def test_template_loader(template_name, template_dirs=None): 578 "A custom template loader that loads the unit-test templates." 579 try: 580 return (TEMPLATE_TESTS[template_name][0] , "test:%s" % template_name) 581 except KeyError: 582 raise template.TemplateDoesNotExist, template_name 583 584 old_template_loaders = loader.template_source_loaders 585 loader.template_source_loaders = [test_template_loader] 586 587 failures = [] 588 tests = TEMPLATE_TESTS.items() 589 tests.sort() 590 591 # Turn TEMPLATE_DEBUG off, because tests assume that. 592 old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, False 593 594 # Set TEMPLATE_STRING_IF_INVALID to a known string 595 old_invalid, settings.TEMPLATE_STRING_IF_INVALID = settings.TEMPLATE_STRING_IF_INVALID, 'INVALID' 596 597 for name, vals in tests: 598 install() 599 if 'LANGUAGE_CODE' in vals[1]: 600 activate(vals[1]['LANGUAGE_CODE']) 601 else: 602 activate('en-us') 603 try: 604 output = loader.get_template(name).render(template.Context(vals[1])) 605 except Exception, e: 606 if e.__class__ != vals[2]: 607 failures.append("Template test: %s -- FAILED. Got %s, exception: %s" % (name, e.__class__, e)) 608 continue 609 610 if 'LANGUAGE_CODE' in vals[1]: 611 deactivate() 612 if output != vals[2]: 613 failures.append("Template test: %s -- FAILED. Expected %r, got %r" % (name, vals[2], output)) 614 loader.template_source_loaders = old_template_loaders 615 deactivate() 616 settings.TEMPLATE_DEBUG = old_td 617 settings.TEMPLATE_STRING_IF_INVALID = old_invalid 618 619 self.assertEqual(failures,[]) 620 621 if __name__ == '__main__': 622 unittest.main() -
tests/regressiontests/urlpatterns_reverse/tests.py
1 "Unit tests for reverse URL lookup" 2 3 from django.core.urlresolvers import reverse_helper, NoReverseMatch 4 import re 5 6 test_data = ( 7 ('^places/(\d+)/$', 'places/3/', [3], {}), 8 ('^places/(\d+)/$', 'places/3/', ['3'], {}), 9 ('^places/(\d+)/$', NoReverseMatch, ['a'], {}), 10 ('^places/(\d+)/$', NoReverseMatch, [], {}), 11 ('^places/(?P<id>\d+)/$', 'places/3/', [], {'id': 3}), 12 ('^people/(?P<name>\w+)/$', 'people/adrian/', ['adrian'], {}), 13 ('^people/(?P<name>\w+)/$', 'people/adrian/', [], {'name': 'adrian'}), 14 ('^people/(?P<name>\w+)/$', NoReverseMatch, ['name with spaces'], {}), 15 ('^people/(?P<name>\w+)/$', NoReverseMatch, [], {'name': 'name with spaces'}), 16 ('^people/(?P<name>\w+)/$', NoReverseMatch, [], {}), 17 ('^hardcoded/$', 'hardcoded/', [], {}), 18 ('^hardcoded/$', 'hardcoded/', ['any arg'], {}), 19 ('^hardcoded/$', 'hardcoded/', [], {'kwarg': 'foo'}), 20 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', 'people/il/adrian/', [], {'state': 'il', 'name': 'adrian'}), 21 ('^people/(?P<state>\w\w)/(?P<name>\d)/$', NoReverseMatch, [], {'state': 'il', 'name': 'adrian'}), 22 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', NoReverseMatch, [], {'state': 'il'}), 23 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', NoReverseMatch, [], {'name': 'adrian'}), 24 ('^people/(?P<state>\w\w)/(\w+)/$', NoReverseMatch, ['il'], {'name': 'adrian'}), 25 ('^people/(?P<state>\w\w)/(\w+)/$', 'people/il/adrian/', ['adrian'], {'state': 'il'}), 26 ) 27 28 def run_tests(verbosity=0): 29 for regex, expected, args, kwargs in test_data: 30 passed = True 31 try: 32 got = reverse_helper(re.compile(regex), *args, **kwargs) 33 except NoReverseMatch, e: 34 if expected != NoReverseMatch: 35 passed, got = False, str(e) 36 else: 37 if got != expected: 38 passed, got = False, got 39 if passed and verbosity: 40 print "Passed: %s" % regex 41 elif not passed: 42 print "REVERSE LOOKUP FAILED: %s" % regex 43 print " Got: %s" % got 44 print " Expected: %r" % expected 45 46 if __name__ == "__main__": 47 run_tests(1) -
tests/othertests/defaultfilters.py
1 r"""2 >>> floatformat(7.7)3 '7.7'4 >>> floatformat(7.0)5 '7'6 >>> floatformat(0.7)7 '0.7'8 >>> floatformat(0.07)9 '0.1'10 >>> floatformat(0.007)11 '0.0'12 >>> floatformat(0.0)13 '0'14 15 >>> addslashes('"double quotes" and \'single quotes\'')16 '\\"double quotes\\" and \\\'single quotes\\\''17 18 >>> capfirst('hello world')19 'Hello world'20 21 >>> fix_ampersands('Jack & Jill & Jeroboam')22 'Jack & Jill & Jeroboam'23 24 >>> linenumbers('line 1\nline 2')25 '1. line 1\n2. line 2'26 27 >>> linenumbers('\n'.join(['x'] * 10))28 '01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. x\n08. x\n09. x\n10. x'29 30 >>> lower('TEST')31 'test'32 33 >>> lower(u'\xcb') # uppercase E umlaut34 u'\xeb'35 36 >>> make_list('abc')37 ['a', 'b', 'c']38 39 >>> make_list(1234)40 ['1', '2', '3', '4']41 42 >>> slugify(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/')43 'jack-jill-like-numbers-123-and-4-and-silly-characters'44 45 >>> stringformat(1, '03d')46 '001'47 48 >>> stringformat(1, 'z')49 ''50 51 >>> title('a nice title, isn\'t it?')52 "A Nice Title, Isn't It?"53 54 55 >>> truncatewords('A sentence with a few words in it', 1)56 'A ...'57 58 >>> truncatewords('A sentence with a few words in it', 5)59 'A sentence with a few ...'60 61 >>> truncatewords('A sentence with a few words in it', 100)62 'A sentence with a few words in it'63 64 >>> truncatewords('A sentence with a few words in it', 'not a number')65 'A sentence with a few words in it'66 67 68 >>> upper('Mixed case input')69 'MIXED CASE INPUT'70 71 >>> upper(u'\xeb') # lowercase e umlaut72 u'\xcb'73 74 75 >>> urlencode('jack & jill')76 'jack%20%26%20jill'77 78 79 >>> urlizetrunc('http://short.com/', 20)80 '<a href="http://short.com/" rel="nofollow">http://short.com/</a>'81 82 >>> urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20)83 '<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=" rel="nofollow">http://www.google.co...</a>'84 85 >>> wordcount('')86 087 88 >>> wordcount('oneword')89 190 91 >>> wordcount('lots of words')92 393 94 >>> wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14)95 "this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid"96 97 >>> ljust('test', 10)98 'test '99 100 >>> ljust('test', 3)101 'test'102 103 >>> rjust('test', 10)104 ' test'105 106 >>> rjust('test', 3)107 'test'108 109 >>> center('test', 6)110 ' test '111 112 >>> cut('a string to be mangled', 'a')113 ' string to be mngled'114 115 >>> cut('a string to be mangled', 'ng')116 'a stri to be maled'117 118 >>> cut('a string to be mangled', 'strings')119 'a string to be mangled'120 121 >>> escape('<some html & special characters > here')122 '<some html & special characters > here'123 124 >>> linebreaks('line 1')125 '<p>line 1</p>'126 127 >>> linebreaks('line 1\nline 2')128 '<p>line 1<br />line 2</p>'129 130 >>> removetags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img')131 'some <b>html</b> with alert("You smell") disallowed tags'132 133 >>> striptags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags')134 'some html with alert("You smell") disallowed tags'135 136 >>> dictsort([{'age': 23, 'name': 'Barbara-Ann'},137 ... {'age': 63, 'name': 'Ra Ra Rasputin'},138 ... {'name': 'Jonny B Goode', 'age': 18}], 'age')139 [{'age': 18, 'name': 'Jonny B Goode'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 63, 'name': 'Ra Ra Rasputin'}]140 141 >>> dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'},142 ... {'age': 63, 'name': 'Ra Ra Rasputin'},143 ... {'name': 'Jonny B Goode', 'age': 18}], 'age')144 [{'age': 63, 'name': 'Ra Ra Rasputin'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 18, 'name': 'Jonny B Goode'}]145 146 >>> first([0,1,2])147 0148 149 >>> first('')150 ''151 152 >>> first('test')153 't'154 155 >>> join([0,1,2], 'glue')156 '0glue1glue2'157 158 >>> length('1234')159 4160 161 >>> length([1,2,3,4])162 4163 164 >>> length_is([], 0)165 True166 167 >>> length_is([], 1)168 False169 170 >>> length_is('a', 1)171 True172 173 >>> length_is('a', 10)174 False175 176 >>> slice_('abcdefg', '0')177 ''178 179 >>> slice_('abcdefg', '1')180 'a'181 182 >>> slice_('abcdefg', '-1')183 'abcdef'184 185 >>> slice_('abcdefg', '1:2')186 'b'187 188 >>> slice_('abcdefg', '1:3')189 'bc'190 191 >>> slice_('abcdefg', '0::2')192 'aceg'193 194 >>> unordered_list(['item 1', []])195 '\t<li>item 1</li>'196 197 >>> unordered_list(['item 1', [['item 1.1', []]]])198 '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>'199 200 >>> unordered_list(['item 1', [['item 1.1', []], ['item 1.2', []]]])201 '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>'202 203 >>> add('1', '2')204 3205 206 >>> get_digit(123, 1)207 3208 209 >>> get_digit(123, 2)210 2211 212 >>> get_digit(123, 3)213 1214 215 >>> get_digit(123, 4)216 0217 218 >>> get_digit(123, 0)219 123220 221 >>> get_digit('xyz', 0)222 'xyz'223 224 # real testing of date() is in dateformat.py225 >>> date(datetime.datetime(2005, 12, 29), "d F Y")226 '29 December 2005'227 >>> date(datetime.datetime(2005, 12, 29), r'jS o\f F')228 '29th of December'229 230 # real testing of time() is done in dateformat.py231 >>> time(datetime.time(13), "h")232 '01'233 234 # real testing is done in timesince.py, where we can provide our own 'now'235 >>> timesince(datetime.datetime.now() - datetime.timedelta(1))236 '1 day'237 238 >>> default("val", "default")239 'val'240 241 >>> default(None, "default")242 'default'243 244 >>> default('', "default")245 'default'246 247 >>> default_if_none("val", "default")248 'val'249 250 >>> default_if_none(None, "default")251 'default'252 253 >>> default_if_none('', "default")254 ''255 256 >>> divisibleby(4, 2)257 True258 259 >>> divisibleby(4, 3)260 False261 262 >>> yesno(True)263 'yes'264 265 >>> yesno(False)266 'no'267 268 >>> yesno(None)269 'maybe'270 271 >>> yesno(True, 'certainly,get out of town,perhaps')272 'certainly'273 274 >>> yesno(False, 'certainly,get out of town,perhaps')275 'get out of town'276 277 >>> yesno(None, 'certainly,get out of town,perhaps')278 'perhaps'279 280 >>> yesno(None, 'certainly,get out of town')281 'get out of town'282 283 >>> filesizeformat(1023)284 '1023 bytes'285 286 >>> filesizeformat(1024)287 '1.0 KB'288 289 >>> filesizeformat(10*1024)290 '10.0 KB'291 292 >>> filesizeformat(1024*1024-1)293 '1024.0 KB'294 295 >>> filesizeformat(1024*1024)296 '1.0 MB'297 298 >>> filesizeformat(1024*1024*50)299 '50.0 MB'300 301 >>> filesizeformat(1024*1024*1024-1)302 '1024.0 MB'303 304 >>> filesizeformat(1024*1024*1024)305 '1.0 GB'306 307 >>> pluralize(1)308 ''309 310 >>> pluralize(0)311 's'312 313 >>> pluralize(2)314 's'315 316 >>> pluralize([1])317 ''318 319 >>> pluralize([])320 's'321 322 >>> pluralize([1,2,3])323 's'324 325 >>> pluralize(1,'es')326 ''327 328 >>> pluralize(0,'es')329 'es'330 331 >>> pluralize(2,'es')332 'es'333 334 >>> pluralize(1,'y,ies')335 'y'336 337 >>> pluralize(0,'y,ies')338 'ies'339 340 >>> pluralize(2,'y,ies')341 'ies'342 343 >>> pluralize(0,'y,ies,error')344 ''345 346 >>> phone2numeric('0800 flowers')347 '0800 3569377'348 349 350 351 """352 353 from django.template.defaultfilters import *354 import datetime355 356 if __name__ == '__main__':357 import doctest358 doctest.testmod() -
tests/othertests/templates.py
1 from django.conf import settings2 3 if __name__ == '__main__':4 # When running this file in isolation, we need to set up the configuration5 # before importing 'template'.6 settings.configure()7 8 from django import template9 from django.template import loader10 from django.utils.translation import activate, deactivate, install11 from django.utils.tzinfo import LocalTimezone12 from datetime import datetime, timedelta13 import traceback14 15 #################################16 # Custom template tag for tests #17 #################################18 19 register = template.Library()20 21 class EchoNode(template.Node):22 def __init__(self, contents):23 self.contents = contents24 25 def render(self, context):26 return " ".join(self.contents)27 28 def do_echo(parser, token):29 return EchoNode(token.contents.split()[1:])30 31 register.tag("echo", do_echo)32 33 template.libraries['django.templatetags.testtags'] = register34 35 #####################################36 # Helper objects for template tests #37 #####################################38 39 class SomeException(Exception):40 silent_variable_failure = True41 42 class SomeOtherException(Exception):43 pass44 45 class SomeClass:46 def __init__(self):47 self.otherclass = OtherClass()48 49 def method(self):50 return "SomeClass.method"51 52 def method2(self, o):53 return o54 55 def method3(self):56 raise SomeException57 58 def method4(self):59 raise SomeOtherException60 61 class OtherClass:62 def method(self):63 return "OtherClass.method"64 65 # NOW and NOW_tz are used by timesince tag tests.66 NOW = datetime.now()67 NOW_tz = datetime.now(LocalTimezone(datetime.now()))68 69 # SYNTAX --70 # 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class)71 TEMPLATE_TESTS = {72 73 ### BASIC SYNTAX ##########################################################74 75 # Plain text should go through the template parser untouched76 'basic-syntax01': ("something cool", {}, "something cool"),77 78 # Variables should be replaced with their value in the current context79 'basic-syntax02': ("{{ headline }}", {'headline':'Success'}, "Success"),80 81 # More than one replacement variable is allowed in a template82 'basic-syntax03': ("{{ first }} --- {{ second }}", {"first" : 1, "second" : 2}, "1 --- 2"),83 84 # Fail silently when a variable is not found in the current context85 'basic-syntax04': ("as{{ missing }}df", {}, "asINVALIDdf"),86 87 # A variable may not contain more than one word88 'basic-syntax06': ("{{ multi word variable }}", {}, template.TemplateSyntaxError),89 90 # Raise TemplateSyntaxError for empty variable tags91 'basic-syntax07': ("{{ }}", {}, template.TemplateSyntaxError),92 'basic-syntax08': ("{{ }}", {}, template.TemplateSyntaxError),93 94 # Attribute syntax allows a template to call an object's attribute95 'basic-syntax09': ("{{ var.method }}", {"var": SomeClass()}, "SomeClass.method"),96 97 # Multiple levels of attribute access are allowed98 'basic-syntax10': ("{{ var.otherclass.method }}", {"var": SomeClass()}, "OtherClass.method"),99 100 # Fail silently when a variable's attribute isn't found101 'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, "INVALID"),102 103 # Raise TemplateSyntaxError when trying to access a variable beginning with an underscore104 'basic-syntax12': ("{{ var.__dict__ }}", {"var": SomeClass()}, template.TemplateSyntaxError),105 106 # Raise TemplateSyntaxError when trying to access a variable containing an illegal character107 'basic-syntax13': ("{{ va>r }}", {}, template.TemplateSyntaxError),108 'basic-syntax14': ("{{ (var.r) }}", {}, template.TemplateSyntaxError),109 'basic-syntax15': ("{{ sp%am }}", {}, template.TemplateSyntaxError),110 'basic-syntax16': ("{{ eggs! }}", {}, template.TemplateSyntaxError),111 'basic-syntax17': ("{{ moo? }}", {}, template.TemplateSyntaxError),112 113 # Attribute syntax allows a template to call a dictionary key's value114 'basic-syntax18': ("{{ foo.bar }}", {"foo" : {"bar" : "baz"}}, "baz"),115 116 # Fail silently when a variable's dictionary key isn't found117 'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, "INVALID"),118 119 # Fail silently when accessing a non-simple method120 'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, "INVALID"),121 122 # Basic filter usage123 'basic-syntax21': ("{{ var|upper }}", {"var": "Django is the greatest!"}, "DJANGO IS THE GREATEST!"),124 125 # Chained filters126 'basic-syntax22': ("{{ var|upper|lower }}", {"var": "Django is the greatest!"}, "django is the greatest!"),127 128 # Raise TemplateSyntaxError for space between a variable and filter pipe129 'basic-syntax23': ("{{ var |upper }}", {}, template.TemplateSyntaxError),130 131 # Raise TemplateSyntaxError for space after a filter pipe132 'basic-syntax24': ("{{ var| upper }}", {}, template.TemplateSyntaxError),133 134 # Raise TemplateSyntaxError for a nonexistent filter135 'basic-syntax25': ("{{ var|does_not_exist }}", {}, template.TemplateSyntaxError),136 137 # Raise TemplateSyntaxError when trying to access a filter containing an illegal character138 'basic-syntax26': ("{{ var|fil(ter) }}", {}, template.TemplateSyntaxError),139 140 # Raise TemplateSyntaxError for invalid block tags141 'basic-syntax27': ("{% nothing_to_see_here %}", {}, template.TemplateSyntaxError),142 143 # Raise TemplateSyntaxError for empty block tags144 'basic-syntax28': ("{% %}", {}, template.TemplateSyntaxError),145 146 # Chained filters, with an argument to the first one147 'basic-syntax29': ('{{ var|removetags:"b i"|upper|lower }}', {"var": "<b><i>Yes</i></b>"}, "yes"),148 149 # Escaped string as argument150 'basic-syntax30': (r'{{ var|default_if_none:" endquote\" hah" }}', {"var": None}, ' endquote" hah'),151 152 # Variable as argument153 'basic-syntax31': (r'{{ var|default_if_none:var2 }}', {"var": None, "var2": "happy"}, 'happy'),154 155 # Default argument testing156 'basic-syntax32': (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'),157 158 # Fail silently for methods that raise an exception with a "silent_variable_failure" attribute159 'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, "1INVALID2"),160 161 # In methods that raise an exception without a "silent_variable_attribute" set to True,162 # the exception propogates163 'basic-syntax34': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException),164 165 # Escaped backslash in argument166 'basic-syntax35': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'),167 168 # Escaped backslash using known escape char169 'basic-syntax35': (r'{{ var|default_if_none:"foo\now" }}', {"var": None}, r'foo\now'),170 171 ### COMMENT TAG ###########################################################172 'comment-tag01': ("{% comment %}this is hidden{% endcomment %}hello", {}, "hello"),173 'comment-tag02': ("{% comment %}this is hidden{% endcomment %}hello{% comment %}foo{% endcomment %}", {}, "hello"),174 175 # Comment tag can contain invalid stuff.176 'comment-tag03': ("foo{% comment %} {% if %} {% endcomment %}", {}, "foo"),177 'comment-tag04': ("foo{% comment %} {% endblock %} {% endcomment %}", {}, "foo"),178 'comment-tag05': ("foo{% comment %} {% somerandomtag %} {% endcomment %}", {}, "foo"),179 180 ### CYCLE TAG #############################################################181 'cycle01': ('{% cycle a %}', {}, template.TemplateSyntaxError),182 'cycle02': ('{% cycle a,b,c as abc %}{% cycle abc %}', {}, 'ab'),183 'cycle03': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}', {}, 'abc'),184 'cycle04': ('{% cycle a,b,c as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}', {}, 'abca'),185 'cycle05': ('{% cycle %}', {}, template.TemplateSyntaxError),186 'cycle06': ('{% cycle a %}', {}, template.TemplateSyntaxError),187 'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError),188 189 ### EXCEPTIONS ############################################################190 191 # Raise exception for invalid template name192 'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateSyntaxError),193 194 # Raise exception for invalid template name (in variable)195 'exception02': ("{% extends nonexistent %}", {}, template.TemplateSyntaxError),196 197 # Raise exception for extra {% extends %} tags198 'exception03': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% extends 'inheritance16' %}", {}, template.TemplateSyntaxError),199 200 # Raise exception for custom tags used in child with {% load %} tag in parent, not in child201 'exception04': ("{% extends 'inheritance17' %}{% block first %}{% echo 400 %}5678{% endblock %}", {}, template.TemplateSyntaxError),202 203 ### FILTER TAG ############################################################204 'filter01': ('{% filter upper %}{% endfilter %}', {}, ''),205 'filter02': ('{% filter upper %}django{% endfilter %}', {}, 'DJANGO'),206 'filter03': ('{% filter upper|lower %}django{% endfilter %}', {}, 'django'),207 208 ### FIRSTOF TAG ###########################################################209 'firstof01': ('{% firstof a b c %}', {'a':0,'b':0,'c':0}, ''),210 'firstof02': ('{% firstof a b c %}', {'a':1,'b':0,'c':0}, '1'),211 'firstof03': ('{% firstof a b c %}', {'a':0,'b':2,'c':0}, '2'),212 'firstof04': ('{% firstof a b c %}', {'a':0,'b':0,'c':3}, '3'),213 'firstof05': ('{% firstof a b c %}', {'a':1,'b':2,'c':3}, '1'),214 'firstof06': ('{% firstof %}', {}, template.TemplateSyntaxError),215 216 ### FOR TAG ###############################################################217 'for-tag01': ("{% for val in values %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "123"),218 'for-tag02': ("{% for val in values reversed %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "321"),219 'for-tag-vars01': ("{% for val in values %}{{ forloop.counter }}{% endfor %}", {"values": [6, 6, 6]}, "123"),220 'for-tag-vars02': ("{% for val in values %}{{ forloop.counter0 }}{% endfor %}", {"values": [6, 6, 6]}, "012"),221 'for-tag-vars03': ("{% for val in values %}{{ forloop.revcounter }}{% endfor %}", {"values": [6, 6, 6]}, "321"),222 'for-tag-vars04': ("{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}", {"values": [6, 6, 6]}, "210"),223 224 ### IF TAG ################################################################225 'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"),226 'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"),227 'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"),228 229 # AND230 'if-tag-and01': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),231 'if-tag-and02': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),232 'if-tag-and03': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'),233 'if-tag-and04': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'),234 'if-tag-and05': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'),235 'if-tag-and06': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'),236 'if-tag-and07': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True}, 'no'),237 'if-tag-and08': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'bar': True}, 'no'),238 239 # OR240 'if-tag-or01': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),241 'if-tag-or02': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'),242 'if-tag-or03': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),243 'if-tag-or04': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'),244 'if-tag-or05': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': False}, 'no'),245 'if-tag-or06': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': False}, 'no'),246 'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'),247 'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'),248 249 # TODO: multiple ORs250 251 # NOT252 'if-tag-not01': ("{% if not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'yes'),253 'if-tag-not02': ("{% if not %}yes{% else %}no{% endif %}", {'foo': True}, 'no'),254 'if-tag-not03': ("{% if not %}yes{% else %}no{% endif %}", {'not': True}, 'yes'),255 'if-tag-not04': ("{% if not not %}no{% else %}yes{% endif %}", {'not': True}, 'yes'),256 'if-tag-not05': ("{% if not not %}no{% else %}yes{% endif %}", {}, 'no'),257 258 'if-tag-not06': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {}, 'no'),259 'if-tag-not07': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),260 'if-tag-not08': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'),261 'if-tag-not09': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'),262 'if-tag-not10': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'),263 264 'if-tag-not11': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {}, 'no'),265 'if-tag-not12': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),266 'if-tag-not13': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),267 'if-tag-not14': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),268 'if-tag-not15': ("{% if not foo and bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'no'),269 270 'if-tag-not16': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'),271 'if-tag-not17': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),272 'if-tag-not18': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'),273 'if-tag-not19': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'),274 'if-tag-not20': ("{% if foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),275 276 'if-tag-not21': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {}, 'yes'),277 'if-tag-not22': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),278 'if-tag-not23': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),279 'if-tag-not24': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),280 'if-tag-not25': ("{% if not foo or bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),281 282 'if-tag-not26': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {}, 'yes'),283 'if-tag-not27': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),284 'if-tag-not28': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),285 'if-tag-not29': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'no'),286 'if-tag-not30': ("{% if not foo and not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),287 288 'if-tag-not31': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {}, 'yes'),289 'if-tag-not32': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),290 'if-tag-not33': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'yes'),291 'if-tag-not34': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),292 'if-tag-not35': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),293 294 # AND and OR raises a TemplateSyntaxError295 'if-tag-error01': ("{% if foo or bar and baz %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, template.TemplateSyntaxError),296 'if-tag-error02': ("{% if foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),297 'if-tag-error03': ("{% if foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),298 'if-tag-error04': ("{% if not foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),299 'if-tag-error05': ("{% if not foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),300 301 ### IFCHANGED TAG #########################################################302 'ifchanged01': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,2,3) }, '123'),303 'ifchanged02': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,1,3) }, '13'),304 'ifchanged03': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', { 'num': (1,1,1) }, '1'),305 306 ### IFEQUAL TAG ###########################################################307 'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),308 'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"),309 'ifequal03': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 2}, "no"),310 'ifequal04': ("{% ifequal a b %}yes{% else %}no{% endifequal %}", {"a": 1, "b": 1}, "yes"),311 'ifequal05': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "test"}, "yes"),312 'ifequal06': ("{% ifequal a 'test' %}yes{% else %}no{% endifequal %}", {"a": "no"}, "no"),313 'ifequal07': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "test"}, "yes"),314 'ifequal08': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {"a": "no"}, "no"),315 'ifequal09': ('{% ifequal a "test" %}yes{% else %}no{% endifequal %}', {}, "no"),316 'ifequal10': ('{% ifequal a b %}yes{% else %}no{% endifequal %}', {}, "yes"),317 318 # SMART SPLITTING319 'ifequal-split01': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {}, "no"),320 'ifequal-split02': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'foo'}, "no"),321 'ifequal-split03': ('{% ifequal a "test man" %}yes{% else %}no{% endifequal %}', {'a': 'test man'}, "yes"),322 'ifequal-split04': ("{% ifequal a 'test man' %}yes{% else %}no{% endifequal %}", {'a': 'test man'}, "yes"),323 'ifequal-split05': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': ''}, "no"),324 'ifequal-split06': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i "love" you'}, "yes"),325 'ifequal-split07': ("{% ifequal a 'i \"love\" you' %}yes{% else %}no{% endifequal %}", {'a': 'i love you'}, "no"),326 'ifequal-split08': (r"{% ifequal a 'I\'m happy' %}yes{% else %}no{% endifequal %}", {'a': "I'm happy"}, "yes"),327 'ifequal-split09': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slash\man"}, "yes"),328 'ifequal-split10': (r"{% ifequal a 'slash\man' %}yes{% else %}no{% endifequal %}", {'a': r"slashman"}, "no"),329 330 ### IFNOTEQUAL TAG ########################################################331 'ifnotequal01': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 2}, "yes"),332 'ifnotequal02': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 1}, ""),333 'ifnotequal03': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 2}, "yes"),334 'ifnotequal04': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 1}, "no"),335 336 ### INCLUDE TAG ###########################################################337 'include01': ('{% include "basic-syntax01" %}', {}, "something cool"),338 'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"),339 'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"),340 'include04': ('a{% include "nonexistent" %}b', {}, "ab"),341 342 ### INHERITANCE ###########################################################343 344 # Standard template with no inheritance345 'inheritance01': ("1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", {}, '1_3_'),346 347 # Standard two-level inheritance348 'inheritance02': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'),349 350 # Three-level with no redefinitions on third level351 'inheritance03': ("{% extends 'inheritance02' %}", {}, '1234'),352 353 # Two-level with no redefinitions on second level354 'inheritance04': ("{% extends 'inheritance01' %}", {}, '1_3_'),355 356 # Two-level with double quotes instead of single quotes357 'inheritance05': ('{% extends "inheritance02" %}', {}, '1234'),358 359 # Three-level with variable parent-template name360 'inheritance06': ("{% extends foo %}", {'foo': 'inheritance02'}, '1234'),361 362 # Two-level with one block defined, one block not defined363 'inheritance07': ("{% extends 'inheritance01' %}{% block second %}5{% endblock %}", {}, '1_35'),364 365 # Three-level with one block defined on this level, two blocks defined next level366 'inheritance08': ("{% extends 'inheritance02' %}{% block second %}5{% endblock %}", {}, '1235'),367 368 # Three-level with second and third levels blank369 'inheritance09': ("{% extends 'inheritance04' %}", {}, '1_3_'),370 371 # Three-level with space NOT in a block -- should be ignored372 'inheritance10': ("{% extends 'inheritance04' %} ", {}, '1_3_'),373 374 # Three-level with both blocks defined on this level, but none on second level375 'inheritance11': ("{% extends 'inheritance04' %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {}, '1234'),376 377 # Three-level with this level providing one and second level providing the other378 'inheritance12': ("{% extends 'inheritance07' %}{% block first %}2{% endblock %}", {}, '1235'),379 380 # Three-level with this level overriding second level381 'inheritance13': ("{% extends 'inheritance02' %}{% block first %}a{% endblock %}{% block second %}b{% endblock %}", {}, '1a3b'),382 383 # A block defined only in a child template shouldn't be displayed384 'inheritance14': ("{% extends 'inheritance01' %}{% block newblock %}NO DISPLAY{% endblock %}", {}, '1_3_'),385 386 # A block within another block387 'inheritance15': ("{% extends 'inheritance01' %}{% block first %}2{% block inner %}inner{% endblock %}{% endblock %}", {}, '12inner3_'),388 389 # A block within another block (level 2)390 'inheritance16': ("{% extends 'inheritance15' %}{% block inner %}out{% endblock %}", {}, '12out3_'),391 392 # {% load %} tag (parent -- setup for exception04)393 'inheritance17': ("{% load testtags %}{% block first %}1234{% endblock %}", {}, '1234'),394 395 # {% load %} tag (standard usage, without inheritance)396 'inheritance18': ("{% load testtags %}{% echo this that theother %}5678", {}, 'this that theother5678'),397 398 # {% load %} tag (within a child template)399 'inheritance19': ("{% extends 'inheritance01' %}{% block first %}{% load testtags %}{% echo 400 %}5678{% endblock %}", {}, '140056783_'),400 401 # Two-level inheritance with {{ block.super }}402 'inheritance20': ("{% extends 'inheritance01' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'),403 404 # Three-level inheritance with {{ block.super }} from parent405 'inheritance21': ("{% extends 'inheritance02' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '12a34'),406 407 # Three-level inheritance with {{ block.super }} from grandparent408 'inheritance22': ("{% extends 'inheritance04' %}{% block first %}{{ block.super }}a{% endblock %}", {}, '1_a3_'),409 410 # Three-level inheritance with {{ block.super }} from parent and grandparent411 'inheritance23': ("{% extends 'inheritance20' %}{% block first %}{{ block.super }}b{% endblock %}", {}, '1_ab3_'),412 413 # Inheritance from local context without use of template loader414 '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'),415 416 # Inheritance from local context with variable parent template417 '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'),418 419 ### I18N ##################################################################420 421 # {% spaceless %} tag422 'spaceless01': ("{% spaceless %} <b> <i> text </i> </b> {% endspaceless %}", {}, "<b> <i> text </i> </b>"),423 'spaceless02': ("{% spaceless %} <b> \n <i> text </i> \n </b> {% endspaceless %}", {}, "<b> <i> text </i> </b>"),424 'spaceless03': ("{% spaceless %}<b><i>text</i></b>{% endspaceless %}", {}, "<b><i>text</i></b>"),425 426 # simple translation of a string delimited by '427 'i18n01': ("{% load i18n %}{% trans 'xxxyyyxxx' %}", {}, "xxxyyyxxx"),428 429 # simple translation of a string delimited by "430 'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, "xxxyyyxxx"),431 432 # simple translation of a variable433 'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"),434 435 # simple translation of a variable and filter436 'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"),437 438 # simple translation of a string with interpolation439 'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"),440 441 # simple translation of a string to german442 'i18n06': ('{% load i18n %}{% trans "Page not found" %}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"),443 444 # translation of singular form445 'i18n07': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 1}, "singular"),446 447 # translation of plural form448 'i18n08': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 2}, "plural"),449 450 # simple non-translation (only marking) of a string to german451 'i18n09': ('{% load i18n %}{% trans "Page not found" noop %}', {'LANGUAGE_CODE': 'de'}, "Page not found"),452 453 # translation of a variable with a translated filter454 'i18n10': ('{{ bool|yesno:_("ja,nein") }}', {'bool': True}, 'ja'),455 456 # translation of a variable with a non-translated filter457 'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'),458 459 # usage of the get_available_languages tag460 'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'),461 462 # translation of a constant string463 'i18n13': ('{{ _("Page not found") }}', {'LANGUAGE_CODE': 'de'}, 'Seite nicht gefunden'),464 465 ### MULTILINE #############################################################466 467 'multiline01': ("""468 Hello,469 boys.470 How471 are472 you473 gentlemen.474 """,475 {},476 """477 Hello,478 boys.479 How480 are481 you482 gentlemen.483 """),484 485 ### REGROUP TAG ###########################################################486 'regroup01': ('{% regroup data by bar as grouped %}' + \487 '{% for group in grouped %}' + \488 '{{ group.grouper }}:' + \489 '{% for item in group.list %}' + \490 '{{ item.foo }}' + \491 '{% endfor %},' + \492 '{% endfor %}',493 {'data': [ {'foo':'c', 'bar':1},494 {'foo':'d', 'bar':1},495 {'foo':'a', 'bar':2},496 {'foo':'b', 'bar':2},497 {'foo':'x', 'bar':3} ]},498 '1:cd,2:ab,3:x,'),499 500 # Test for silent failure when target variable isn't found501 'regroup02': ('{% regroup data by bar as grouped %}' + \502 '{% for group in grouped %}' + \503 '{{ group.grouper }}:' + \504 '{% for item in group.list %}' + \505 '{{ item.foo }}' + \506 '{% endfor %},' + \507 '{% endfor %}',508 {}, 'INVALID:INVALIDINVALIDINVALIDINVALIDINVALIDINVALIDINVALID,'),509 510 ### TEMPLATETAG TAG #######################################################511 'templatetag01': ('{% templatetag openblock %}', {}, '{%'),512 'templatetag02': ('{% templatetag closeblock %}', {}, '%}'),513 'templatetag03': ('{% templatetag openvariable %}', {}, '{{'),514 'templatetag04': ('{% templatetag closevariable %}', {}, '}}'),515 'templatetag05': ('{% templatetag %}', {}, template.TemplateSyntaxError),516 'templatetag06': ('{% templatetag foo %}', {}, template.TemplateSyntaxError),517 'templatetag07': ('{% templatetag openbrace %}', {}, '{'),518 'templatetag08': ('{% templatetag closebrace %}', {}, '}'),519 'templatetag09': ('{% templatetag openbrace %}{% templatetag openbrace %}', {}, '{{'),520 'templatetag10': ('{% templatetag closebrace %}{% templatetag closebrace %}', {}, '}}'),521 522 ### WIDTHRATIO TAG ########################################################523 'widthratio01': ('{% widthratio a b 0 %}', {'a':50,'b':100}, '0'),524 'widthratio02': ('{% widthratio a b 100 %}', {'a':0,'b':0}, ''),525 'widthratio03': ('{% widthratio a b 100 %}', {'a':0,'b':100}, '0'),526 'widthratio04': ('{% widthratio a b 100 %}', {'a':50,'b':100}, '50'),527 'widthratio05': ('{% widthratio a b 100 %}', {'a':100,'b':100}, '100'),528 529 # 62.5 should round to 63530 'widthratio06': ('{% widthratio a b 100 %}', {'a':50,'b':80}, '63'),531 532 # 71.4 should round to 71533 'widthratio07': ('{% widthratio a b 100 %}', {'a':50,'b':70}, '71'),534 535 # Raise exception if we don't have 3 args, last one an integer536 'widthratio08': ('{% widthratio %}', {}, template.TemplateSyntaxError),537 'widthratio09': ('{% widthratio a b %}', {'a':50,'b':100}, template.TemplateSyntaxError),538 'widthratio10': ('{% widthratio a b 100.0 %}', {'a':50,'b':100}, template.TemplateSyntaxError),539 540 ### NOW TAG ########################################################541 # Simple case542 'now01' : ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)),543 544 # Check parsing of escaped and special characters545 'now02' : ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError),546 # 'now03' : ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)),547 # 'now04' : ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year))548 549 ### TIMESINCE TAG ##################################################550 # Default compare with datetime.now()551 'timesince01' : ('{{ a|timesince }}', {'a':datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1 minute'),552 'timesince02' : ('{{ a|timesince }}', {'a':(datetime.now() - timedelta(days=1, minutes = 1))}, '1 day'),553 'timesince03' : ('{{ a|timesince }}', {'a':(datetime.now() -554 timedelta(hours=1, minutes=25, seconds = 10))}, '1 hour, 25 minutes'),555 556 # Compare to a given parameter557 'timesince04' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2), 'b':NOW + timedelta(days=1)}, '1 day'),558 'timesince05' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2, minutes=1), 'b':NOW + timedelta(days=2)}, '1 minute'),559 560 # Check that timezone is respected561 'timesince06' : ('{{ a|timesince:b }}', {'a':NOW_tz + timedelta(hours=8), 'b':NOW_tz}, '8 hours'),562 563 ### TIMEUNTIL TAG ##################################################564 # Default compare with datetime.now()565 'timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'),566 'timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1 day'),567 'timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8 hours, 10 minutes'),568 569 # Compare to a given parameter570 'timeuntil04' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=1), 'b':NOW - timedelta(days=2)}, '1 day'),571 'timeuntil05' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=2), 'b':NOW - timedelta(days=2, minutes=1)}, '1 minute'),572 }573 574 def test_template_loader(template_name, template_dirs=None):575 "A custom template loader that loads the unit-test templates."576 try:577 return (TEMPLATE_TESTS[template_name][0] , "test:%s" % template_name)578 except KeyError:579 raise template.TemplateDoesNotExist, template_name580 581 def run_tests(verbosity=0, standalone=False):582 # Register our custom template loader.583 old_template_loaders = loader.template_source_loaders584 loader.template_source_loaders = [test_template_loader]585 586 failed_tests = []587 tests = TEMPLATE_TESTS.items()588 tests.sort()589 590 # Turn TEMPLATE_DEBUG off, because tests assume that.591 old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, False592 # Set TEMPLATE_STRING_IF_INVALID to a known string593 old_invalid, settings.TEMPLATE_STRING_IF_INVALID = settings.TEMPLATE_STRING_IF_INVALID, 'INVALID'594 595 for name, vals in tests:596 install()597 if 'LANGUAGE_CODE' in vals[1]:598 activate(vals[1]['LANGUAGE_CODE'])599 else:600 activate('en-us')601 try:602 output = loader.get_template(name).render(template.Context(vals[1]))603 except Exception, e:604 if e.__class__ == vals[2]:605 if verbosity:606 print "Template test: %s -- Passed" % name607 else:608 if verbosity:609 traceback.print_exc()610 print "Template test: %s -- FAILED. Got %s, exception: %s" % (name, e.__class__, e)611 failed_tests.append(name)612 continue613 if 'LANGUAGE_CODE' in vals[1]:614 deactivate()615 if output == vals[2]:616 if verbosity:617 print "Template test: %s -- Passed" % name618 else:619 if verbosity:620 print "Template test: %s -- FAILED. Expected %r, got %r" % (name, vals[2], output)621 failed_tests.append(name)622 loader.template_source_loaders = old_template_loaders623 deactivate()624 settings.TEMPLATE_DEBUG = old_td625 settings.TEMPLATE_STRING_IF_INVALID = old_invalid626 627 if failed_tests and not standalone:628 msg = "Template tests %s failed." % failed_tests629 if not verbosity:630 msg += " Re-run tests with -v1 to see actual failures"631 raise Exception, msg632 633 if __name__ == "__main__":634 run_tests(1, True) -
tests/othertests/urlpatterns_reverse.py
1 "Unit tests for reverse URL lookup"2 3 from django.core.urlresolvers import reverse_helper, NoReverseMatch4 import re5 6 test_data = (7 ('^places/(\d+)/$', 'places/3/', [3], {}),8 ('^places/(\d+)/$', 'places/3/', ['3'], {}),9 ('^places/(\d+)/$', NoReverseMatch, ['a'], {}),10 ('^places/(\d+)/$', NoReverseMatch, [], {}),11 ('^places/(?P<id>\d+)/$', 'places/3/', [], {'id': 3}),12 ('^people/(?P<name>\w+)/$', 'people/adrian/', ['adrian'], {}),13 ('^people/(?P<name>\w+)/$', 'people/adrian/', [], {'name': 'adrian'}),14 ('^people/(?P<name>\w+)/$', NoReverseMatch, ['name with spaces'], {}),15 ('^people/(?P<name>\w+)/$', NoReverseMatch, [], {'name': 'name with spaces'}),16 ('^people/(?P<name>\w+)/$', NoReverseMatch, [], {}),17 ('^hardcoded/$', 'hardcoded/', [], {}),18 ('^hardcoded/$', 'hardcoded/', ['any arg'], {}),19 ('^hardcoded/$', 'hardcoded/', [], {'kwarg': 'foo'}),20 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', 'people/il/adrian/', [], {'state': 'il', 'name': 'adrian'}),21 ('^people/(?P<state>\w\w)/(?P<name>\d)/$', NoReverseMatch, [], {'state': 'il', 'name': 'adrian'}),22 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', NoReverseMatch, [], {'state': 'il'}),23 ('^people/(?P<state>\w\w)/(?P<name>\w+)/$', NoReverseMatch, [], {'name': 'adrian'}),24 ('^people/(?P<state>\w\w)/(\w+)/$', NoReverseMatch, ['il'], {'name': 'adrian'}),25 ('^people/(?P<state>\w\w)/(\w+)/$', 'people/il/adrian/', ['adrian'], {'state': 'il'}),26 )27 28 def run_tests(verbosity=0):29 for regex, expected, args, kwargs in test_data:30 passed = True31 try:32 got = reverse_helper(re.compile(regex), *args, **kwargs)33 except NoReverseMatch, e:34 if expected != NoReverseMatch:35 passed, got = False, str(e)36 else:37 if got != expected:38 passed, got = False, got39 if passed and verbosity:40 print "Passed: %s" % regex41 elif not passed:42 print "REVERSE LOOKUP FAILED: %s" % regex43 print " Got: %s" % got44 print " Expected: %r" % expected45 46 if __name__ == "__main__":47 run_tests(1) -
tests/othertests/markup.py
1 # Quick tests for the markup templatetags (django.contrib.markup)2 3 from django.template import Template, Context, add_to_builtins4 import re5 6 add_to_builtins('django.contrib.markup.templatetags.markup')7 8 # find out if markup modules are installed and tailor the test appropriately9 try:10 import textile11 except ImportError:12 textile = None13 14 try:15 import markdown16 except ImportError:17 markdown = None18 19 try:20 import docutils21 except ImportError:22 docutils = None23 24 # simple examples 'cause this isn't actually testing the markup, just25 # that the filters work as advertised26 27 ### test textile28 29 textile_content = """Paragraph 130 31 Paragraph 2 with "quotes" and @code@"""32 33 t = Template("{{ textile_content|textile }}")34 rendered = t.render(Context(locals())).strip()35 if textile:36 assert rendered == """<p>Paragraph 1</p>37 38 <p>Paragraph 2 with “quotes” and <code>code</code></p>"""39 else:40 assert rendered == textile_content41 42 ### test markdown43 44 markdown_content = """Paragraph 145 46 ## An h2"""47 48 t = Template("{{ markdown_content|markdown }}")49 rendered = t.render(Context(locals())).strip()50 if markdown:51 pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")52 assert pattern.match(rendered)53 else:54 assert rendered == markdown_content55 56 ### test rest57 58 rest_content = """Paragraph 159 60 Paragraph 2 with a link_61 62 .. _link: http://www.example.com/"""63 64 t = Template("{{ rest_content|restructuredtext }}")65 rendered = t.render(Context(locals())).strip()66 if docutils:67 assert rendered =="""<p>Paragraph 1</p>68 <p>Paragraph 2 with a <a class="reference" href="http://www.example.com/">link</a></p>"""69 else:70 assert rendered == rest_content -
tests/othertests/cache.py
1 # Unit tests for cache framework2 # Uses whatever cache backend is set in the test settings file.3 4 from django.core.cache import cache5 import time6 7 # functions/classes for complex data type tests8 def f():9 return 4210 class C:11 def m(n):12 return 2413 14 # simple set/get15 cache.set("key", "value")16 assert cache.get("key") == "value"17 18 # get with non-existent keys19 assert cache.get("does not exist") is None20 assert cache.get("does not exist", "bang!") == "bang!"21 22 # get_many23 cache.set('a', 'a')24 cache.set('b', 'b')25 cache.set('c', 'c')26 cache.set('d', 'd')27 assert cache.get_many(['a', 'c', 'd']) == {'a' : 'a', 'c' : 'c', 'd' : 'd'}28 assert cache.get_many(['a', 'b', 'e']) == {'a' : 'a', 'b' : 'b'}29 30 # delete31 cache.set("key1", "spam")32 cache.set("key2", "eggs")33 assert cache.get("key1") == "spam"34 cache.delete("key1")35 assert cache.get("key1") is None36 assert cache.get("key2") == "eggs"37 38 # has_key39 cache.set("hello", "goodbye")40 assert cache.has_key("hello") == True41 assert cache.has_key("goodbye") == False42 43 # test data types44 stuff = {45 'string' : 'this is a string',46 'int' : 42,47 'list' : [1, 2, 3, 4],48 'tuple' : (1, 2, 3, 4),49 'dict' : {'A': 1, 'B' : 2},50 'function' : f,51 'class' : C,52 }53 for (key, value) in stuff.items():54 cache.set(key, value)55 assert cache.get(key) == value56 57 # expiration58 cache.set('expire', 'very quickly', 1)59 time.sleep(2)60 assert cache.get("expire") == None -
tests/othertests/httpwrappers.py
1 """2 ###################3 # Empty QueryDict #4 ###################5 6 >>> q = QueryDict('')7 8 >>> q['foo']9 Traceback (most recent call last):10 ...11 MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>"12 13 >>> q['something'] = 'bar'14 Traceback (most recent call last):15 ...16 AttributeError: This QueryDict instance is immutable17 18 >>> q.get('foo', 'default')19 'default'20 21 >>> q.getlist('foo')22 []23 24 >>> q.setlist('foo', ['bar', 'baz'])25 Traceback (most recent call last):26 ...27 AttributeError: This QueryDict instance is immutable28 29 >>> q.appendlist('foo', ['bar'])30 Traceback (most recent call last):31 ...32 AttributeError: This QueryDict instance is immutable33 34 >>> q.has_key('foo')35 False36 37 >>> q.items()38 []39 40 >>> q.lists()41 []42 43 >>> q.keys()44 []45 46 >>> q.values()47 []48 49 >>> len(q)50 051 52 >>> q.update({'foo': 'bar'})53 Traceback (most recent call last):54 ...55 AttributeError: This QueryDict instance is immutable56 57 >>> q.pop('foo')58 Traceback (most recent call last):59 ...60 AttributeError: This QueryDict instance is immutable61 62 >>> q.popitem()63 Traceback (most recent call last):64 ...65 AttributeError: This QueryDict instance is immutable66 67 >>> q.clear()68 Traceback (most recent call last):69 ...70 AttributeError: This QueryDict instance is immutable71 72 >>> q.setdefault('foo', 'bar')73 Traceback (most recent call last):74 ...75 AttributeError: This QueryDict instance is immutable76 77 >>> q.urlencode()78 ''79 80 ###################################81 # Mutable copy of empty QueryDict #82 ###################################83 84 >>> q = q.copy()85 86 >>> q['foo']87 Traceback (most recent call last):88 ...89 MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>"90 91 >>> q['name'] = 'john'92 93 >>> q['name']94 'john'95 96 >>> q.get('foo', 'default')97 'default'98 99 >>> q.get('name', 'default')100 'john'101 102 >>> q.getlist('name')103 ['john']104 105 >>> q.getlist('foo')106 []107 108 >>> q.setlist('foo', ['bar', 'baz'])109 110 >>> q.get('foo', 'default')111 'baz'112 113 >>> q.getlist('foo')114 ['bar', 'baz']115 116 >>> q.appendlist('foo', 'another')117 118 >>> q.getlist('foo')119 ['bar', 'baz', 'another']120 121 >>> q['foo']122 'another'123 124 >>> q.has_key('foo')125 True126 127 >>> q.items()128 [('foo', 'another'), ('name', 'john')]129 130 >>> q.lists()131 [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]132 133 >>> q.keys()134 ['foo', 'name']135 136 >>> q.values()137 ['another', 'john']138 139 >>> len(q)140 2141 142 >>> q.update({'foo': 'hello'})143 144 # Displays last value145 >>> q['foo']146 'hello'147 148 >>> q.get('foo', 'not available')149 'hello'150 151 >>> q.getlist('foo')152 ['bar', 'baz', 'another', 'hello']153 154 >>> q.pop('foo')155 ['bar', 'baz', 'another', 'hello']156 157 >>> q.get('foo', 'not there')158 'not there'159 160 >>> q.setdefault('foo', 'bar')161 'bar'162 163 >>> q['foo']164 'bar'165 166 >>> q.getlist('foo')167 ['bar']168 169 >>> q.urlencode()170 'foo=bar&name=john'171 172 >>> q.clear()173 174 >>> len(q)175 0176 177 #####################################178 # QueryDict with one key/value pair #179 #####################################180 181 >>> q = QueryDict('foo=bar')182 183 >>> q['foo']184 'bar'185 186 >>> q['bar']187 Traceback (most recent call last):188 ...189 MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {'foo': ['bar']}>"190 191 >>> q['something'] = 'bar'192 Traceback (most recent call last):193 ...194 AttributeError: This QueryDict instance is immutable195 196 >>> q.get('foo', 'default')197 'bar'198 199 >>> q.get('bar', 'default')200 'default'201 202 >>> q.getlist('foo')203 ['bar']204 205 >>> q.getlist('bar')206 []207 208 >>> q.setlist('foo', ['bar', 'baz'])209 Traceback (most recent call last):210 ...211 AttributeError: This QueryDict instance is immutable212 213 >>> q.appendlist('foo', ['bar'])214 Traceback (most recent call last):215 ...216 AttributeError: This QueryDict instance is immutable217 218 >>> q.has_key('foo')219 True220 221 >>> q.has_key('bar')222 False223 224 >>> q.items()225 [('foo', 'bar')]226 227 >>> q.lists()228 [('foo', ['bar'])]229 230 >>> q.keys()231 ['foo']232 233 >>> q.values()234 ['bar']235 236 >>> len(q)237 1238 239 >>> q.update({'foo': 'bar'})240 Traceback (most recent call last):241 ...242 AttributeError: This QueryDict instance is immutable243 244 >>> q.pop('foo')245 Traceback (most recent call last):246 ...247 AttributeError: This QueryDict instance is immutable248 249 >>> q.popitem()250 Traceback (most recent call last):251 ...252 AttributeError: This QueryDict instance is immutable253 254 >>> q.clear()255 Traceback (most recent call last):256 ...257 AttributeError: This QueryDict instance is immutable258 259 >>> q.setdefault('foo', 'bar')260 Traceback (most recent call last):261 ...262 AttributeError: This QueryDict instance is immutable263 264 >>> q.urlencode()265 'foo=bar'266 267 #####################################################268 # QueryDict with two key/value pairs with same keys #269 #####################################################270 271 >>> q = QueryDict('vote=yes&vote=no')272 273 >>> q['vote']274 'no'275 276 >>> q['something'] = 'bar'277 Traceback (most recent call last):278 ...279 AttributeError: This QueryDict instance is immutable280 281 >>> q.get('vote', 'default')282 'no'283 284 >>> q.get('foo', 'default')285 'default'286 287 >>> q.getlist('vote')288 ['yes', 'no']289 290 >>> q.getlist('foo')291 []292 293 >>> q.setlist('foo', ['bar', 'baz'])294 Traceback (most recent call last):295 ...296 AttributeError: This QueryDict instance is immutable297 298 >>> q.appendlist('foo', ['bar'])299 Traceback (most recent call last):300 ...301 AttributeError: This QueryDict instance is immutable302 303 >>> q.has_key('vote')304 True305 306 >>> q.has_key('foo')307 False308 309 >>> q.items()310 [('vote', 'no')]311 312 >>> q.lists()313 [('vote', ['yes', 'no'])]314 315 >>> q.keys()316 ['vote']317 318 >>> q.values()319 ['no']320 321 >>> len(q)322 1323 324 >>> q.update({'foo': 'bar'})325 Traceback (most recent call last):326 ...327 AttributeError: This QueryDict instance is immutable328 329 >>> q.pop('foo')330 Traceback (most recent call last):331 ...332 AttributeError: This QueryDict instance is immutable333 334 >>> q.popitem()335 Traceback (most recent call last):336 ...337 AttributeError: This QueryDict instance is immutable338 339 >>> q.clear()340 Traceback (most recent call last):341 ...342 AttributeError: This QueryDict instance is immutable343 344 >>> q.setdefault('foo', 'bar')345 Traceback (most recent call last):346 ...347 AttributeError: This QueryDict instance is immutable348 349 >>> q.urlencode()350 'vote=yes&vote=no'351 352 """353 354 from django.http import QueryDict355 356 if __name__ == "__main__":357 import doctest358 doctest.testmod() -
tests/othertests/db_typecasts.py
1 # Unit tests for typecast functions in django.db.backends.util2 3 from django.db.backends import util as typecasts4 import datetime5 6 TEST_CASES = {7 'typecast_date': (8 ('', None),9 (None, None),10 ('2005-08-11', datetime.date(2005, 8, 11)),11 ('1990-01-01', datetime.date(1990, 1, 1)),12 ),13 'typecast_time': (14 ('', None),15 (None, None),16 ('0:00:00', datetime.time(0, 0)),17 ('0:30:00', datetime.time(0, 30)),18 ('8:50:00', datetime.time(8, 50)),19 ('08:50:00', datetime.time(8, 50)),20 ('12:00:00', datetime.time(12, 00)),21 ('12:30:00', datetime.time(12, 30)),22 ('13:00:00', datetime.time(13, 00)),23 ('23:59:00', datetime.time(23, 59)),24 ('00:00:12', datetime.time(0, 0, 12)),25 ('00:00:12.5', datetime.time(0, 0, 12, 500000)),26 ('7:22:13.312', datetime.time(7, 22, 13, 312000)),27 ),28 'typecast_timestamp': (29 ('', None),30 (None, None),31 ('2005-08-11 0:00:00', datetime.datetime(2005, 8, 11)),32 ('2005-08-11 0:30:00', datetime.datetime(2005, 8, 11, 0, 30)),33 ('2005-08-11 8:50:30', datetime.datetime(2005, 8, 11, 8, 50, 30)),34 ('2005-08-11 8:50:30.123', datetime.datetime(2005, 8, 11, 8, 50, 30, 123000)),35 ('2005-08-11 8:50:30.9', datetime.datetime(2005, 8, 11, 8, 50, 30, 900000)),36 ('2005-08-11 8:50:30.312-05', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)),37 ('2005-08-11 8:50:30.312+02', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)),38 ),39 'typecast_boolean': (40 (None, None),41 ('', False),42 ('t', True),43 ('f', False),44 ('x', False),45 ),46 }47 48 for k, v in TEST_CASES.items():49 for inpt, expected in v:50 got = getattr(typecasts, k)(inpt)51 assert got == expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got) -
tests/othertests/dateformat.py
1 r"""2 >>> format(my_birthday, '')3 ''4 >>> format(my_birthday, 'a')5 'p.m.'6 >>> format(my_birthday, 'A')7 'PM'8 >>> format(my_birthday, 'd')9 '08'10 >>> format(my_birthday, 'j')11 '8'12 >>> format(my_birthday, 'l')13 'Sunday'14 >>> format(my_birthday, 'L')15 'False'16 >>> format(my_birthday, 'm')17 '07'18 >>> format(my_birthday, 'M')19 'Jul'20 >>> format(my_birthday, 'n')21 '7'22 >>> format(my_birthday, 'N')23 'July'24 >>> format(my_birthday, 'O')25 '+0100'26 >>> format(my_birthday, 'P')27 '10 p.m.'28 >>> format(my_birthday, 'r')29 'Sun, 8 Jul 1979 22:00:00 +0100'30 >>> format(my_birthday, 's')31 '00'32 >>> format(my_birthday, 'S')33 'th'34 >>> format(my_birthday, 't')35 '31'36 >>> format(my_birthday, 'T')37 'CET'38 >>> format(my_birthday, 'U')39 '300531600'40 >>> format(my_birthday, 'w')41 '0'42 >>> format(my_birthday, 'W')43 '27'44 >>> format(my_birthday, 'y')45 '79'46 >>> format(my_birthday, 'Y')47 '1979'48 >>> format(my_birthday, 'z')49 '189'50 >>> format(my_birthday, 'Z')51 '3600'52 53 >>> format(summertime, 'I')54 '1'55 >>> format(summertime, 'O')56 '+0200'57 >>> format(wintertime, 'I')58 '0'59 >>> format(wintertime, 'O')60 '+0100'61 62 >>> format(my_birthday, r'Y z \C\E\T')63 '1979 189 CET'64 65 >>> format(my_birthday, r'jS o\f F')66 '8th of July'67 """68 69 from django.utils import dateformat, translation70 import datetime, os, time71 72 format = dateformat.format73 os.environ['TZ'] = 'Europe/Copenhagen'74 translation.activate('en-us')75 76 time.tzset()77 78 my_birthday = datetime.datetime(1979, 7, 8, 22, 00)79 summertime = datetime.datetime(2005, 10, 30, 1, 00)80 wintertime = datetime.datetime(2005, 10, 30, 4, 00) -
tests/runtests.py
1 1 #!/usr/bin/env python 2 2 3 import os, re, sys, time, traceback 3 import os, sys, traceback 4 import unittest 4 5 5 # doctest is included in the same package as this module, because this testing6 # framework uses features only available in the Python 2.4 version of doctest,7 # and Django aims to work with Python 2.3+.8 import doctest9 10 6 MODEL_TESTS_DIR_NAME = 'modeltests' 11 OTHER_TESTS_DIR = "othertests"12 7 REGRESSION_TESTS_DIR_NAME = 'regressiontests' 13 TEST_DATABASE_NAME = 'django_test_db'14 8 15 error_list = []16 def log_error(model_name, title, description):17 error_list.append({18 'title': "%r module: %s" % (model_name, title),19 'description': description,20 })21 22 9 MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME) 23 10 REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME) 24 11 … … 37 24 models = [] 38 25 for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR): 39 26 for f in os.listdir(dirpath): 40 if f.startswith('__init__') or f.startswith('.') or f.startswith('sql') :27 if f.startswith('__init__') or f.startswith('.') or f.startswith('sql') or f.startswith('invalid'): 41 28 continue 42 29 models.append((loc, f)) 43 30 return models 44 31 45 class DjangoDoctestRunner(doctest.DocTestRunner): 46 def __init__(self, verbosity_level, *args, **kwargs): 47 self.verbosity_level = verbosity_level 48 doctest.DocTestRunner.__init__(self, *args, **kwargs) 49 self._checker = DjangoDoctestOutputChecker() 50 self.optionflags = doctest.ELLIPSIS 51 52 def report_start(self, out, test, example): 53 if self.verbosity_level > 1: 54 out(" >>> %s\n" % example.source.strip()) 55 56 def report_failure(self, out, test, example, got): 57 log_error(test.name, "API test failed", 58 "Code: %r\nLine: %s\nExpected: %r\nGot: %r" % (example.source.strip(), example.lineno, example.want, got)) 59 60 def report_unexpected_exception(self, out, test, example, exc_info): 61 from django.db import transaction 62 tb = ''.join(traceback.format_exception(*exc_info)[1:]) 63 log_error(test.name, "API test raised an exception", 64 "Code: %r\nLine: %s\nException: %s" % (example.source.strip(), example.lineno, tb)) 65 # Rollback, in case of database errors. Otherwise they'd have 66 # side effects on other tests. 67 transaction.rollback_unless_managed() 68 69 normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) 70 71 class DjangoDoctestOutputChecker(doctest.OutputChecker): 72 def check_output(self, want, got, optionflags): 73 ok = doctest.OutputChecker.check_output(self, want, got, optionflags) 74 75 # Doctest does an exact string comparison of output, which means long 76 # integers aren't equal to normal integers ("22L" vs. "22"). The 77 # following code normalizes long integers so that they equal normal 78 # integers. 79 if not ok: 80 return normalize_long_ints(want) == normalize_long_ints(got) 81 return ok 82 83 class TestRunner: 84 def __init__(self, verbosity_level=0, which_tests=None): 85 self.verbosity_level = verbosity_level 86 self.which_tests = which_tests 87 88 def output(self, required_level, message): 89 if self.verbosity_level > required_level - 1: 90 print message 91 92 def run_tests(self): 93 from django.conf import settings 94 95 # An empty access of the settings to force the default options to be 96 # installed prior to assigning to them. 97 settings.INSTALLED_APPS 98 99 # Manually set INSTALLED_APPS to point to the test models. 100 settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS + ['.'.join(a) for a in get_test_models()] 101 102 # Manually set DEBUG and USE_I18N. 103 settings.DEBUG = False 104 settings.USE_I18N = True 105 106 from django.db import connection 32 def get_invalid_models(): 33 models = [] 34 for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR): 35 for f in os.listdir(dirpath): 36 if f.startswith('__init__') or f.startswith('.') or f.startswith('sql'): 37 continue 38 if f.startswith('invalid'): 39 models.append((loc, f)) 40 return models 41 42 class InvalidModelTestCase(unittest.TestCase): 43 def __init__(self, model_label): 44 unittest.TestCase.__init__(self) 45 self.model_label = model_label 46 47 def runTest(self): 107 48 from django.core import management 108 import django.db.models109 110 # Determine which models we're going to test.111 test_models = get_test_models()112 if 'othertests' in self.which_tests:113 self.which_tests.remove('othertests')114 run_othertests = True115 if not self.which_tests:116 test_models = []117 else:118 run_othertests = not self.which_tests119 120 if self.which_tests:121 # Only run the specified tests.122 bad_models = [m for m in self.which_tests if (MODEL_TESTS_DIR_NAME, m) not in test_models and (REGRESSION_TESTS_DIR_NAME, m) not in test_models]123 if bad_models:124 sys.stderr.write("Models not found: %s\n" % bad_models)125 sys.exit(1)126 else:127 all_tests = []128 for test in self.which_tests:129 for loc in MODEL_TESTS_DIR_NAME, REGRESSION_TESTS_DIR_NAME:130 if (loc, test) in test_models:131 all_tests.append((loc, test))132 test_models = all_tests133 134 self.output(0, "Running tests with database %r" % settings.DATABASE_ENGINE)135 136 # If we're using SQLite, it's more convenient to test against an137 # in-memory database.138 if settings.DATABASE_ENGINE == "sqlite3":139 global TEST_DATABASE_NAME140 TEST_DATABASE_NAME = ":memory:"141 else:142 # Create the test database and connect to it. We need to autocommit143 # if the database supports it because PostgreSQL doesn't allow144 # CREATE/DROP DATABASE statements within transactions.145 cursor = connection.cursor()146 self._set_autocommit(connection)147 self.output(1, "Creating test database")148 try:149 cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)150 except Exception, e:151 sys.stderr.write("Got an error creating the test database: %s\n" % e)152 confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_DATABASE_NAME)153 if confirm == 'yes':154 cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)155 cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)156 else:157 print "Tests cancelled."158 return159 connection.close()160 old_database_name = settings.DATABASE_NAME161 settings.DATABASE_NAME = TEST_DATABASE_NAME162 163 # Initialize the test database.164 cursor = connection.cursor()165 166 49 from django.db.models.loading import load_app 167 # Install the core always installed apps 168 for app in ALWAYS_INSTALLED_APPS: 169 self.output(1, "Installing contrib app %s" % app) 170 mod = load_app(app) 171 management.install(mod) 50 from cStringIO import StringIO 172 51 173 # Run the tests for each test model. 174 self.output(1, "Running app tests") 175 for model_dir, model_name in test_models: 176 self.output(1, "%s model: Importing" % model_name) 177 try: 178 mod = load_app(model_dir + '.' + model_name) 179 except Exception, e: 180 log_error(model_name, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 181 continue 52 try: 53 module = load_app(self.model_label) 54 except Exception, e: 55 self.fail('Unable to load invalid model module') 56 57 s = StringIO() 58 count = management.get_validation_errors(s, module) 59 s.seek(0) 60 error_log = s.read() 61 actual = error_log.split('\n') 62 expected = module.model_errors.split('\n') 182 63 183 if not getattr(mod, 'error_log', None): 184 # Model is not marked as an invalid model 185 self.output(1, "%s.%s model: Installing" % (model_dir, model_name)) 186 management.install(mod) 64 unexpected = [err for err in actual if err not in expected] 65 missing = [err for err in expected if err not in actual] 187 66 188 # Run the API tests. 189 p = doctest.DocTestParser() 190 test_namespace = dict([(m._meta.object_name, m) \ 191 for m in django.db.models.get_models(mod)]) 192 dtest = p.get_doctest(mod.API_TESTS, test_namespace, model_name, None, None) 193 # Manually set verbose=False, because "-v" command-line parameter 194 # has side effects on doctest TestRunner class. 195 runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False) 196 self.output(1, "%s.%s model: Running tests" % (model_dir, model_name)) 197 runner.run(dtest, clear_globs=True, out=sys.stdout.write) 198 else: 199 # Check that model known to be invalid is invalid for the right reasons. 200 self.output(1, "%s.%s model: Validating" % (model_dir, model_name)) 67 self.assert_(not unexpected, "Unexpected Errors: " + '\n'.join(unexpected)) 68 self.assert_(not missing, "Missing Errors: " + '\n'.join(missing)) 201 69 202 from cStringIO import StringIO 203 s = StringIO() 204 count = management.get_validation_errors(s, mod) 205 s.seek(0) 206 error_log = s.read() 207 actual = error_log.split('\n') 208 expected = mod.error_log.split('\n') 70 def django_tests(verbosity, tests_to_run): 71 from django.conf import settings 72 from django.db.models.loading import get_apps, load_app 73 old_installed_apps = settings.INSTALLED_APPS 74 75 # load all the ALWAYS_INSTALLED_APPS 76 settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS 77 get_apps() 78 79 test_models = [] 80 # Load all the test model apps 81 for model_dir, model_name in get_test_models(): 82 model_label = '.'.join([model_dir, model_name]) 83 try: 84 # if the model was named on the command line, or 85 # no models were named (i.e., run all), import 86 # this model and add it to the list to test. 87 if not tests_to_run or model_name in tests_to_run: 88 if verbosity >= 1: 89 print "Importing model %s" % model_name 90 mod = load_app(model_label) 91 settings.INSTALLED_APPS.append(model_label) 92 test_models.append(mod) 93 except Exception, e: 94 sys.stderr.write("Error while importing %s:" % model_name + ''.join(traceback.format_exception(*sys.exc_info())[1:])) 95 continue 209 96 210 unexpected = [err for err in actual if err not in expected] 211 missing = [err for err in expected if err not in actual] 212 213 if unexpected or missing: 214 unexpected_log = '\n'.join(unexpected) 215 missing_log = '\n'.join(missing) 216 log_error(model_name, 217 "Validator found %d validation errors, %d expected" % (count, len(expected) - 1), 218 "Missing errors:\n%s\n\nUnexpected errors:\n%s" % (missing_log, unexpected_log)) 219 220 if run_othertests: 221 # Run the non-model tests in the other tests dir 222 self.output(1, "Running other tests") 223 other_tests_dir = os.path.join(os.path.dirname(__file__), OTHER_TESTS_DIR) 224 test_modules = [f[:-3] for f in os.listdir(other_tests_dir) if f.endswith('.py') and not f.startswith('__init__')] 225 for module in test_modules: 226 self.output(1, "%s module: Importing" % module) 227 try: 228 mod = __import__("othertests." + module, '', '', ['']) 229 except Exception, e: 230 log_error(module, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 231 continue 232 if mod.__doc__: 233 p = doctest.DocTestParser() 234 dtest = p.get_doctest(mod.__doc__, mod.__dict__, module, None, None) 235 runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False) 236 self.output(1, "%s module: running tests" % module) 237 runner.run(dtest, clear_globs=True, out=sys.stdout.write) 238 if hasattr(mod, "run_tests") and callable(mod.run_tests): 239 self.output(1, "%s module: running tests" % module) 240 try: 241 mod.run_tests(verbosity_level) 242 except Exception, e: 243 log_error(module, "Exception running tests", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 244 continue 245 246 # Unless we're using SQLite, remove the test database to clean up after 247 # ourselves. Connect to the previous database (not the test database) 248 # to do so, because it's not allowed to delete a database while being 249 # connected to it. 250 if settings.DATABASE_ENGINE != "sqlite3": 251 connection.close() 252 settings.DATABASE_NAME = old_database_name 253 cursor = connection.cursor() 254 self.output(1, "Deleting test database") 255 self._set_autocommit(connection) 256 time.sleep(1) # To avoid "database is being accessed by other users" errors. 257 cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME) 258 259 # Display output. 260 if error_list: 261 for d in error_list: 262 print 263 print d['title'] 264 print "=" * len(d['title']) 265 print d['description'] 266 print "%s error%s:" % (len(error_list), len(error_list) != 1 and 's' or '') 267 else: 268 print "All tests passed." 269 270 def _set_autocommit(self, connection): 271 """ 272 Make sure a connection is in autocommit mode. 273 """ 274 if hasattr(connection.connection, "autocommit"): 275 connection.connection.autocommit(True) 276 elif hasattr(connection.connection, "set_isolation_level"): 277 connection.connection.set_isolation_level(0) 278 97 # Add tests for invalid models 98 extra_tests = [] 99 for model_dir, model_name in get_invalid_models(): 100 model_label = '.'.join([model_dir, model_name]) 101 if not tests_to_run or model_name in tests_to_run: 102 extra_tests.append(InvalidModelTestCase(model_label)) 103 104 # Run the test suite, including the extra validation tests. 105 from django.test.simple import run_tests 106 run_tests(test_models, verbosity, extra_tests=extra_tests) 107 108 # Restore the old INSTALLED_APPS setting 109 settings.INSTALLED_APPS = old_installed_apps 110 279 111 if __name__ == "__main__": 280 112 from optparse import OptionParser 281 113 usage = "%prog [options] [model model model ...]" 282 114 parser = OptionParser(usage=usage) 283 parser.add_option('-v', help='How verbose should the output be? Choices are 0, 1 and 2, where 2 is most verbose. Default is 0.', 284 type='choice', choices=['0', '1', '2']) 115 parser.add_option('-v','--verbosity', action='store', dest='verbosity', default='0', 116 type='choice', choices=['0', '1', '2'], 117 help='Verbosity level; 0=minimal output, 1=normal output, 2=all output') 285 118 parser.add_option('--settings', 286 119 help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') 287 120 options, args = parser.parse_args() 288 verbosity_level = 0289 if options.v:290 verbosity_level = int(options.v)291 121 if options.settings: 292 122 os.environ['DJANGO_SETTINGS_MODULE'] = options.settings 293 t = TestRunner(verbosity_level, args)294 t.run_tests()123 124 django_tests(int(options.verbosity), args)