At Mozilla we use jingo-minify to bundle static resources such as .js and .css files. It's not a perfect solution but it's got some great benefits. One of them is that you need to know exactly which static resources you need in a template and because things are bundled you don't need to care too much about what files it originally consisted of. For example "jquery-1.6.2.js" + "common.js" + "jquery.cookies.js" can become "bundles/core.js"

A drawback of this is if you forget to compress and prepare all assets (using the compress_assets management command in jingo-minify) is that you break your site with missing static resources. So how to test for this?

Here's a simple solution I cooked up which appears to do the trick. It's just a quick start but it works. First:

# tests/mixins.py
import re
from nose.tools import eq_, ok_

SCRIPTS_REGEX = re.compile('<script\s*[^>]*src=["\']([^"\']+)["\'].*?</script>',
                          re.M|re.DOTALL)
STYLES_REGEX = re.compile('<link.*?href=["\']([^"\']+)["\'].*?>',
                         re.M|re.DOTALL)

class EmbedsTestCaseMixin:
   def assert_all_embeds(self, response):
       if hasattr(response, 'content'):
           response = response.content
       response = re.sub('<!--(.*)-->', '', response, re.M)
       for found in SCRIPTS_REGEX.findall(response):
           if found.endswith('.js'):
               resp = self.client.get(found)
               eq_(resp.status_code, 200, found)

       for found in STYLES_REGEX.findall(response):
           if found.endswith('.css'):
               resp = self.client.get(found)
               eq_(resp.status_code, 200, found)

Then with this you can render a page and check that all resources are reachable:

# apps/foo/tests.py
from tests.mixins import EmbedsTestCaseMixin
from django.test import TestCase
from django.core.urlresolvers import reverse

class FooViewsTestCase(TestCase):
    def test_add_page_static_files(self):
         url = reverse('foo.views.add_page')
         response = self.client.get(url)
         assert response.status_code == 200
         self.assert_all_embeds(response)

I know it ain't django-rocket science but it's damn useful as it quickly catches me out if I accidentally get a typo in any of the bundles which in previous projects I've become accustomed to check by simply clicking around in Firefox with Firebug (Net tab) open.

Hope it helps!

Alex - 11 July 2011 [«« Reply to this]
Your comment-removing regex is a bit too greedy: it will eat anything between two comments:

In [10]: re.sub('<!--(.*)-->', '', '<!-- lala -->lu<!-- blah -->', re.M)
Out[10]: ''

fix: use the non-greedy version of *:

In [11]: re.sub('<!--(.*?)-->', '', '<!-- lala -->lu<!-- blah -->', re.M)
Out[11]: 'lu'
Peter Bengtsson - 11 July 2011 [«« Reply to this]
Thanks! Well spotted!


Your email will never ever be published