diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2012-03-28 20:42:23 -0700 |
---|---|---|
committer | Chris Jerdonek <chris.jerdonek@gmail.com> | 2012-03-28 20:42:23 -0700 |
commit | 80dd7698985949c0bb9e7995bfb5389f0328531d (patch) | |
tree | db20c1817e644ebc06c108ffe642075d13310938 | |
parent | c756f24366f4365d4ee6a7c39d00423f4f188d8e (diff) | |
download | pystache-80dd7698985949c0bb9e7995bfb5389f0328531d.tar.gz |
Simplified Renderer class: Renderer now uses new Loader class.
-rw-r--r-- | pystache/loader.py | 24 | ||||
-rw-r--r-- | pystache/renderer.py | 67 | ||||
-rw-r--r-- | tests/test_loader.py | 65 | ||||
-rw-r--r-- | tests/test_renderer.py | 73 |
4 files changed, 88 insertions, 141 deletions
diff --git a/pystache/loader.py b/pystache/loader.py index 968f1bd..706a2f7 100644 --- a/pystache/loader.py +++ b/pystache/loader.py @@ -11,6 +11,7 @@ import os import sys from . import defaults +from .locator import Locator class Loader(object): @@ -78,3 +79,26 @@ class Loader(object): text = f.read() return self.unicode(text, encoding) + + def load(self, obj, search_dirs): + """ + Find and return the template associated to the given object. + + Arguments: + + obj: a string or object instance. If obj is a string, then obj + will be interpreted as the template name. Otherwise, obj will + be interpreted as an instance of a user-defined class. + + search_dirs: the list of directories in which to search for + templates when loading a template by name. + + """ + locator = Locator(extension=self.extension) + + if isinstance(obj, basestring): + path = locator.find_path_by_name(search_dirs, obj) + else: + path = locator.find_path_by_object(search_dirs, obj) + + return self.read(path) diff --git a/pystache/renderer.py b/pystache/renderer.py index ece6d0e..adbac3e 100644 --- a/pystache/renderer.py +++ b/pystache/renderer.py @@ -11,9 +11,7 @@ import sys from . import defaults from .context import Context -# TODO: remove this alias. -from .loader import Loader as Reader -from .locator import Locator +from .loader import Loader from .renderengine import RenderEngine @@ -43,7 +41,7 @@ class Renderer(object): """ def __init__(self, file_encoding=None, default_encoding=None, - decode_errors='strict', search_dirs=None, file_extension=None, + decode_errors=None, search_dirs=None, file_extension=None, escape=None, partials=None): """ Construct an instance. @@ -87,9 +85,8 @@ class Renderer(object): encoding name returned by sys.getdefaultencoding(). decode_errors: the string to pass as the errors argument to the - built-in function unicode() when converting to unicode any - strings of type str encountered during the rendering process. - Defaults to "strict". + built-in function unicode() when converting str strings to + unicode. Defaults to the package default. search_dirs: the list of directories in which to search for templates when loading a template by name. Defaults to the @@ -101,6 +98,9 @@ class Renderer(object): Defaults to the package default. """ + if decode_errors is None: + decode_errors = defaults.DECODE_ERRORS + if default_encoding is None: default_encoding = sys.getdefaultencoding() @@ -169,32 +169,23 @@ class Renderer(object): # the default_encoding and decode_errors attributes. return unicode(s, self.default_encoding, self.decode_errors) - def _make_reader(self): - """ - Create a Reader instance using current attributes. - - """ - return Reader(encoding=self.file_encoding, decode_errors=self.decode_errors) - - def make_locator(self): + def _make_loader(self): """ - Create a Locator instance using current attributes. + Create a Loader instance using current attributes. """ - return Locator(extension=self.file_extension) + return Loader(encoding=self.file_encoding, decode_errors=self.decode_errors, + extension=self.file_extension) def _make_load_template(self): """ Return a function that loads a template by name. """ - reader = self._make_reader() - locator = self.make_locator() + loader = self._make_loader() def load_template(template_name): - template_path = locator.find_path_by_name(self.search_dirs, template_name) - - return reader.read(template_path) + return loader.load(template_name, self.search_dirs) return load_template @@ -237,18 +228,6 @@ class Renderer(object): escape=self._escape_to_unicode) 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 = self._make_reader() - return reader.read(path) - # TODO: add unit tests for this method. def load_template(self, template_name): """ @@ -258,19 +237,6 @@ class Renderer(object): load_template = self._make_load_template() return load_template(template_name) - def get_associated_template(self, obj): - """ - Find and return the template associated with an object. - - The function first searches the directory containing the object's - class definition. - - """ - locator = self.make_locator() - template_path = locator.find_path_by_object(self.search_dirs, obj) - - return self.read(template_path) - def _render_string(self, template, *context, **kwargs): """ Render the given template string using the given context. @@ -291,8 +257,10 @@ class Renderer(object): Render the template associated with the given object. """ + loader = self._make_loader() + template = loader.load(obj, self.search_dirs) + context = [obj] + list(context) - template = self.get_associated_template(obj) return self._render_string(template, *context, **kwargs) @@ -303,7 +271,8 @@ class Renderer(object): Read the render() docstring for more information. """ - template = self.read(template_path) + loader = self._make_loader() + template = loader.read(template_path) return self._render_string(template, *context, **kwargs) diff --git a/tests/test_loader.py b/tests/test_loader.py index 5e02058..1836466 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -10,40 +10,39 @@ import sys import unittest from .common import AssertStringMixin -# TODO: remove this alias. -from pystache.loader import Loader as Reader +from pystache.loader import Loader DATA_DIR = 'tests/data' -class ReaderTestCase(unittest.TestCase, AssertStringMixin): +class LoaderTestCase(unittest.TestCase, AssertStringMixin): def _get_path(self, filename): return os.path.join(DATA_DIR, filename) def test_init__decode_errors(self): # Test the default value. - reader = Reader() + reader = Loader() self.assertEquals(reader.decode_errors, 'strict') - reader = Reader(decode_errors='replace') + reader = Loader(decode_errors='replace') self.assertEquals(reader.decode_errors, 'replace') def test_init__encoding(self): # Test the default value. - reader = Reader() + reader = Loader() self.assertEquals(reader.encoding, sys.getdefaultencoding()) - reader = Reader(encoding='foo') + reader = Loader(encoding='foo') self.assertEquals(reader.encoding, 'foo') def test_init__extension(self): # Test the default value. - reader = Reader() + reader = Loader() self.assertEquals(reader.extension, 'mustache') - reader = Reader(extension='foo') + reader = Loader(extension='foo') self.assertEquals(reader.extension, 'foo') def test_unicode__basic__input_str(self): @@ -51,7 +50,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin): Test unicode(): default arguments with str input. """ - reader = Reader() + reader = Loader() actual = reader.unicode("foo") self.assertString(actual, u"foo") @@ -61,7 +60,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin): Test unicode(): default arguments with unicode input. """ - reader = Reader() + reader = Loader() actual = reader.unicode(u"foo") self.assertString(actual, u"foo") @@ -76,7 +75,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin): s = UnicodeSubclass(u"foo") - reader = Reader() + reader = Loader() actual = reader.unicode(s) self.assertString(actual, u"foo") @@ -86,7 +85,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin): Test unicode(): encoding attribute. """ - reader = Reader() + reader = Loader() non_ascii = u'é'.encode('utf-8') @@ -100,65 +99,63 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin): Test unicode(): encoding argument. """ - reader = Reader() + reader = Loader() non_ascii = u'é'.encode('utf-8') self.assertRaises(UnicodeDecodeError, reader.unicode, non_ascii) - self.assertEquals(reader.unicode(non_ascii, encoding='utf-8'), u'é') + actual = reader.unicode(non_ascii, encoding='utf-8') + self.assertEquals(actual, u'é') def test_read(self): """ Test read(). """ - reader = Reader() + reader = Loader() path = self._get_path('ascii.mustache') - self.assertEquals(reader.read(path), 'ascii: abc') - - def test_read__returns_unicode(self): - """ - Test that read() returns unicode strings. - - """ - reader = Reader() - path = self._get_path('ascii.mustache') - contents = reader.read(path) - self.assertEqual(type(contents), unicode) + actual = reader.read(path) + self.assertString(actual, u'ascii: abc') def test_read__encoding__attribute(self): """ Test read(): encoding attribute respected. """ - reader = Reader() + reader = Loader() path = self._get_path('non_ascii.mustache') self.assertRaises(UnicodeDecodeError, reader.read, path) + reader.encoding = 'utf-8' - self.assertEquals(reader.read(path), u'non-ascii: é') + actual = reader.read(path) + self.assertString(actual, u'non-ascii: é') def test_read__encoding__argument(self): """ Test read(): encoding argument respected. """ - reader = Reader() + reader = Loader() path = self._get_path('non_ascii.mustache') self.assertRaises(UnicodeDecodeError, reader.read, path) - self.assertEquals(reader.read(path, encoding='utf-8'), u'non-ascii: é') + + actual = reader.read(path, encoding='utf-8') + self.assertString(actual, u'non-ascii: é') def test_get__decode_errors(self): """ Test get(): decode_errors attribute. """ - reader = Reader() + reader = Loader() path = self._get_path('non_ascii.mustache') self.assertRaises(UnicodeDecodeError, reader.read, path) - reader.decode_errors = 'replace' - self.assertEquals(reader.read(path), u'non-ascii: \ufffd\ufffd') + + reader.decode_errors = 'ignore' + actual = reader.read(path) + self.assertString(actual, u'non-ascii: ') diff --git a/tests/test_renderer.py b/tests/test_renderer.py index 7a9b7cf..5c702d3 100644 --- a/tests/test_renderer.py +++ b/tests/test_renderer.py @@ -12,7 +12,7 @@ import unittest from examples.simple import Simple from pystache.renderer import Renderer -from pystache.locator import Locator +from pystache.loader import Loader from .common import get_data_path from .data.views import SayHello @@ -182,76 +182,33 @@ class RendererTestCase(unittest.TestCase): # U+FFFD is the official Unicode replacement character. self.assertEquals(renderer.unicode(s), u'd\ufffd\ufffdf') - ## Test the read() method. + ## Test the _make_loader() 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 = 'non_ascii.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 = 'non_ascii.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 make_locator() method. - - def test_make_locator__return_type(self): + def test__make_loader__return_type(self): """ - Test that make_locator() returns a Locator. + Test that _make_loader() returns a Loader. """ renderer = Renderer() - locator = renderer.make_locator() + loader = renderer._make_loader() - self.assertEquals(type(locator), Locator) + self.assertEquals(type(loader), Loader) - def test_make_locator__file_extension(self): + def test__make_loader__attributes(self): """ - Test that make_locator() respects the file_extension attribute. + Test that _make_locator() sets all attributes correctly.. """ renderer = Renderer() - renderer.file_extension = 'foo' - - locator = renderer.make_locator() - - self.assertEquals(locator.template_extension, 'foo') - - # This test is a sanity check. Strictly speaking, it shouldn't - # be necessary based on our tests above. - def test_make_locator__default(self): - renderer = Renderer() - actual = renderer.make_locator() + renderer.decode_errors = 'dec' + renderer.file_encoding = 'enc' + renderer.file_extension = 'ext' - expected = Locator() + loader = renderer._make_loader() - self.assertEquals(type(actual), type(expected)) - self.assertEquals(actual.template_extension, expected.template_extension) + self.assertEquals(loader.decode_errors, 'dec') + self.assertEquals(loader.encoding, 'enc') + self.assertEquals(loader.extension, 'ext') ## Test the render() method. |