Commit 3f3f2a96 by Chris Jerdonek

Merge branch 'issue-102-support-python3' into 'development'

Still more work to do: about 14 failing tests and still need to wire up
the spec tests and README doctests.
parents 844ebdbc 642cade9
......@@ -51,8 +51,8 @@ Use It
::
>>> import pystache
>>> pystache.render('Hi {{person}}!', {'person': 'Mom'})
u'Hi Mom!'
>>> print pystache.render('Hi {{person}}!', {'person': 'Mom'})
Hi Mom!
You can also create dedicated view classes to hold your view logic.
......@@ -75,8 +75,8 @@ Then your template, say_hello.mustache::
Pull it together::
>>> renderer = pystache.Renderer()
>>> renderer.render(hello)
u'Hello, Pizza!'
>>> print renderer.render(hello)
Hello, Pizza!
Unicode Handling
......@@ -161,8 +161,8 @@ Author
::
>>> context = { 'author': 'Chris Wanstrath', 'email': 'chris@ozmm.org' }
>>> pystache.render("{{author}} :: {{email}}", context)
u'Chris Wanstrath :: chris@ozmm.org'
>>> print pystache.render("{{author}} :: {{email}}", context)
Chris Wanstrath :: chris@ozmm.org
.. _ctemplate: http://code.google.com/p/google-ctemplate/
......
# coding: utf-8
"""
Exposes common functions.
"""
# This function was designed to be portable across Python versions -- both
# with older versions and with Python 3 after applying 2to3.
def read(path):
"""
Return the contents of a text file as a byte string.
"""
# Opening in binary mode is necessary for compatibility across Python
# 2 and 3. In both Python 2 and 3, open() defaults to opening files in
# text mode. However, in Python 2, open() returns file objects whose
# read() method returns byte strings (strings of type `str` in Python 2),
# whereas in Python 3, the file object returns unicode strings (strings
# of type `str` in Python 3).
f = open(path, 'rb')
# We avoid use of the with keyword for Python 2.4 support.
try:
return f.read()
finally:
f.close()
......@@ -5,11 +5,16 @@ Defines a Context class to represent mustache(5)'s notion of context.
"""
class NotFound(object): pass
# This equals '__builtin__' in Python 2 and 'builtins' in Python 3.
_BUILTIN_MODULE = type(0).__module__
# We use this private global variable as a return value to represent a key
# not being found on lookup. This lets us distinguish between the case
# of a key's value being None with the case of a key not being found --
# without having to rely on exceptions (e.g. KeyError) for flow control.
class NotFound(object):
pass
_NOT_FOUND = NotFound()
......@@ -34,7 +39,7 @@ def _get_value(item, key):
# (e.g. catching KeyError).
if key in item:
return item[key]
elif type(item).__module__ != '__builtin__':
elif type(item).__module__ != _BUILTIN_MODULE:
# Then we consider the argument an "object" for the purposes of
# the spec.
#
......
......@@ -8,7 +8,12 @@ does not otherwise specify a value.
"""
import cgi
try:
# Python 3.2 deprecates cgi.escape() and adds the html module as a replacement.
import html
except ImportError:
import cgi as html
import os
import sys
......@@ -39,12 +44,14 @@ SEARCH_DIRS = [os.curdir] # i.e. ['.']
# rendering templates (e.g. for tags enclosed in double braces).
# Only unicode strings will be passed to this function.
#
# The quote=True argument causes double quotes to be escaped,
# but not single quotes:
# The quote=True argument causes double quotes to be escaped in Python 2,
# but not single quotes, and both double quotes and single quotes to be
# escaped in Python 3:
#
# http://docs.python.org/dev/library/html.html#html.escape
# http://docs.python.org/library/cgi.html#cgi.escape
#
TAG_ESCAPE = lambda u: cgi.escape(u, quote=True)
TAG_ESCAPE = lambda u: html.escape(u, quote=True)
# The default template extension.
TEMPLATE_EXTENSION = 'mustache'
......@@ -8,6 +8,7 @@ This module provides a Loader class for locating and reading templates.
import os
import sys
from pystache import common
from pystache import defaults
from pystache.locator import Locator
......@@ -106,17 +107,12 @@ class Loader(object):
Read the template at the given path, and return it as a unicode string.
"""
# We avoid use of the with keyword for Python 2.4 support.
f = open(path, 'r')
try:
text = f.read()
finally:
f.close()
b = common.read(path)
if encoding is None:
encoding = self.file_encoding
return self.unicode(text, encoding)
return self.unicode(b, encoding)
# TODO: unit-test this method.
def load_name(self, name):
......
......@@ -131,7 +131,7 @@ class Parser(object):
if tag_type == '/':
if tag_key != section_key:
raise ParsingError("Section end tag mismatch: %s != %s" % (repr(tag_key), repr(section_key)))
raise ParsingError("Section end tag mismatch: %s != %s" % (tag_key, section_key))
return ParsedTemplate(parse_tree), template[start_index:match_index], end_index
......
......@@ -55,7 +55,7 @@ class RenderEngine(object):
this class will not pass tag values to literal prior to passing
them to this function. This allows for more flexibility,
for example using a custom escape function that handles
incoming strings of type markupssafe.Markup differently
incoming strings of type markupsafe.Markup differently
from plain unicode strings.
"""
......@@ -167,9 +167,28 @@ class RenderEngine(object):
# TODO: should we check the arity?
template = data(template)
parsed_template = self._parse(template, delimiters=delims)
data = [ data ]
elif not hasattr(data, '__iter__') or isinstance(data, dict):
data = [ data ]
data = [data]
else:
# The cleanest, least brittle way of determining whether
# something supports iteration is by trying to call iter() on it:
#
# http://docs.python.org/library/functions.html#iter
#
# It is not sufficient, for example, to check whether the item
# implements __iter__ () (the iteration protocol). There is
# also __getitem__() (the sequence protocol). In Python 2,
# strings do not implement __iter__(), but in Python 3 they do.
try:
iter(data)
except TypeError:
# Then the value does not support iteration.
data = [data]
else:
# We treat the value as a list (but do not treat strings
# and dicts as lists).
if isinstance(data, (basestring, dict)):
data = [data]
# Otherwise, leave it alone.
parts = []
for element in data:
......
......@@ -9,7 +9,7 @@ from pystache import defaults
from pystache.context import Context
from pystache.loader import Loader
from pystache.renderengine import RenderEngine
from pystache.spec_loader import SpecLoader
from pystache.specloader import SpecLoader
from pystache.template_spec import TemplateSpec
......@@ -64,10 +64,10 @@ class Renderer(object):
this class will only pass it unicode strings. The constructor
assigns this function to the constructed instance's escape()
method.
The argument defaults to `cgi.escape(s, quote=True)`. To
disable escaping entirely, one can pass `lambda u: u` as the
escape function, for example. One may also wish to consider
using markupsafe's escape function: markupsafe.escape().
To disable escaping entirely, one can pass `lambda u: u`
as the escape function, for example. One may also wish to
consider using markupsafe's escape function: markupsafe.escape().
This argument defaults to the package default.
file_encoding: the name of the default encoding to use when reading
template files. All templates are converted to unicode prior
......@@ -160,9 +160,16 @@ class Renderer(object):
"""
return unicode(self.escape(self._to_unicode_soft(s)))
def unicode(self, s, encoding=None):
def unicode(self, b, encoding=None):
"""
Convert a string to unicode, using string_encoding and decode_errors.
Convert a byte string to unicode, using string_encoding and decode_errors.
Arguments:
b: a byte string.
encoding: the name of an encoding. Defaults to the string_encoding
attribute for this instance.
Raises:
......@@ -178,7 +185,7 @@ class Renderer(object):
# TODO: Wrap UnicodeDecodeErrors with a message about setting
# the string_encoding and decode_errors attributes.
return unicode(s, encoding, self.decode_errors)
return unicode(b, encoding, self.decode_errors)
def _make_loader(self):
"""
......
......@@ -55,10 +55,10 @@ class AssertStringMixin:
description = details % reason
return format % description
self.assertEquals(actual, expected, make_message("different characters"))
self.assertEqual(actual, expected, make_message("different characters"))
reason = "types different: %s != %s (actual)" % (repr(type(expected)), repr(type(actual)))
self.assertEquals(type(expected), type(actual), make_message(reason))
self.assertEqual(type(expected), type(actual), make_message(reason))
class AssertIsMixin:
......
......@@ -39,7 +39,7 @@ class CommandsTestCase(unittest.TestCase):
"""
actual = self.callScript("Hi {{thing}}", '{"thing": "world"}')
self.assertEquals(actual, u"Hi world\n")
self.assertEqual(actual, u"Hi world\n")
def tearDown(self):
sys.stdout = ORIGINAL_STDOUT
......@@ -95,7 +95,7 @@ Again, Welcome!""")
view.template = '''{{>partial_in_partial}}'''
actual = renderer.render(view, {'prop': 'derp'})
self.assertEquals(actual, 'Hi derp!')
self.assertEqual(actual, 'Hi derp!')
if __name__ == '__main__':
unittest.main()
......@@ -18,30 +18,30 @@ class LoaderTests(unittest.TestCase, AssertStringMixin):
def test_init__extension(self):
loader = Loader(extension='foo')
self.assertEquals(loader.extension, 'foo')
self.assertEqual(loader.extension, 'foo')
def test_init__extension__default(self):
# Test the default value.
loader = Loader()
self.assertEquals(loader.extension, 'mustache')
self.assertEqual(loader.extension, 'mustache')
def test_init__file_encoding(self):
loader = Loader(file_encoding='bar')
self.assertEquals(loader.file_encoding, 'bar')
self.assertEqual(loader.file_encoding, 'bar')
def test_init__file_encoding__default(self):
file_encoding = defaults.FILE_ENCODING
try:
defaults.FILE_ENCODING = 'foo'
loader = Loader()
self.assertEquals(loader.file_encoding, 'foo')
self.assertEqual(loader.file_encoding, 'foo')
finally:
defaults.FILE_ENCODING = file_encoding
def test_init__to_unicode(self):
to_unicode = lambda x: x
loader = Loader(to_unicode=to_unicode)
self.assertEquals(loader.to_unicode, to_unicode)
self.assertEqual(loader.to_unicode, to_unicode)
def test_init__to_unicode__default(self):
loader = Loader()
......
......@@ -26,10 +26,10 @@ class LocatorTests(unittest.TestCase):
def test_init__extension(self):
# Test the default value.
locator = Locator()
self.assertEquals(locator.template_extension, 'mustache')
self.assertEqual(locator.template_extension, 'mustache')
locator = Locator(extension='txt')
self.assertEquals(locator.template_extension, 'txt')
self.assertEqual(locator.template_extension, 'txt')
locator = Locator(extension=False)
self.assertTrue(locator.template_extension is False)
......@@ -40,40 +40,40 @@ class LocatorTests(unittest.TestCase):
obj = SayHello()
actual = locator.get_object_directory(obj)
self.assertEquals(actual, os.path.abspath(DATA_DIR))
self.assertEqual(actual, os.path.abspath(DATA_DIR))
def test_get_object_directory__not_hasattr_module(self):
locator = Locator()
obj = datetime(2000, 1, 1)
self.assertFalse(hasattr(obj, '__module__'))
self.assertEquals(locator.get_object_directory(obj), None)
self.assertEqual(locator.get_object_directory(obj), None)
self.assertFalse(hasattr(None, '__module__'))
self.assertEquals(locator.get_object_directory(None), None)
self.assertEqual(locator.get_object_directory(None), None)
def test_make_file_name(self):
locator = Locator()
locator.template_extension = 'bar'
self.assertEquals(locator.make_file_name('foo'), 'foo.bar')
self.assertEqual(locator.make_file_name('foo'), 'foo.bar')
locator.template_extension = False
self.assertEquals(locator.make_file_name('foo'), 'foo')
self.assertEqual(locator.make_file_name('foo'), 'foo')
locator.template_extension = ''
self.assertEquals(locator.make_file_name('foo'), 'foo.')
self.assertEqual(locator.make_file_name('foo'), 'foo.')
def test_make_file_name__template_extension_argument(self):
locator = Locator()
self.assertEquals(locator.make_file_name('foo', template_extension='bar'), 'foo.bar')
self.assertEqual(locator.make_file_name('foo', template_extension='bar'), 'foo.bar')
def test_find_name(self):
locator = Locator()
path = locator.find_name(search_dirs=['examples'], template_name='simple')
self.assertEquals(os.path.basename(path), 'simple.mustache')
self.assertEqual(os.path.basename(path), 'simple.mustache')
def test_find_name__using_list_of_paths(self):
locator = Locator()
......@@ -98,7 +98,7 @@ class LocatorTests(unittest.TestCase):
dirpath = os.path.dirname(path)
dirname = os.path.split(dirpath)[-1]
self.assertEquals(dirname, 'locator')
self.assertEqual(dirname, 'locator')
def test_find_name__non_existent_template_fails(self):
locator = Locator()
......@@ -113,7 +113,7 @@ class LocatorTests(unittest.TestCase):
actual = locator.find_object(search_dirs=[], obj=obj, file_name='sample_view.mustache')
expected = os.path.abspath(os.path.join(DATA_DIR, 'sample_view.mustache'))
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def test_find_object__none_file_name(self):
locator = Locator()
......@@ -123,18 +123,18 @@ class LocatorTests(unittest.TestCase):
actual = locator.find_object(search_dirs=[], obj=obj)
expected = os.path.abspath(os.path.join(DATA_DIR, 'say_hello.mustache'))
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def test_find_object__none_object_directory(self):
locator = Locator()
obj = None
self.assertEquals(None, locator.get_object_directory(obj))
self.assertEqual(None, locator.get_object_directory(obj))
actual = locator.find_object(search_dirs=[DATA_DIR], obj=obj, file_name='say_hello.mustache')
expected = os.path.join(DATA_DIR, 'say_hello.mustache')
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def test_make_template_name(self):
"""
......@@ -147,4 +147,4 @@ class LocatorTests(unittest.TestCase):
pass
foo = FooBar()
self.assertEquals(locator.make_template_name(foo), 'foo_bar')
self.assertEqual(locator.make_template_name(foo), 'foo_bar')
......@@ -9,6 +9,7 @@ Creates a unittest.TestCase for the tests defined in the mustache spec.
FILE_ENCODING = 'utf-8' # the encoding of the spec test files.
yaml = None
try:
# We try yaml first since it is more convenient when adding and modifying
......@@ -31,28 +32,28 @@ else:
parser = yaml
import codecs
import glob
import os.path
import unittest
import pystache
from pystache import common
from pystache.renderer import Renderer
from pystache.tests.common import AssertStringMixin, SPEC_TEST_DIR
spec_paths = glob.glob(os.path.join(SPEC_TEST_DIR, '*.%s' % file_extension))
def parse(u, file_extension):
def parse(u):
"""
Parse
Arguments:
u: a unicode string.
"""
# TODO: find a cleaner mechanism for choosing between the two.
if file_extension[0] == 'j':
# Then json.
if yaml is None:
# Then use json.
# The only way to get the simplejson module to return unicode strings
# is to pass it unicode. See, for example--
......@@ -156,20 +157,14 @@ def buildTest(testData, spec_filename, parser):
return test
for spec_path in spec_paths:
file_name = os.path.basename(spec_path)
spec_paths = glob.glob(os.path.join(SPEC_TEST_DIR, '*.%s' % file_extension))
for path in spec_paths:
# We avoid use of the with keyword for Python 2.4 support.
# TODO: share code here with pystache's open() code.
f = open(spec_path, 'r')
try:
s = f.read()
finally:
f.close()
file_name = os.path.basename(path)
u = s.decode(FILE_ENCODING)
spec_data = parse(u, file_extension)
b = common.read(path)
u = unicode(b, encoding=FILE_ENCODING)
spec_data = parse(u)
tests = spec_data['tests']
......
......@@ -9,15 +9,15 @@ class PystacheTests(unittest.TestCase):
def _assert_rendered(self, expected, template, context):
actual = pystache.render(template, context)
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def test_basic(self):
ret = pystache.render("Hi {{thing}}!", { 'thing': 'world' })
self.assertEquals(ret, "Hi world!")
self.assertEqual(ret, "Hi world!")
def test_kwargs(self):
ret = pystache.render("Hi {{thing}}!", thing='world')
self.assertEquals(ret, "Hi world!")
self.assertEqual(ret, "Hi world!")
def test_less_basic(self):
template = "It's a nice day for {{beverage}}, right {{person}}?"
......@@ -42,7 +42,7 @@ class PystacheTests(unittest.TestCase):
def test_comments(self):
template = "What {{! the }} what?"
actual = pystache.render(template)
self.assertEquals("What what?", actual)
self.assertEqual("What what?", actual)
def test_false_sections_are_hidden(self):
template = "Ready {{#set}}set {{/set}}go!"
......
......@@ -5,10 +5,10 @@ Unit tests of renderengine.py.
"""
import cgi
import unittest
from pystache.context import Context
from pystache import defaults
from pystache.parser import ParsingError
from pystache.renderengine import RenderEngine
from pystache.tests.common import AssertStringMixin
......@@ -26,9 +26,9 @@ class RenderEngineTestCase(unittest.TestCase):
# In real-life, these arguments would be functions
engine = RenderEngine(load_partial="foo", literal="literal", escape="escape")
self.assertEquals(engine.escape, "escape")
self.assertEquals(engine.literal, "literal")
self.assertEquals(engine.load_partial, "foo")
self.assertEqual(engine.escape, "escape")
self.assertEqual(engine.literal, "literal")
self.assertEqual(engine.load_partial, "foo")
class RenderTests(unittest.TestCase, AssertStringMixin):
......@@ -47,7 +47,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
Create and return a default RenderEngine for testing.
"""
escape = lambda s: unicode(cgi.escape(s))
escape = defaults.TAG_ESCAPE
engine = RenderEngine(literal=unicode, escape=escape, load_partial=None)
return engine
......@@ -230,7 +230,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
#
# we need to resort to built-in attributes (double-underscored) on
# the integer type.
self._assert_builtin_type(15, '__hex__', '0xf', u'999')
self._assert_builtin_type(15, '__neg__', -15, u'999')
def test_interpolation__built_in_type__list(self):
"""
......@@ -315,7 +315,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
try:
self._assert_render(None, template)
except ParsingError, err:
self.assertEquals(str(err), "Section end tag mismatch: u'section' != None")
self.assertEqual(str(err), "Section end tag mismatch: section != None")
def test_section__end_tag_mismatch(self):
"""
......@@ -326,7 +326,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
try:
self._assert_render(None, template)
except ParsingError, err:
self.assertEquals(str(err), "Section end tag mismatch: u'section_end' != u'section_start'")
self.assertEqual(str(err), "Section end tag mismatch: section_end != section_start")
def test_section__context_values(self):
"""
......
......@@ -28,11 +28,11 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
renderer = Renderer()
actual = renderer.render(template, context)
self.assertEquals(actual, "Colors: red Colors: green Colors: blue ")
self.assertEqual(actual, "Colors: red Colors: green Colors: blue ")
def test_empty_context(self):
template = '{{#empty_list}}Shouldnt see me {{/empty_list}}{{^empty_list}}Should see me{{/empty_list}}'
self.assertEquals(pystache.Renderer().render(template), "Should see me")
self.assertEqual(pystache.Renderer().render(template), "Should see me")
def test_callables(self):
view = Lambdas()
......@@ -58,7 +58,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
def test_non_existent_value_renders_blank(self):
view = Simple()
template = '{{not_set}} {{blank}}'
self.assertEquals(pystache.Renderer().render(template), ' ')
self.assertEqual(pystache.Renderer().render(template), ' ')
def test_template_partial_extension(self):
......
......@@ -18,7 +18,7 @@ from pystache import Renderer
from pystache import TemplateSpec
from pystache.locator import Locator
from pystache.loader import Loader
from pystache.spec_loader import SpecLoader
from pystache.specloader import SpecLoader
from pystache.tests.common import DATA_DIR
from pystache.tests.common import EXAMPLES_DIR
from pystache.tests.common import AssertIsMixin
......@@ -49,7 +49,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
# TODO: change this test to remove the following brittle line.
view.template_rel_directory = "../../examples"
actual = renderer.render(view)
self.assertEquals(actual, "No tags...")
self.assertEqual(actual, "No tags...")
def test_template_path_for_partials(self):
"""
......@@ -65,7 +65,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
self.assertRaises(IOError, renderer1.render, spec)
actual = renderer2.render(spec)
self.assertEquals(actual, "Partial: No tags...")
self.assertEqual(actual, "Partial: No tags...")
def test_basic_method_calls(self):
renderer = Renderer()
......@@ -79,7 +79,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
renderer = Renderer()
actual = renderer.render(view)
self.assertEquals(actual, "Hi Chris!")
self.assertEqual(actual, "Hi Chris!")
def test_complex(self):
renderer = Renderer()
......@@ -95,7 +95,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
def test_higher_order_replace(self):
renderer = Renderer()
actual = renderer.render(Lambdas())
self.assertEquals(actual, 'bar != bar. oh, it does!')
self.assertEqual(actual, 'bar != bar. oh, it does!')
def test_higher_order_rot13(self):
view = Lambdas()
......@@ -119,7 +119,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
renderer = Renderer(search_dirs=EXAMPLES_DIR)
actual = renderer.render(view)
self.assertEquals(actual, u'nopqrstuvwxyz')
self.assertEqual(actual, u'nopqrstuvwxyz')
def test_hierarchical_partials_with_lambdas(self):
view = Lambdas()
......@@ -152,6 +152,28 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
self.assertString(actual, u"""one, two, three, empty list""")
def _make_specloader():
"""
Return a default SpecLoader instance for testing purposes.
"""
# Python 2 and 3 have different default encodings. Thus, to have
# consistent test results across both versions, we need to specify
# the string and file encodings explicitly rather than relying on
# the defaults.
def to_unicode(s, encoding=None):
"""
Raises a TypeError exception if the given string is already unicode.
"""
if encoding is None:
encoding = 'ascii'
return unicode(s, encoding, 'strict')
loader = Loader(file_encoding='ascii', to_unicode=to_unicode)
return SpecLoader(loader=loader)
class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
"""
......@@ -159,13 +181,16 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
"""
def _make_specloader(self):
return _make_specloader()
def test_init__defaults(self):
custom = SpecLoader()
spec_loader = SpecLoader()
# Check the loader attribute.
loader = custom.loader
self.assertEquals(loader.extension, 'mustache')
self.assertEquals(loader.file_encoding, sys.getdefaultencoding())
loader = spec_loader.loader
self.assertEqual(loader.extension, 'mustache')
self.assertEqual(loader.file_encoding, sys.getdefaultencoding())
# TODO: finish testing the other Loader attributes.
to_unicode = loader.to_unicode
......@@ -187,7 +212,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec()
custom.template = "abc"
self._assert_template(SpecLoader(), custom, u"abc")
spec_loader = self._make_specloader()
self._assert_template(spec_loader, custom, u"abc")
def test_load__template__type_unicode(self):
"""
......@@ -197,7 +223,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec()
custom.template = u"abc"
self._assert_template(SpecLoader(), custom, u"abc")
spec_loader = self._make_specloader()
self._assert_template(spec_loader, custom, u"abc")
def test_load__template__unicode_non_ascii(self):
"""
......@@ -207,7 +234,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec()
custom.template = u"é"
self._assert_template(SpecLoader(), custom, u"é")
spec_loader = self._make_specloader()
self._assert_template(spec_loader, custom, u"é")
def test_load__template__with_template_encoding(self):
"""
......@@ -217,10 +245,12 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec()
custom.template = u'é'.encode('utf-8')
self.assertRaises(UnicodeDecodeError, self._assert_template, SpecLoader(), custom, u'é')
spec_loader = self._make_specloader()
self.assertRaises(UnicodeDecodeError, self._assert_template, spec_loader, custom, u'é')
custom.template_encoding = 'utf-8'
self._assert_template(SpecLoader(), custom, u'é')
self._assert_template(spec_loader, custom, u'é')
# TODO: make this test complete.
def test_load__template__correct_loader(self):
......@@ -255,8 +285,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
# Check that our unicode() above was called.
self._assert_template(custom_loader, view, u'foo')
self.assertEquals(loader.s, "template-foo")
self.assertEquals(loader.encoding, "encoding-foo")
self.assertEqual(loader.s, "template-foo")
self.assertEqual(loader.encoding, "encoding-foo")
# TODO: migrate these tests into the SpecLoaderTests class.
......@@ -266,14 +296,13 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
# TemplateSpec attributes or something).
class TemplateSpecTests(unittest.TestCase):
# TODO: rename this method to _make_loader().
def _make_locator(self):
return SpecLoader()
def _make_loader(self):
return _make_specloader()
def _assert_template_location(self, view, expected):
locator = self._make_locator()
actual = locator._find_relative(view)
self.assertEquals(actual, expected)
loader = self._make_loader()
actual = loader._find_relative(view)
self.assertEqual(actual, expected)
def test_find_relative(self):
"""
......@@ -334,38 +363,38 @@ class TemplateSpecTests(unittest.TestCase):
Test _find() with a view that has a directory specified.
"""
locator = self._make_locator()
loader = self._make_loader()
view = SampleView()
view.template_rel_path = 'foo/bar.txt'
self.assertTrue(locator._find_relative(view)[0] is not None)
self.assertTrue(loader._find_relative(view)[0] is not None)
actual = locator._find(view)
actual = loader._find(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'foo/bar.txt'))
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def test_find__without_directory(self):
"""
Test _find() with a view that doesn't have a directory specified.
"""
locator = self._make_locator()
loader = self._make_loader()
view = SampleView()
self.assertTrue(locator._find_relative(view)[0] is None)
self.assertTrue(loader._find_relative(view)[0] is None)
actual = locator._find(view)
actual = loader._find(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'sample_view.mustache'))
self.assertEquals(actual, expected)
self.assertEqual(actual, expected)
def _assert_get_template(self, custom, expected):
locator = self._make_locator()
actual = locator.load(custom)
loader = self._make_loader()
actual = loader.load(custom)
self.assertEquals(type(actual), unicode)
self.assertEquals(actual, expected)
self.assertEqual(type(actual), unicode)
self.assertEqual(actual, expected)
def test_get_template(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