Commit f6f24cbf by Chris Jerdonek

Merge branch 'issue_62' into development: closing issue #62

parents fe888064 b41b8e10
...@@ -6,7 +6,7 @@ This module provides a Loader class. ...@@ -6,7 +6,7 @@ This module provides a Loader class.
""" """
import os import os
import sys
DEFAULT_EXTENSION = 'mustache' DEFAULT_EXTENSION = 'mustache'
...@@ -19,6 +19,11 @@ class Loader(object): ...@@ -19,6 +19,11 @@ class Loader(object):
Arguments: Arguments:
encoding: the name of the encoding to use when converting file
contents to unicode. This name will be passed as the encoding
argument to the built-in function unicode(). Defaults to the
encoding name returned by sys.getdefaultencoding().
search_dirs: the directories in which to search for templates. search_dirs: the directories in which to search for templates.
Defaults to the current working directory. Defaults to the current working directory.
...@@ -26,6 +31,8 @@ class Loader(object): ...@@ -26,6 +31,8 @@ class Loader(object):
Pass False for no extension. Pass False for no extension.
""" """
if encoding is None:
encoding = sys.getdefaultencoding()
if extension is None: if extension is None:
extension = DEFAULT_EXTENSION extension = DEFAULT_EXTENSION
if search_dirs is None: if search_dirs is None:
...@@ -73,9 +80,9 @@ class Loader(object): ...@@ -73,9 +80,9 @@ class Loader(object):
try: try:
template = f.read() template = f.read()
if self.template_encoding:
template = unicode(template, self.template_encoding)
finally: finally:
f.close() f.close()
template = unicode(template, self.template_encoding)
return template return template
...@@ -133,15 +133,31 @@ class Renderer(object): ...@@ -133,15 +133,31 @@ class Renderer(object):
return context return context
def _make_render_engine(self): def _make_load_partial(self):
""" """
Return a RenderEngine instance for rendering. Return the load_partial function for use by RenderEngine.
""" """
# Make sure the return value of load_template is unicode.
def load_partial(name): def load_partial(name):
template = self.load_template(name) template = self.load_template(name)
return self.unicode(template) # Make sure the return value of load_template is unicode since
# RenderEngine requires it. Also, check that the string is not
# already unicode to avoid "double-decoding". Otherwise, we
# would get the following error:
# TypeError: decoding Unicode is not supported
if not isinstance(template, unicode):
template = self.unicode(template)
return template
return load_partial
def _make_render_engine(self):
"""
Return a RenderEngine instance for rendering.
"""
load_partial = self._make_load_partial()
engine = RenderEngine(load_partial=load_partial, engine = RenderEngine(load_partial=load_partial,
literal=self.literal, literal=self.literal,
......
import os import os
import sys
import unittest import unittest
from pystache.loader import Loader from pystache.loader import Loader
...@@ -8,18 +9,13 @@ class LoaderTestCase(unittest.TestCase): ...@@ -8,18 +9,13 @@ class LoaderTestCase(unittest.TestCase):
search_dirs = 'examples' search_dirs = 'examples'
def test_init(self): def test_init__search_dirs(self):
""" # Test the default value.
Test the __init__() constructor.
"""
loader = Loader() loader = Loader()
self.assertEquals(loader.search_dirs, [os.curdir]) self.assertEquals(loader.search_dirs, [os.curdir])
self.assertTrue(loader.template_encoding is None)
loader = Loader(search_dirs=['foo'], encoding='utf-8') loader = Loader(search_dirs=['foo'])
self.assertEquals(loader.search_dirs, ['foo']) self.assertEquals(loader.search_dirs, ['foo'])
self.assertEquals(loader.template_encoding, 'utf-8')
def test_init__extension(self): def test_init__extension(self):
# Test the default value. # Test the default value.
...@@ -32,6 +28,14 @@ class LoaderTestCase(unittest.TestCase): ...@@ -32,6 +28,14 @@ class LoaderTestCase(unittest.TestCase):
loader = Loader(extension=False) loader = Loader(extension=False)
self.assertTrue(loader.template_extension is False) self.assertTrue(loader.template_extension is False)
def test_init__loader(self):
# Test the default value.
loader = Loader()
self.assertEquals(loader.template_encoding, sys.getdefaultencoding())
loader = Loader(encoding='foo')
self.assertEquals(loader.template_encoding, 'foo')
def test_make_file_name(self): def test_make_file_name(self):
loader = Loader() loader = Loader()
...@@ -67,3 +71,13 @@ class LoaderTestCase(unittest.TestCase): ...@@ -67,3 +71,13 @@ class LoaderTestCase(unittest.TestCase):
loader.template_extension = False loader.template_extension = False
self.assertEquals(loader.load_template('extensionless'), "No file extension: {{foo}}") self.assertEquals(loader.load_template('extensionless'), "No file extension: {{foo}}")
def test_load_template__unicode_return_value(self):
"""
Check that load_template() returns unicode strings.
"""
loader = Loader(search_dirs=self.search_dirs)
template = loader.load_template('simple')
self.assertEqual(type(template), unicode)
...@@ -240,6 +240,20 @@ class RendererTestCase(unittest.TestCase): ...@@ -240,6 +240,20 @@ class RendererTestCase(unittest.TestCase):
renderer.default_encoding = 'utf_8' renderer.default_encoding = 'utf_8'
self.assertEquals(renderer.render(template), "déf") self.assertEquals(renderer.render(template), "déf")
def test_make_load_partial__unicode(self):
"""
Test that the generated load_partial does not "double-decode" Unicode.
"""
renderer = Renderer()
# In real-life, the partial would be different with each name.
renderer.load_template = lambda name: u"partial"
load_partial = renderer._make_load_partial()
# This would raise a TypeError exception if we tried to double-decode.
self.assertEquals(load_partial("test"), "partial")
# By testing that Renderer.render() constructs the RenderEngine instance # By testing that Renderer.render() constructs the RenderEngine instance
# 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
......
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