1 # Copyright (c) 2008, Eric Florenzano
2 # Copyright (c) 2010, 2011 Linaro Limited
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following
13 # disclaimer in the documentation and/or other materials provided
14 # with the distribution.
15 # * Neither the name of the author nor the names of other
16 # contributors may be used to endorse or promote products derived
17 # from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 from django.core.paginator import Paginator
32 from django.http import HttpRequest as DjangoHttpRequest
33 from django.template import Template, Context
36 from django.test import SimpleTestCase
37 except ImportError: # Django 1.2 compatible
38 from django.test import TestCase as SimpleTestCase
40 from linaro_django_pagination.paginator import InfinitePaginator, FinitePaginator
41 from linaro_django_pagination.templatetags.pagination_tags import paginate
42 from linaro_django_pagination.middleware import PaginationMiddleware
45 class HttpRequest(DjangoHttpRequest):
46 page = lambda self, suffix: 1
49 class CommonTestCase(SimpleTestCase):
50 def test_records_for_the_first_page(self):
51 p = Paginator(range(15), 2)
52 pg = paginate({'paginator': p, 'page_obj': p.page(1)})
53 self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
54 self.assertEqual(pg['records']['first'], 1)
55 self.assertEqual(pg['records']['last'], 2)
57 def test_records_for_the_last_page(self):
58 p = Paginator(range(15), 2)
59 pg = paginate({'paginator': p, 'page_obj': p.page(8)})
60 self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
61 self.assertEqual(pg['records']['first'], 15)
62 self.assertEqual(pg['records']['last'], 15)
64 def test_pages_list(self):
65 p = Paginator(range(17), 2)
66 self.assertEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1, 2, 3, 4, 5, 6, 7, 8, 9])
68 def test_page_with_empty_objects_list(self):
69 p = Paginator(range(0), 2)
70 self.assertListEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1])
73 class DefaultWindowTestCase(SimpleTestCase):
75 Test paginate using default window setting
76 moving the window from 1 ... to end
77 window size = 2, margin = 2
78 window = 2 -> show 5 pages
81 self.p = Paginator(range(31), 2)
83 def test_on_start_page_1(self):
84 # [1] 2 3 4 5 ... 15, 16
86 paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 2)['pages'],
87 [1, 2, 3, 4, 5, None, 15, 16]
90 def test_on_start_page_2(self):
91 # 1 [2] 3 4 5 ... 15, 16
93 paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 2)['pages'],
94 [1, 2, 3, 4, 5, None, 15, 16]
97 def test_on_start_page_3(self):
98 # 1 2 [3] 4 5 ... 15, 16
100 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 2)['pages'],
101 [1, 2, 3, 4, 5, None, 15, 16]
104 def test_on_start_page_4(self):
105 # 1 2 3 [4] 5 6 ... 15, 16
106 self.assertListEqual(
107 paginate({'paginator': self.p, 'page_obj': self.p.page(4)}, 2, 2)['pages'],
108 [1, 2, 3, 4, 5, 6, None, 15, 16])
110 def test_on_start_page_5(self):
111 # 1 2 3 4 [5] 6 7 ... 15, 16
112 self.assertListEqual(
113 paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 2)['pages'],
114 [1, 2, 3, 4, 5, 6, 7, None, 15, 16]
117 def test_in_middle(self):
118 # 1 2 ... 5 6 [7] 8 9 ... 15, 16
119 self.assertListEqual(
120 paginate({'paginator': self.p, 'page_obj': self.p.page(7)}, 2, 2)['pages'],
121 [1, 2, None, 5, 6, 7, 8, 9, None, 15, 16]
124 def test_on_end_page_13(self):
125 # 1 2 ... 12 [13] 14 15 16
126 self.assertListEqual(
127 paginate({'paginator': self.p, 'page_obj': self.p.page(13)}, 2, 2)['pages'],
128 [1, 2, None, 11, 12, 13, 14, 15, 16],
131 def test_on_end(self):
132 # 1 2 ... 12 13 14 15 [16
133 self.assertListEqual(
134 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 2)['pages'],
135 [1, 2, None, 12, 13, 14, 15, 16]
139 class NoMarginTestCase(SimpleTestCase):
141 self.p = Paginator(range(31), 2)
143 def test_on_start(self):
144 self.assertListEqual(
145 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 0)['pages'],
146 [1, 2, 3, 4, 5, None],
149 def test_in_middle(self):
150 self.assertListEqual(
151 paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 0)['pages'],
152 [None, 3, 4, 5, 6, 7, None],
155 def test_on_end(self):
156 self.assertListEqual(
157 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 0)['pages'],
158 [None, 12, 13, 14, 15, 16],
162 class ZeroWindowZeroMarginTestCase(SimpleTestCase):
164 Test paginate using window=0 and margin=0
167 self.p = Paginator(range(31), 2)
169 def test_on_start_page_1(self):
170 self.assertListEqual(
171 paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 0, 0)['pages'],
175 def test_in_middle_page_2(self):
176 self.assertListEqual(
177 paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 0, 0)['pages'],
181 def test_in_middle_page_3(self):
182 self.assertListEqual(
183 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 0, 0)['pages'],
187 def test_in_middle_page_10(self):
188 self.assertListEqual(
189 paginate({'paginator': self.p, 'page_obj': self.p.page(10)}, 0, 0)['pages'],
193 def test_in_middle_page_14(self):
194 self.assertListEqual(
195 paginate({'paginator': self.p, 'page_obj': self.p.page(14)}, 0, 0)['pages'],
199 def test_in_middle_page_15(self):
200 self.assertListEqual(
201 paginate({'paginator': self.p, 'page_obj': self.p.page(15)}, 0, 0)['pages'],
205 def test_on_end_page_16(self):
206 self.assertListEqual(
207 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 0, 0)['pages'],
212 class SpecialTestCase(SimpleTestCase):
213 def test_middle_with_no_window_and_margin_1(self):
214 p = Paginator(range(31), 2)
215 self.assertListEqual(
216 paginate({'paginator': p, 'page_obj': p.page(5)}, 0, 1)['pages'],
217 [1, None, 5, None, 16],
220 def test_middle_with_no_window_and_margin_4(self):
221 p = Paginator(range(21), 2, 1)
222 self.assertListEqual(
223 paginate({'paginator': p, 'page_obj': p.page(1)}, 0, 4)['pages'],
224 [1, 2, 3, 4, None, 7, 8, 9, 10],
228 class TemplateRenderingTestCase(SimpleTestCase):
229 def test_default_tag_options(self):
230 t = Template("{% load pagination_tags %}{% autopaginate var %}{% paginate %}")
232 '<div class="pagination">',
233 t.render(Context({'var': range(21), 'request': HttpRequest()})),
236 def test_paginate_by_option(self):
237 t = Template("{% load pagination_tags %}{% autopaginate var 20 %}{% paginate %}")
239 '<div class="pagination">',
240 t.render(Context({'var': range(21), 'request': HttpRequest()})),
243 def test_orphans_option(self):
244 t = Template("{% load pagination_tags %}{% autopaginate var by %}{% paginate %}")
245 content = t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()}))
246 self.assertIn('<div class="pagination">', content)
247 self.assertIn('<a href="?page=2"', content)
249 def test_as_option(self):
250 t = Template("{% load pagination_tags %}{% autopaginate var by as foo %}{{ foo }}")
252 t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()})),
256 def test_multiple_pagination(self):
257 t = Template("{% load pagination_tags %}{% autopaginate var2 by as foo2 %}{% paginate %}"
258 "{% autopaginate var by as foo %}{% paginate %}")
259 content = t.render(Context({'var': range(21), 'var2': range(50, 121), 'by': 20, 'request': HttpRequest()}))
260 self.assertIn('<div class="pagination">', content)
261 self.assertIn('<a href="?page_var2=2"', content)
262 self.assertIn('<a href="?page_var=2"', content)
265 class InfinitePaginatorTestCase(SimpleTestCase):
267 self.p = InfinitePaginator(range(20), 2, link_template='/bacon/page/%d')
269 def test_paginator_repr(self):
271 repr(InfinitePaginator),
272 "<class 'linaro_django_pagination.paginator.InfinitePaginator'>",
275 def test_validate_number(self):
276 self.assertEqual(self.p.validate_number(2), 2)
278 def test_orphans(self):
279 self.assertEqual(self.p.orphans, 0)
281 def test_page_repr(self):
282 self.assertEqual(repr(self.p.page(3)), '<Page 3>')
284 def test_page_end_index(self):
285 self.assertEqual(self.p.page(3).end_index(), 6)
287 def test_page_has_next(self):
288 self.assertTrue(self.p.page(3).has_next(), True)
290 def test_page_has_previous(self):
291 self.assertTrue(self.p.page(3).has_previous(), True)
293 def test_page_next_link(self):
294 self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
296 def test_page_previous_link(self):
297 self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
299 def test_last_page_which_has_no_next_page(self):
300 self.assertFalse(self.p.page(10).has_next())
302 def test_first_page_which_has_no_previous_page(self):
303 self.assertFalse(self.p.page(1).has_previous())
306 class FinitePaginatorTestCase(SimpleTestCase):
308 self.p = FinitePaginator(range(20), 2, offset=10, link_template='/bacon/page/%d')
312 repr(FinitePaginator),
313 "<class 'linaro_django_pagination.paginator.FinitePaginator'>"
316 def test_validate_number(self):
317 self.assertEqual(self.p.validate_number(2), 2)
319 def test_orphans(self):
320 self.assertEqual(self.p.orphans, 0)
322 def test_page_repr(self):
323 self.assertEqual(repr(self.p.page(3)), '<Page 3>')
325 def test_page_start_index(self):
326 self.assertEqual(self.p.page(3).start_index(), 10)
328 def test_page_end(self):
329 self.assertEqual(self.p.page(3).end_index(), 6)
331 def test_page_has_next(self):
332 self.assertTrue(self.p.page(3).has_next(), True)
334 def test_page_has_previous(self):
335 self.assertTrue(self.p.page(3).has_previous(), True)
337 def test_page_next_link(self):
338 self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
340 def test_page_previous_link(self):
341 self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
343 def test_on_start_page_repr(self):
344 self.assertEqual(repr(self.p.page(2)), '<Page 2>')
346 def test_on_start_has_no_next(self):
347 self.assertTrue(self.p.page(2).has_next(), False)
349 def test_on_start_has_previous(self):
350 self.assertTrue(self.p.page(2).has_previous(), True)
352 def test_on_start_has_next_link(self):
353 self.assertEqual(self.p.page(2).next_link(), '/bacon/page/3')
355 def test_on_start_has_previous_link(self):
356 self.assertEqual(self.p.page(2).previous_link(), '/bacon/page/1')
359 class MiddlewareTestCase(SimpleTestCase):
363 def test_get_page_in_request(self):
364 middleware = PaginationMiddleware()
365 request = DjangoHttpRequest()
366 middleware.process_request(request)
367 self.assertEqual(request.page(''), 1)