Added get_path tests back in. Special-cased get_path if root and self are equal to...
[philo.git] / tests.py
1 from django.test import TestCase
2 from django import template
3 from django.conf import settings
4 from django.db import connection
5 from philo.exceptions import AncestorDoesNotExist
6 from philo.models import Node, Page, Template
7 from philo.contrib.penfield.models import Blog, BlogView, BlogEntry
8
9
10 class NodeURLTestCase(TestCase):
11         """Tests the features of the node_url template tag."""
12         urls = 'philo.urls'
13         fixtures = ['test_fixtures.json']
14         
15         def setUp(self):
16                 if 'south' in settings.INSTALLED_APPS:
17                         from south.management.commands.migrate import Command
18                         command = Command()
19                         command.handle(all_apps=True)
20                 
21                 self.templates = [
22                                 ("{% node_url %}", "/root/second/"),
23                                 ("{% node_url for node2 %}", "/root/second2/"),
24                                 ("{% node_url as hello %}<p>{{ hello|slice:'1:' }}</p>", "<p>root/second/</p>"),
25                                 ("{% node_url for nodes|first %}", "/root/"),
26                                 ("{% node_url with entry %}", settings.TEMPLATE_STRING_IF_INVALID),
27                                 ("{% node_url with entry for node2 %}", "/root/second2/2010/10/20/first-entry"),
28                                 ("{% node_url with tag for node2 %}", "/root/second2/tags/test-tag/"),
29                                 ("{% node_url with date for node2 %}", "/root/second2/2010/10/20"),
30                                 ("{% node_url entries_by_day year=date|date:'Y' month=date|date:'m' day=date|date:'d' for node2 as goodbye %}<em>{{ goodbye|upper }}</em>", "<em>/ROOT/SECOND2/2010/10/20</em>"),
31                                 ("{% node_url entries_by_month year=date|date:'Y' month=date|date:'m' for node2 %}", "/root/second2/2010/10"),
32                                 ("{% node_url entries_by_year year=date|date:'Y' for node2 %}", "/root/second2/2010/"),
33                 ]
34                 
35                 nodes = Node.objects.all()
36                 blog = Blog.objects.all()[0]
37                 
38                 self.context = template.Context({
39                         'node': nodes.get(slug='second'),
40                         'node2': nodes.get(slug='second2'),
41                         'nodes': nodes,
42                         'entry': BlogEntry.objects.all()[0],
43                         'tag': blog.entry_tags.all()[0],
44                         'date': blog.entry_dates['day'][0]
45                 })
46         
47         def test_nodeurl(self):
48                 for string, result in self.templates:
49                         self.assertEqual(template.Template(string).render(self.context), result)
50
51 class TreePathTestCase(TestCase):
52         urls = 'philo.urls'
53         fixtures = ['test_fixtures.json']
54         
55         def setUp(self):
56                 if 'south' in settings.INSTALLED_APPS:
57                         from south.management.commands.migrate import Command
58                         command = Command()
59                         command.handle(all_apps=True)
60         
61         def assertQueryLimit(self, max, expected_result, *args, **kwargs):
62                 # As a rough measure of efficiency, limit the number of queries required for a given operation.
63                 settings.DEBUG = True
64                 call = kwargs.pop('callable', Node.objects.get_with_path)
65                 try:
66                         queries = len(connection.queries)
67                         if isinstance(expected_result, type) and issubclass(expected_result, Exception):
68                                 self.assertRaises(expected_result, call, *args, **kwargs)
69                         else:
70                                 self.assertEqual(call(*args, **kwargs), expected_result)
71                         queries = len(connection.queries) - queries
72                         if queries > max:
73                                 raise AssertionError('"%d" unexpectedly not less than or equal to "%s"' % (queries, max))
74                 finally:
75                         settings.DEBUG = False
76         
77         def test_get_with_path(self):
78                 root = Node.objects.get(slug='root')
79                 third = Node.objects.get(slug='third')
80                 second2 = Node.objects.get(slug='second2')
81                 fifth = Node.objects.get(slug='fifth')
82                 e = Node.DoesNotExist
83                 
84                 # Empty segments
85                 self.assertQueryLimit(0, root, '', root=root)
86                 self.assertQueryLimit(0, e, '')
87                 self.assertQueryLimit(0, (root, None), '', root=root, absolute_result=False)
88                 
89                 # Absolute result
90                 self.assertQueryLimit(1, third, 'root/second/third')
91                 self.assertQueryLimit(1, third, 'second/third', root=root)
92                 self.assertQueryLimit(1, third, 'root//////second/third///')
93                 
94                 self.assertQueryLimit(1, e, 'root/secont/third')
95                 self.assertQueryLimit(1, e, 'second/third')
96                 
97                 # Non-absolute result (binary search)
98                 self.assertQueryLimit(2, (second2, 'sub/path/tail'), 'root/second2/sub/path/tail', absolute_result=False)
99                 self.assertQueryLimit(3, (second2, 'sub/'), 'root/second2/sub/', absolute_result=False)
100                 self.assertQueryLimit(2, e, 'invalid/path/1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/7/8/9/0', absolute_result=False)
101                 self.assertQueryLimit(1, (root, None), 'root', absolute_result=False)
102                 self.assertQueryLimit(2, (second2, None), 'root/second2', absolute_result=False)
103                 self.assertQueryLimit(3, (third, None), 'root/second/third', absolute_result=False)
104                 
105                 # with root != None
106                 self.assertQueryLimit(1, (second2, None), 'second2', root=root, absolute_result=False)
107                 self.assertQueryLimit(2, (third, None), 'second/third', root=root, absolute_result=False)
108                 
109                 # Preserve trailing slash
110                 self.assertQueryLimit(2, (second2, 'sub/path/tail/'), 'root/second2/sub/path/tail/', absolute_result=False)
111                 
112                 # Speed increase for leaf nodes - should this be tested?
113                 self.assertQueryLimit(1, (fifth, 'sub/path/tail/len/five'), 'root/second/third/fourth/fifth/sub/path/tail/len/five', absolute_result=False)
114         
115         def test_get_path(self):
116                 root = Node.objects.get(slug='root')
117                 root2 = Node.objects.get(slug='root')
118                 third = Node.objects.get(slug='third')
119                 second2 = Node.objects.get(slug='second2')
120                 fifth = Node.objects.get(slug='fifth')
121                 e = AncestorDoesNotExist
122                 
123                 self.assertQueryLimit(0, 'root', callable=root.get_path)
124                 self.assertQueryLimit(0, '', root2, callable=root.get_path)
125                 self.assertQueryLimit(1, 'root/second/third', callable=third.get_path)
126                 self.assertQueryLimit(1, 'second/third', root, callable=third.get_path)
127                 self.assertQueryLimit(1, e, third, callable=second2.get_path)
128                 self.assertQueryLimit(1, '? - ?', root, ' - ', 'title', callable=third.get_path)