5d1a1cb174afa0294a380612c1e328e7ad35d376
[wolnelektury.git] / apps / sorl / thumbnail / tests / templatetags.py
1 import os
2 from django.conf import settings
3 from django.template import Template, Context, TemplateSyntaxError
4 from sorl.thumbnail.tests.classes import BaseTest, RELATIVE_PIC_NAME
5
6
7 class ThumbnailTagTest(BaseTest):
8     def render_template(self, source):
9         context = Context({
10             'source': RELATIVE_PIC_NAME,
11             'invalid_source': 'not%s' % RELATIVE_PIC_NAME,
12             'size': (90, 100),
13             'invalid_size': (90, 'fish'),
14             'strsize': '80x90',
15             'invalid_strsize': ('1notasize2'),
16             'invalid_q': 'notanumber'})
17         source = '{% load thumbnail %}' + source
18         return Template(source).render(context)
19
20     def testTagInvalid(self):
21         # No args, or wrong number of args
22         src = '{% thumbnail %}'
23         self.assertRaises(TemplateSyntaxError, self.render_template, src)
24         src = '{% thumbnail source %}'
25         self.assertRaises(TemplateSyntaxError, self.render_template, src)
26         src = '{% thumbnail source 80x80 as variable crop %}'
27         self.assertRaises(TemplateSyntaxError, self.render_template, src)
28
29         # Invalid option
30         src = '{% thumbnail source 240x200 invalid %}'
31         self.assertRaises(TemplateSyntaxError, self.render_template, src)
32
33         # Old comma separated options format can only have an = for quality
34         src = '{% thumbnail source 80x80 crop=1,quality=1 %}'
35         self.assertRaises(TemplateSyntaxError, self.render_template, src)
36
37         # Invalid quality
38         src_invalid = '{% thumbnail source 240x200 quality=invalid_q %}'
39         src_missing = '{% thumbnail source 240x200 quality=missing_q %}'
40         # ...with THUMBNAIL_DEBUG = False
41         self.assertEqual(self.render_template(src_invalid), '')
42         self.assertEqual(self.render_template(src_missing), '')
43         # ...and with THUMBNAIL_DEBUG = True
44         self.change_settings.change({'DEBUG': True})
45         self.assertRaises(TemplateSyntaxError, self.render_template,
46                           src_invalid)
47         self.assertRaises(TemplateSyntaxError, self.render_template,
48                           src_missing)
49
50         # Invalid source
51         src = '{% thumbnail invalid_source 80x80 %}'
52         src_on_context = '{% thumbnail invalid_source 80x80 as thumb %}'
53         # ...with THUMBNAIL_DEBUG = False
54         self.change_settings.change({'DEBUG': False})
55         self.assertEqual(self.render_template(src), '')
56         # ...and with THUMBNAIL_DEBUG = True
57         self.change_settings.change({'DEBUG': True})
58         self.assertRaises(TemplateSyntaxError, self.render_template, src)
59         self.assertRaises(TemplateSyntaxError, self.render_template,
60                           src_on_context)
61
62         # Non-existant source
63         src = '{% thumbnail non_existant_source 80x80 %}'
64         src_on_context = '{% thumbnail non_existant_source 80x80 as thumb %}'
65         # ...with THUMBNAIL_DEBUG = False
66         self.change_settings.change({'DEBUG': False})
67         self.assertEqual(self.render_template(src), '')
68         # ...and with THUMBNAIL_DEBUG = True
69         self.change_settings.change({'DEBUG': True})
70         self.assertRaises(TemplateSyntaxError, self.render_template, src)
71
72         # Invalid size as a tuple:
73         src = '{% thumbnail source invalid_size %}'
74         # ...with THUMBNAIL_DEBUG = False
75         self.change_settings.change({'DEBUG': False})
76         self.assertEqual(self.render_template(src), '')
77         # ...and THUMBNAIL_DEBUG = True
78         self.change_settings.change({'DEBUG': True})
79         self.assertRaises(TemplateSyntaxError, self.render_template, src)
80         # Invalid size as a string:
81         src = '{% thumbnail source invalid_strsize %}'
82         # ...with THUMBNAIL_DEBUG = False
83         self.change_settings.change({'DEBUG': False})
84         self.assertEqual(self.render_template(src), '')
85         # ...and THUMBNAIL_DEBUG = True
86         self.change_settings.change({'DEBUG': True})
87         self.assertRaises(TemplateSyntaxError, self.render_template, src)
88
89         # Non-existant size
90         src = '{% thumbnail source non_existant_size %}'
91         # ...with THUMBNAIL_DEBUG = False
92         self.change_settings.change({'DEBUG': False})
93         self.assertEqual(self.render_template(src), '')
94         # ...and THUMBNAIL_DEBUG = True
95         self.change_settings.change({'DEBUG': True})
96         self.assertRaises(TemplateSyntaxError, self.render_template, src)
97
98     def testTag(self):
99         expected_base = RELATIVE_PIC_NAME.replace('.', '_')
100         # Set DEBUG = True to make it easier to trace any failures
101         self.change_settings.change({'DEBUG': True})
102
103         # Basic
104         output = self.render_template('src="'
105             '{% thumbnail source 240x240 %}"')
106         expected = '%s_240x240_q85.jpg' % expected_base
107         expected_fn = os.path.join(settings.MEDIA_ROOT, expected)
108         self.verify_thumbnail((240, 180), expected_filename=expected_fn)
109         expected_url = ''.join((settings.MEDIA_URL, expected))
110         self.assertEqual(output, 'src="%s"' % expected_url)
111
112         # Size from context variable
113         # as a tuple:
114         output = self.render_template('src="'
115             '{% thumbnail source size %}"')
116         expected = '%s_90x100_q85.jpg' % expected_base
117         expected_fn = os.path.join(settings.MEDIA_ROOT, expected)
118         self.verify_thumbnail((90, 67), expected_filename=expected_fn)
119         expected_url = ''.join((settings.MEDIA_URL, expected))
120         self.assertEqual(output, 'src="%s"' % expected_url)
121         # as a string:
122         output = self.render_template('src="'
123             '{% thumbnail source strsize %}"')
124         expected = '%s_80x90_q85.jpg' % expected_base
125         expected_fn = os.path.join(settings.MEDIA_ROOT, expected)
126         self.verify_thumbnail((80, 60), expected_filename=expected_fn)
127         expected_url = ''.join((settings.MEDIA_URL, expected))
128         self.assertEqual(output, 'src="%s"' % expected_url)
129
130         # On context
131         output = self.render_template('height:'
132             '{% thumbnail source 240x240 as thumb %}{{ thumb.height }}')
133         self.assertEqual(output, 'height:180')
134
135         # With options and quality
136         output = self.render_template('src="'
137             '{% thumbnail source 240x240 sharpen crop quality=95 %}"')
138         # Note that the opts are sorted to ensure a consistent filename.
139         expected = '%s_240x240_crop_sharpen_q95.jpg' % expected_base
140         expected_fn = os.path.join(settings.MEDIA_ROOT, expected)
141         self.verify_thumbnail((240, 240), expected_filename=expected_fn)
142         expected_url = ''.join((settings.MEDIA_URL, expected))
143         self.assertEqual(output, 'src="%s"' % expected_url)
144
145         # With option and quality on context (also using its unicode method to
146         # display the url)
147         output = self.render_template(
148             '{% thumbnail source 240x240 sharpen crop quality=95 as thumb %}'
149             'width:{{ thumb.width }}, url:{{ thumb }}')
150         self.assertEqual(output, 'width:240, url:%s' % expected_url)
151
152         # Old comma separated format for options is still supported.
153         output = self.render_template(
154             '{% thumbnail source 240x240 sharpen,crop,quality=95 as thumb %}'
155             'width:{{ thumb.width }}, url:{{ thumb }}')
156         self.assertEqual(output, 'width:240, url:%s' % expected_url)
157
158 filesize_tests = r"""
159 >>> from sorl.thumbnail.templatetags.thumbnail import filesize
160
161 >>> filesize('abc')
162 'abc'
163 >>> filesize(100, 'invalid')
164 100
165
166 >>> bytes = 20
167 >>> filesize(bytes)
168 '20 B'
169 >>> filesize(bytes, 'auto1000')
170 '20 B'
171
172 >>> bytes = 1001
173 >>> filesize(bytes)
174 '1001 B'
175 >>> filesize(bytes, 'auto1000')
176 '1 kB'
177
178 >>> bytes = 10100
179 >>> filesize(bytes)
180 '9.9 KiB'
181
182 # Note that the decimal place is only used if < 10
183 >>> filesize(bytes, 'auto1000')
184 '10 kB'
185
186 >>> bytes = 190000000
187 >>> filesize(bytes)
188 '181 MiB'
189 >>> filesize(bytes, 'auto1000')
190 '190 MB'
191
192 # 'auto*long' methods use pluralisation:
193 >>> filesize(1, 'auto1024long')
194 '1 byte'
195 >>> filesize(1, 'auto1000long')
196 '1 byte'
197 >>> filesize(2, 'auto1024long')
198 '2 bytes'
199 >>> filesize(0, 'auto1000long')
200 '0 bytes'
201
202 # Test all 'auto*long' output:
203 >>> for i in range(1,10):
204 ...     print '%s, %s' % (filesize(1024**i, 'auto1024long'),
205 ...                       filesize(1000**i, 'auto1000long'))
206 1 kibibyte, 1 kilobyte
207 1 mebibyte, 1 megabyte
208 1 gibibyte, 1 gigabyte
209 1 tebibyte, 1 terabyte
210 1 pebibyte, 1 petabyte
211 1 exbibyte, 1 exabyte
212 1 zebibyte, 1 zettabyte
213 1 yobibyte, 1 yottabyte
214 1024 yobibytes, 1000 yottabytes
215
216 # Test all fixed outputs (eg 'kB' or 'MiB')
217 >>> from sorl.thumbnail.templatetags.thumbnail import filesize_formats,\
218 ...    filesize_long_formats
219 >>> for f in filesize_formats:
220 ...     print '%s (%siB, %sB):' % (filesize_long_formats[f], f.upper(), f)
221 ...     for i in range(0, 10):
222 ...         print ' %s, %s' % (filesize(1024**i, '%siB' % f.upper()),
223 ...                            filesize(1000**i, '%sB' % f))
224 kilo (KiB, kB):
225  0.0009765625, 0.001
226  1.0, 1.0
227  1024.0, 1000.0
228  1048576.0, 1000000.0
229  1073741824.0, 1000000000.0
230  1.09951162778e+12, 1e+12
231  1.12589990684e+15, 1e+15
232  1.15292150461e+18, 1e+18
233  1.18059162072e+21, 1e+21
234  1.20892581961e+24, 1e+24
235 mega (MiB, MB):
236  0.0, 1e-06
237  0.0009765625, 0.001
238  1.0, 1.0
239  1024.0, 1000.0
240  1048576.0, 1000000.0
241  1073741824.0, 1000000000.0
242  1.09951162778e+12, 1e+12
243  1.12589990684e+15, 1e+15
244  1.15292150461e+18, 1e+18
245  1.18059162072e+21, 1e+21
246 giga (GiB, GB):
247  0.0, 1e-09
248  0.0, 1e-06
249  0.0009765625, 0.001
250  1.0, 1.0
251  1024.0, 1000.0
252  1048576.0, 1000000.0
253  1073741824.0, 1000000000.0
254  1.09951162778e+12, 1e+12
255  1.12589990684e+15, 1e+15
256  1.15292150461e+18, 1e+18
257 tera (TiB, TB):
258  0.0, 1e-12
259  0.0, 1e-09
260  0.0, 1e-06
261  0.0009765625, 0.001
262  1.0, 1.0
263  1024.0, 1000.0
264  1048576.0, 1000000.0
265  1073741824.0, 1000000000.0
266  1.09951162778e+12, 1e+12
267  1.12589990684e+15, 1e+15
268 peta (PiB, PB):
269  0.0, 1e-15
270  0.0, 1e-12
271  0.0, 1e-09
272  0.0, 1e-06
273  0.0009765625, 0.001
274  1.0, 1.0
275  1024.0, 1000.0
276  1048576.0, 1000000.0
277  1073741824.0, 1000000000.0
278  1.09951162778e+12, 1e+12
279 exa (EiB, EB):
280  0.0, 1e-18
281  0.0, 1e-15
282  0.0, 1e-12
283  0.0, 1e-09
284  0.0, 1e-06
285  0.0009765625, 0.001
286  1.0, 1.0
287  1024.0, 1000.0
288  1048576.0, 1000000.0
289  1073741824.0, 1000000000.0
290 zetta (ZiB, ZB):
291  0.0, 1e-21
292  0.0, 1e-18
293  0.0, 1e-15
294  0.0, 1e-12
295  0.0, 1e-09
296  0.0, 1e-06
297  0.0009765625, 0.001
298  1.0, 1.0
299  1024.0, 1000.0
300  1048576.0, 1000000.0
301 yotta (YiB, YB):
302  0.0, 1e-24
303  0.0, 1e-21
304  0.0, 1e-18
305  0.0, 1e-15
306  0.0, 1e-12
307  0.0, 1e-09
308  0.0, 1e-06
309  0.0009765625, 0.001
310  1.0, 1.0
311  1024.0, 1000.0
312 """