Commit fe888064 by Chris Jerdonek

Merge 'issue_61' into development: closing issue #61

Ensures that the Renderer class can handle the case of load_template
not returning unicode.
parents cb7383e7 d5cee636
...@@ -55,10 +55,14 @@ class RenderEngine(object): ...@@ -55,10 +55,14 @@ class RenderEngine(object):
modifiers = Modifiers() modifiers = Modifiers()
def __init__(self, load_template=None, literal=None, escape=None): def __init__(self, load_partial=None, literal=None, escape=None):
""" """
Arguments: Arguments:
load_partial: a function for loading templates by name when
loading partials. The function should accept a template name
and return a unicode template string.
escape: a function that takes a unicode or str string, escape: a function that takes a unicode or str string,
converts it to unicode, and escapes and returns it. converts it to unicode, and escapes and returns it.
...@@ -68,7 +72,7 @@ class RenderEngine(object): ...@@ -68,7 +72,7 @@ class RenderEngine(object):
""" """
self.escape = escape self.escape = escape
self.literal = literal self.literal = literal
self.load_template = load_template self.load_partial = load_partial
def render(self, template, context): def render(self, template, context):
""" """
...@@ -178,7 +182,7 @@ class RenderEngine(object): ...@@ -178,7 +182,7 @@ class RenderEngine(object):
@modifiers.set('>') @modifiers.set('>')
def _render_partial(self, template_name): def _render_partial(self, template_name):
markup = self.load_template(template_name) markup = self.load_partial(template_name)
return self._render(markup) return self._render(markup)
@modifiers.set('=') @modifiers.set('=')
...@@ -194,7 +198,7 @@ class RenderEngine(object): ...@@ -194,7 +198,7 @@ class RenderEngine(object):
@modifiers.set('{') @modifiers.set('{')
@modifiers.set('&') @modifiers.set('&')
def render_unescaped(self, tag_name): def _render_unescaped(self, tag_name):
""" """
Render a tag without escaping it. Render a tag without escaping it.
......
...@@ -138,7 +138,12 @@ class Renderer(object): ...@@ -138,7 +138,12 @@ class Renderer(object):
Return a RenderEngine instance for rendering. Return a RenderEngine instance for rendering.
""" """
engine = RenderEngine(load_template=self.load_template, # Make sure the return value of load_template is unicode.
def load_partial(name):
template = self.load_template(name)
return self.unicode(template)
engine = RenderEngine(load_partial=load_partial,
literal=self.literal, literal=self.literal,
escape=self._unicode_and_escape) escape=self._unicode_and_escape)
return engine return engine
......
...@@ -21,13 +21,12 @@ class RenderEngineTestCase(unittest.TestCase): ...@@ -21,13 +21,12 @@ class RenderEngineTestCase(unittest.TestCase):
Create and return a default RenderEngine for testing. Create and return a default RenderEngine for testing.
""" """
load_template = None
to_unicode = unicode to_unicode = unicode
escape = lambda s: cgi.escape(to_unicode(s)) escape = lambda s: cgi.escape(to_unicode(s))
literal = to_unicode literal = to_unicode
engine = RenderEngine(literal=literal, escape=escape, load_template=None) engine = RenderEngine(literal=literal, escape=escape, load_partial=None)
return engine return engine
def _assert_render(self, expected, template, *context, **kwargs): def _assert_render(self, expected, template, *context, **kwargs):
...@@ -35,7 +34,7 @@ class RenderEngineTestCase(unittest.TestCase): ...@@ -35,7 +34,7 @@ class RenderEngineTestCase(unittest.TestCase):
engine = kwargs.get('engine', self._engine()) engine = kwargs.get('engine', self._engine())
if partials is not None: if partials is not None:
engine.load_template = lambda key: partials[key] engine.load_partial = lambda key: partials[key]
context = Context(*context) context = Context(*context)
...@@ -49,23 +48,23 @@ class RenderEngineTestCase(unittest.TestCase): ...@@ -49,23 +48,23 @@ class RenderEngineTestCase(unittest.TestCase):
""" """
# In real-life, these arguments would be functions # In real-life, these arguments would be functions
engine = RenderEngine(load_template="load_template", literal="literal", escape="escape") engine = RenderEngine(load_partial="foo", literal="literal", escape="escape")
self.assertEquals(engine.load_partial, "foo")
self.assertEquals(engine.escape, "escape") self.assertEquals(engine.escape, "escape")
self.assertEquals(engine.literal, "literal") self.assertEquals(engine.literal, "literal")
self.assertEquals(engine.load_template, "load_template")
def test_render(self): def test_render(self):
self._assert_render('Hi Mom', 'Hi {{person}}', {'person': 'Mom'}) self._assert_render('Hi Mom', 'Hi {{person}}', {'person': 'Mom'})
def test_render__load_template(self): def test_render__load_partial(self):
""" """
Test that render() uses the load_template attribute. Test that render() uses the load_template attribute.
""" """
engine = self._engine() engine = self._engine()
partials = {'partial': "{{person}}"} partials = {'partial': "{{person}}"}
engine.load_template = lambda key: partials[key] engine.load_partial = lambda key: partials[key]
self._assert_render('Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, engine=engine) self._assert_render('Hi Mom', 'Hi {{>partial}}', {'person': 'Mom'}, engine=engine)
def test_render__literal(self): def test_render__literal(self):
......
...@@ -244,16 +244,19 @@ class RendererTestCase(unittest.TestCase): ...@@ -244,16 +244,19 @@ class RendererTestCase(unittest.TestCase):
# correctly, we no longer need to test the rendering code paths through # correctly, we no longer need to test the rendering code paths through
# the Renderer. We can test rendering paths through only the RenderEngine # the Renderer. We can test rendering paths through only the RenderEngine
# for the same amount of code coverage. # for the same amount of code coverage.
def test_make_render_engine__load_template(self): def test_make_render_engine__load_partial(self):
""" """
Test that _make_render_engine() passes the right load_template. Test that _make_render_engine() constructs and passes load_partial correctly.
""" """
renderer = Renderer() renderer = Renderer()
renderer.load_template = "foo" # in real life, this would be a function. renderer.unicode = lambda s: s.upper() # a test version.
# In real-life, the partial would be different with each name.
renderer.load_template = lambda name: "partial"
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
self.assertEquals(engine.load_template, "foo") # Make sure it calls unicode.
self.assertEquals(engine.load_partial('name'), "PARTIAL")
def test_make_render_engine__literal(self): def test_make_render_engine__literal(self):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment