PageRenderTime 68ms CodeModel.GetById 43ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/hyde/tests/ext/test_images.py

http://github.com/hyde/hyde
Python | 286 lines | 263 code | 11 blank | 12 comment | 0 complexity | 0d521077bd5b60a9ef67ecdab66a75c7 MD5 | raw file
  1# -*- coding: utf-8 -*-
  2"""
  3Use nose
  4`$ pip install nose`
  5`$ nosetests`
  6
  7Requires PIL
  8"""
  9from hyde.generator import Generator
 10from hyde.site import Site
 11from hyde.ext.plugins.images import thumb_scale_size
 12
 13
 14from fswrap import File
 15import yaml
 16
 17TEST_SITE = File(__file__).parent.parent.child_folder('_test')
 18IMAGE_SOURCE = File(__file__).parent.child_folder('images')
 19
 20PORTRAIT_IMAGE = "portrait.jpg"
 21PORTRAIT_SIZE = (90, 120)
 22LANDSCAPE_IMAGE = "landscape.jpg"
 23LANDSCAPE_SIZE = (120, 90)
 24
 25IMAGES = [PORTRAIT_IMAGE, LANDSCAPE_IMAGE]
 26SIZES = [PORTRAIT_SIZE, LANDSCAPE_SIZE]
 27
 28# PIL requirement
 29try:
 30    from PIL import Image
 31except ImportError:
 32    # No pillow
 33    import Image
 34
 35class TestImageSizer(object):
 36
 37    def setUp(self):
 38        TEST_SITE.make()
 39        TEST_SITE.parent.child_folder(
 40                    'sites/test_jinja').copy_contents_to(TEST_SITE)
 41        IMAGES = TEST_SITE.child_folder('content/media/img')
 42        IMAGES.make()
 43        IMAGE_SOURCE.copy_contents_to(IMAGES)
 44        self.site = Site(TEST_SITE)
 45
 46    def tearDown(self):
 47        TEST_SITE.delete()
 48
 49    def _generic_test_image(self, text):
 50        self.site.config.mode = "production"
 51        self.site.config.plugins = ['hyde.ext.plugins.images.ImageSizerPlugin']
 52        tlink = File(self.site.content.source_folder.child('timg.html'))
 53        tlink.write(text)
 54        gen = Generator(self.site)
 55        gen.generate_all()
 56        f = File(self.site.config.deploy_root_path.child(tlink.name))
 57        assert f.exists
 58        html = f.read_all()
 59        assert html
 60        return html
 61
 62    def test_size_image(self):
 63        text = u"""
 64<img src="/media/img/%s">
 65""" % PORTRAIT_IMAGE
 66        html = self._generic_test_image(text)
 67        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
 68        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
 69
 70    def test_size_image_relative(self):
 71        text = u"""
 72<img src="media/img/%s">
 73""" % PORTRAIT_IMAGE
 74        html = self._generic_test_image(text)
 75        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
 76        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
 77
 78    def test_size_image_no_resize(self):
 79        text = u"""
 80<img src="/media/img/%s" width="2000" height="150">
 81""" % PORTRAIT_IMAGE
 82        html = self._generic_test_image(text)
 83        assert ' width="%d"' % PORTRAIT_SIZE[0] not in html
 84        assert ' height="%d"' % PORTRAIT_SIZE[1] not in html
 85
 86    def test_size_image_size_proportional(self):
 87        text = u"""
 88<img src="/media/img/%s" width="%d">
 89""" % (PORTRAIT_IMAGE,  PORTRAIT_SIZE[0]*2)
 90        html = self._generic_test_image(text)
 91        assert ' width="%d"' % (PORTRAIT_SIZE[0]*2) in html
 92        assert ' height="%d"' % (PORTRAIT_SIZE[1]*2) in html
 93
 94    def test_size_image_not_exists(self):
 95        text = u"""
 96<img src="/media/img/hyde-logo-no.png">
 97"""
 98        self._generic_test_image(text)
 99
100    def test_size_image_multiline(self):
101        text = u"""
102     <img src="/media/img/%s">
103""" % PORTRAIT_IMAGE
104        html = self._generic_test_image(text)
105        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
106        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
107
108    def test_size_multiple_images(self):
109        text = u"""
110<img src="/media/img/%s">
111<img src="/media/img/%s">Hello <img src="/media/img/%s">
112<img src="/media/img/%s">Bye
113""" % ((PORTRAIT_IMAGE,)*4)
114        html = self._generic_test_image(text)
115        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
116        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
117        assert 'Hello ' in html
118        assert 'Bye' in html
119        assert len([f for f in html.split("<img")
120                    if ' width=' in f]) == 4
121        assert len([f for f in html.split("<img")
122                    if ' height=' in f]) == 4
123
124    def test_size_malformed1(self):
125        text = u"""
126<img src="/media/img/%s>
127""" % PORTRAIT_IMAGE
128        html = self._generic_test_image(text)
129        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
130        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
131
132    def test_size_malformed2(self):
133        text = u"""
134<img src="/media/img/%s alt="hello">
135""" % PORTRAIT_IMAGE
136        html = self._generic_test_image(text)
137        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
138        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
139
140    def test_outside_media_url(self):
141        self.site.config.media_url = "http://media.example.com/"
142        text = u"""
143<img src="http://media.example.com/img/%s" alt="hello">
144""" % PORTRAIT_IMAGE
145        html = self._generic_test_image(text)
146        assert ' width="%d"' % PORTRAIT_SIZE[0] in html
147        assert ' height="%d"' % PORTRAIT_SIZE[1] in html
148
149class TestImageThumbSize(object):
150
151    def test_width_only(self):
152        ow, oh = 100, 200
153        nw, nh = thumb_scale_size(ow, oh, 50, None)
154        assert nw == 50
155        assert nh == 100
156
157    def test_width_only_nonintegral(self):
158        ow, oh = 100, 205
159        nw, nh = thumb_scale_size(ow, oh, 50, None)
160        assert nw == 50
161        assert nh == 103
162
163    def test_height_only(self):
164        ow, oh = 100, 200
165        nw, nh = thumb_scale_size(ow, oh, None, 100)
166        assert nw == 50
167        assert nh == 100
168
169    def test_height_only_nonintegral(self):
170        ow, oh = 105, 200
171        nw, nh = thumb_scale_size(ow, oh, None, 100)
172        assert nw == 53
173        assert nh == 100
174
175    def test_height_and_width_portrait(self):
176        ow, oh = 100, 200
177        nw, nh = thumb_scale_size(ow, oh, 50, 50)
178        assert nw == 50
179        assert nh == 100
180
181    def test_height_and_width_landscape(self):
182        ow, oh = 200, 100
183        nw, nh = thumb_scale_size(ow, oh, 50, 50)
184        assert nw == 100
185        assert nh == 50
186
187class TestImageThumbnails(object):
188    # TODO: add tests for cropping? (not easy currently)
189
190    def setUp(self):
191        TEST_SITE.make()
192        TEST_SITE.parent.child_folder(
193                    'sites/test_jinja').copy_contents_to(TEST_SITE)
194        IMAGES = TEST_SITE.child_folder('content/media/img')
195        IMAGES.make()
196        IMAGE_SOURCE.copy_contents_to(IMAGES)
197        self.image_folder = IMAGES
198        self.site = Site(TEST_SITE)
199
200    def tearDown(self):
201        TEST_SITE.delete()
202
203    def _generate_site_with_meta(self, meta):
204        self.site.config.mode = "production"
205        self.site.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin', 'hyde.ext.plugins.images.ImageThumbnailsPlugin']
206
207        mlink = File(self.image_folder.child('meta.yaml'))
208        meta_text = yaml.dump(meta, default_flow_style=False)
209        mlink.write(meta_text)
210        gen = Generator(self.site)
211        gen.generate_all()
212
213    def _test_generic_thumbnails(self, meta):
214        self._generate_site_with_meta(meta)
215        thumb_meta = meta.get('thumbnails', [])
216        for th in thumb_meta:
217            prefix = th.get('prefix')
218            if prefix is None:
219                continue
220
221            for fn in [PORTRAIT_IMAGE, LANDSCAPE_IMAGE]:
222                f = File(self._deployed_image(prefix, fn))
223                assert f.exists
224
225    def _deployed_image(self, prefix, filename):
226        return self.site.config.deploy_root_path.child('media/img/%s%s'%(prefix,filename))
227
228    def test_width(self):
229        prefix='thumb_'
230        meta = dict(thumbnails=[dict(width=50, prefix=prefix, include=['*.jpg'])])
231        self._test_generic_thumbnails(meta)
232        for fn in IMAGES:
233            im = Image.open(self._deployed_image(prefix, fn))
234            assert im.size[0] == 50
235
236    def test_height(self):
237        prefix='thumb_'
238        meta = dict(thumbnails=[dict(height=50, prefix=prefix, include=['*.jpg'])])
239        self._test_generic_thumbnails(meta)
240        for fn in IMAGES:
241            im = Image.open(self._deployed_image(prefix, fn))
242            assert im.size[1] == 50
243
244    def test_width_and_height(self):
245        prefix='thumb_'
246        meta = dict(thumbnails=[dict(width=50, height=50, prefix=prefix, include=['*.jpg'])])
247        self._test_generic_thumbnails(meta)
248        for fn in IMAGES:
249            im = Image.open(self._deployed_image(prefix, fn))
250            assert im.size[0] == 50
251            assert im.size[1] == 50
252
253    def test_larger(self):
254        prefix='thumb_'
255        meta = dict(thumbnails=[dict(larger=50, prefix=prefix, include=['*.jpg'])])
256        self._test_generic_thumbnails(meta)
257
258        im = Image.open(self._deployed_image(prefix, PORTRAIT_IMAGE))
259        assert im.size[1] == 50
260
261        im = Image.open(self._deployed_image(prefix, LANDSCAPE_IMAGE))
262        assert im.size[0] == 50
263
264    def test_smaller(self):
265        prefix='thumb_'
266        meta = dict(thumbnails=[dict(smaller=50, prefix=prefix, include=['*.jpg'])])
267        self._test_generic_thumbnails(meta)
268
269        im = Image.open(self._deployed_image(prefix, PORTRAIT_IMAGE))
270        assert im.size[0] == 50
271
272        im = Image.open(self._deployed_image(prefix, LANDSCAPE_IMAGE))
273        assert im.size[1] == 50
274
275    def test_larger_and_smaller(self):
276        prefix='thumb_'
277        meta = dict(thumbnails=[dict(larger=100, smaller=50, prefix=prefix, include=['*.jpg'])])
278        self._test_generic_thumbnails(meta)
279
280        im = Image.open(self._deployed_image(prefix, PORTRAIT_IMAGE))
281        assert im.size[0] == 50
282        assert im.size[1] == 100
283
284        im = Image.open(self._deployed_image(prefix, LANDSCAPE_IMAGE))
285        assert im.size[0] == 100
286        assert im.size[1] == 50