Commit 137fd4f2 by Chris Jerdonek

Merge 'issue_74' into development: closing issue #74 (Renderer.render_path)

parents 58494244 b09cd303
...@@ -33,8 +33,8 @@ class Renderer(object): ...@@ -33,8 +33,8 @@ class Renderer(object):
""" """
def __init__(self, loader=None, default_encoding=None, decode_errors='strict', def __init__(self, loader=None, file_encoding=None, default_encoding=None,
escape=None): decode_errors='strict', escape=None):
""" """
Construct an instance. Construct an instance.
...@@ -64,21 +64,29 @@ class Renderer(object): ...@@ -64,21 +64,29 @@ class Renderer(object):
escape function, for example. One may also wish to consider escape function, for example. One may also wish to consider
using markupsafe's escape function: markupsafe.escape(). using markupsafe's escape function: markupsafe.escape().
file_encoding: the name of the encoding of all template files.
This encoding is used when reading and converting any template
files to unicode. All templates are converted to unicode prior
to parsing. Defaults to the default_encoding argument.
default_encoding: the name of the encoding to use when converting default_encoding: the name of the encoding to use when converting
to unicode any strings of type `str` encountered during the to unicode any strings of type str encountered during the
rendering process. The name will be passed as the "encoding" rendering process. The name will be passed as the encoding
argument to the built-in function unicode(). Defaults to the argument to the built-in function unicode(). Defaults to the
encoding name returned by sys.getdefaultencoding(). encoding name returned by sys.getdefaultencoding().
decode_errors: the string to pass as the "errors" argument to the decode_errors: the string to pass as the errors argument to the
built-in function unicode() when converting to unicode any built-in function unicode() when converting to unicode any
strings of type `str` encountered during the rendering process. strings of type str encountered during the rendering process.
Defaults to "strict". Defaults to "strict".
""" """
if default_encoding is None: if default_encoding is None:
default_encoding = sys.getdefaultencoding() default_encoding = sys.getdefaultencoding()
if file_encoding is None:
file_encoding = default_encoding
if escape is None: if escape is None:
# The quote=True argument causes double quotes to be escaped, # The quote=True argument causes double quotes to be escaped,
# but not single quotes: # but not single quotes:
...@@ -92,6 +100,7 @@ class Renderer(object): ...@@ -92,6 +100,7 @@ class Renderer(object):
self.decode_errors = decode_errors self.decode_errors = decode_errors
self.default_encoding = default_encoding self.default_encoding = default_encoding
self.escape = escape self.escape = escape
self.file_encoding = file_encoding
self.loader = loader self.loader = loader
def _to_unicode_soft(self, s): def _to_unicode_soft(self, s):
...@@ -179,6 +188,28 @@ class Renderer(object): ...@@ -179,6 +188,28 @@ class Renderer(object):
escape=self._escape_to_unicode) escape=self._escape_to_unicode)
return engine return engine
def read(self, path):
"""
Read and return as a unicode string the file contents at path.
This class uses this method whenever it needs to read a template
file. This method uses the file_encoding and decode_errors
attributes.
"""
reader = Reader(encoding=self.file_encoding, decode_errors=self.decode_errors)
return reader.read(path)
def render_path(self, template_path, context=None, **kwargs):
"""
Render the template at the given path using the given context.
Read the render() docstring for more information.
"""
template = self.read(template_path)
return self.render(template, context, **kwargs)
def render(self, template, context=None, **kwargs): def render(self, template, context=None, **kwargs):
""" """
Render the given template using the given context. Render the given template using the given context.
......
# coding: utf-8
"""
Provides test-related code that can be used by all tests.
"""
import os
DATA_DIR = 'tests/data'
def get_data_path(file_name):
return os.path.join(DATA_DIR, file_name)
Hello {{to}}
\ No newline at end of file
...@@ -7,7 +7,7 @@ import unittest ...@@ -7,7 +7,7 @@ import unittest
from pystache.loader import Loader from pystache.loader import Loader
from pystache.reader import Reader from pystache.reader import Reader
DATA_DIR = 'tests/data' from .common import DATA_DIR
class LoaderTestCase(unittest.TestCase): class LoaderTestCase(unittest.TestCase):
......
...@@ -13,6 +13,7 @@ from pystache import renderer ...@@ -13,6 +13,7 @@ from pystache import renderer
from pystache.renderer import Renderer from pystache.renderer import Renderer
from pystache.loader import Loader from pystache.loader import Loader
from .common import get_data_path
class RendererInitTestCase(unittest.TestCase): class RendererInitTestCase(unittest.TestCase):
...@@ -110,6 +111,22 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -110,6 +111,22 @@ class RendererInitTestCase(unittest.TestCase):
renderer = Renderer(decode_errors="foo") renderer = Renderer(decode_errors="foo")
self.assertEquals(renderer.decode_errors, "foo") self.assertEquals(renderer.decode_errors, "foo")
def test_file_encoding__default(self):
"""
Check that file_encoding defaults to default_encoding.
"""
renderer = Renderer()
self.assertEquals(renderer.file_encoding, renderer.default_encoding)
def test_file_encoding(self):
"""
Check that the file_encoding attribute is set correctly.
"""
renderer = Renderer(file_encoding='foo')
self.assertEquals(renderer.file_encoding, 'foo')
class RendererTestCase(unittest.TestCase): class RendererTestCase(unittest.TestCase):
...@@ -150,6 +167,42 @@ class RendererTestCase(unittest.TestCase): ...@@ -150,6 +167,42 @@ class RendererTestCase(unittest.TestCase):
# U+FFFD is the official Unicode replacement character. # U+FFFD is the official Unicode replacement character.
self.assertEquals(renderer.unicode(s), u'd\ufffd\ufffdf') self.assertEquals(renderer.unicode(s), u'd\ufffd\ufffdf')
## Test the read() method.
def _read(self, renderer, filename):
path = get_data_path(filename)
return renderer.read(path)
def test_read(self):
renderer = Renderer()
actual = self._read(renderer, 'ascii.mustache')
self.assertEquals(actual, 'ascii: abc')
def test_read__returns_unicode(self):
renderer = Renderer()
actual = self._read(renderer, 'ascii.mustache')
self.assertEquals(type(actual), unicode)
def test_read__file_encoding(self):
filename = 'nonascii.mustache'
renderer = Renderer()
renderer.file_encoding = 'ascii'
self.assertRaises(UnicodeDecodeError, self._read, renderer, filename)
renderer.file_encoding = 'utf-8'
actual = self._read(renderer, filename)
self.assertEquals(actual, u'non-ascii: é')
def test_read__decode_errors(self):
filename = 'nonascii.mustache'
renderer = Renderer()
self.assertRaises(UnicodeDecodeError, self._read, renderer, filename)
renderer.decode_errors = 'ignore'
actual = self._read(renderer, filename)
self.assertEquals(actual, 'non-ascii: ')
## Test the render() method. ## Test the render() method.
def test_render__return_type(self): def test_render__return_type(self):
...@@ -267,6 +320,16 @@ class RendererTestCase(unittest.TestCase): ...@@ -267,6 +320,16 @@ class RendererTestCase(unittest.TestCase):
# TypeError: decoding Unicode is not supported # TypeError: decoding Unicode is not supported
self.assertEquals(load_partial("partial"), "foo") self.assertEquals(load_partial("partial"), "foo")
def test_render_path(self):
"""
Test the render_path() method.
"""
renderer = Renderer()
path = get_data_path('say_hello.mustache')
actual = renderer.render_path(path, to='world')
self.assertEquals(actual, "Hello world")
# By testing that Renderer.render() constructs the right RenderEngine, # By testing that Renderer.render() constructs the right RenderEngine,
# we no longer need to exercise all rendering code paths through # we no longer need to exercise all rendering code paths through
......
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