Skip to content

Instantly share code, notes, and snippets.

@honzakral
Created November 3, 2011 14:30
Show Gist options
  • Save honzakral/1336619 to your computer and use it in GitHub Desktop.
Save honzakral/1336619 to your computer and use it in GitHub Desktop.
Testable python code...
#!/bin/bash
curl -O https://raw.github.com/pypa/virtualenv/master/virtualenv.py
python virtualenv.py testing_in_python
. testing_in_python/bin/activate
pip install django mock
python testable_templatetag.py
from django.template import Node, Library, TemplateSyntaxError
register = Library()
class GetLinkNode(Node):
def __init__(self, app, model, pk):
self.app, self.model, self.pk = app, model, pk
def render(self, context):
from django.db.models.loading import get_model
model = get_model(self.app, self.model)
m = model._default_manager.get(pk=self.pk)
return m.get_absolute_url()
@register.tag('get_link')
def do_get_link(parser, token):
"""
{% get_link for articles.article 2 %}
"""
bits = token.split_contents()
if len(bits) != 4 or bits[1] != 'for' or '.' not in bits[2] or not bits[3].isdigit():
raise TemplateSyntaxError()
app, model = bits[2].split('.', 1)
return GetLinkNode(app, model, int(bits[3]))
import unittest, mock
from django.template import Node, Library, TemplateSyntaxError
register = Library()
class GetLinkNode(Node):
def __init__(self, app, model, pk):
self.app, self.model, self.pk = app, model, pk
def get_model(self):
from django.db.models.loading import get_model
model = get_model(self.app, self.model)
return model._default_manager.get(pk=self.pk)
def render(self, context):
m = self.get_model()
return m.get_absolute_url()
def _parse_get_link(bits):
if len(bits) != 4 or bits[1] != 'for' or '.' not in bits[2] or not bits[3].isdigit():
raise TemplateSyntaxError()
app, model = bits[2].split('.', 1)
return GetLinkNode(app, model, int(bits[3]))
@register.tag('get_link')
def do_get_link(parser, token):
"""
{% get_link for articles.article 2 %}
"""
bits = token.split_contents()
return _parse_get_link(bits)
class TestGetLink(unittest.TestCase):
def test_parser_raises_on_empty(self):
self.assertRaises(TemplateSyntaxError, _parse_get_link, [])
def test_parser_raises_on_no_for(self):
self.assertRaises(TemplateSyntaxError, _parse_get_link, ['get_link', 'as', 'articles.article', '1'])
def test_parser_raises_on_no_dot_in_model(self):
self.assertRaises(TemplateSyntaxError, _parse_get_link, ['get_link', 'for', 'article', '1'])
def test_parser_raises_on_non_numeric_pk(self):
self.assertRaises(TemplateSyntaxError, _parse_get_link, ['get_link', 'for', 'articles.article', 'one'])
def test_parser_constructs_correct_node(self):
node = _parse_get_link(['get_link', 'for', 'articles.article', '1'])
self.assertIsInstance(node, GetLinkNode)
self.assertEquals(1, node.pk)
self.assertEquals('articles', node.app)
self.assertEquals('article', node.model)
def test_node_renders_url_of_object(self):
node = GetLinkNode('articles','article', 1)
with mock.patch.object(node, 'get_model'):
ret = node.render({})
node.get_model.assert_called_once_with()
self.assertEquals(ret, node.get_model().get_absolute_url())
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment