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 ...@@ -51,8 +51,8 @@ Use It
:: ::
>>> import pystache >>> import pystache
>>> pystache.render('Hi {{person}}!', {'person': 'Mom'}) >>> print pystache.render('Hi {{person}}!', {'person': 'Mom'})
u'Hi Mom!' Hi Mom!
You can also create dedicated view classes to hold your view logic. You can also create dedicated view classes to hold your view logic.
...@@ -75,8 +75,8 @@ Then your template, say_hello.mustache:: ...@@ -75,8 +75,8 @@ Then your template, say_hello.mustache::
Pull it together:: Pull it together::
>>> renderer = pystache.Renderer() >>> renderer = pystache.Renderer()
>>> renderer.render(hello) >>> print renderer.render(hello)
u'Hello, Pizza!' Hello, Pizza!
Unicode Handling Unicode Handling
...@@ -161,8 +161,8 @@ Author ...@@ -161,8 +161,8 @@ Author
:: ::
>>> context = { 'author': 'Chris Wanstrath', 'email': 'chris@ozmm.org' } >>> context = { 'author': 'Chris Wanstrath', 'email': 'chris@ozmm.org' }
>>> pystache.render("{{author}} :: {{email}}", context) >>> print pystache.render("{{author}} :: {{email}}", context)
u'Chris Wanstrath :: chris@ozmm.org' Chris Wanstrath :: chris@ozmm.org
.. _ctemplate: http://code.google.com/p/google-ctemplate/ .. _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. ...@@ -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 # 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 # 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 -- # 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. # without having to rely on exceptions (e.g. KeyError) for flow control.
class NotFound(object):
pass
_NOT_FOUND = NotFound() _NOT_FOUND = NotFound()
...@@ -34,7 +39,7 @@ def _get_value(item, key): ...@@ -34,7 +39,7 @@ def _get_value(item, key):
# (e.g. catching KeyError). # (e.g. catching KeyError).
if key in item: if key in item:
return item[key] 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 # Then we consider the argument an "object" for the purposes of
# the spec. # the spec.
# #
......
...@@ -8,7 +8,12 @@ does not otherwise specify a value. ...@@ -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 os
import sys import sys
...@@ -39,12 +44,14 @@ SEARCH_DIRS = [os.curdir] # i.e. ['.'] ...@@ -39,12 +44,14 @@ SEARCH_DIRS = [os.curdir] # i.e. ['.']
# rendering templates (e.g. for tags enclosed in double braces). # rendering templates (e.g. for tags enclosed in double braces).
# Only unicode strings will be passed to this function. # Only unicode strings will be passed to this function.
# #
# The quote=True argument causes double quotes to be escaped, # The quote=True argument causes double quotes to be escaped in Python 2,
# but not single quotes: # 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 # 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. # The default template extension.
TEMPLATE_EXTENSION = 'mustache' TEMPLATE_EXTENSION = 'mustache'
...@@ -8,6 +8,7 @@ This module provides a Loader class for locating and reading templates. ...@@ -8,6 +8,7 @@ This module provides a Loader class for locating and reading templates.
import os import os
import sys import sys
from pystache import common
from pystache import defaults from pystache import defaults
from pystache.locator import Locator from pystache.locator import Locator
...@@ -106,17 +107,12 @@ class Loader(object): ...@@ -106,17 +107,12 @@ class Loader(object):
Read the template at the given path, and return it as a unicode string. 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. b = common.read(path)
f = open(path, 'r')
try:
text = f.read()
finally:
f.close()
if encoding is None: if encoding is None:
encoding = self.file_encoding encoding = self.file_encoding
return self.unicode(text, encoding) return self.unicode(b, encoding)
# TODO: unit-test this method. # TODO: unit-test this method.
def load_name(self, name): def load_name(self, name):
......
...@@ -131,7 +131,7 @@ class Parser(object): ...@@ -131,7 +131,7 @@ class Parser(object):
if tag_type == '/': if tag_type == '/':
if tag_key != section_key: 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 return ParsedTemplate(parse_tree), template[start_index:match_index], end_index
......
...@@ -55,7 +55,7 @@ class RenderEngine(object): ...@@ -55,7 +55,7 @@ class RenderEngine(object):
this class will not pass tag values to literal prior to passing this class will not pass tag values to literal prior to passing
them to this function. This allows for more flexibility, them to this function. This allows for more flexibility,
for example using a custom escape function that handles 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. from plain unicode strings.
""" """
...@@ -167,9 +167,28 @@ class RenderEngine(object): ...@@ -167,9 +167,28 @@ class RenderEngine(object):
# TODO: should we check the arity? # TODO: should we check the arity?
template = data(template) template = data(template)
parsed_template = self._parse(template, delimiters=delims) parsed_template = self._parse(template, delimiters=delims)
data = [ data ] data = [data]
elif not hasattr(data, '__iter__') or isinstance(data, dict): else:
data = [ data ] # 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 = [] parts = []
for element in data: for element in data:
......
...@@ -9,7 +9,7 @@ from pystache import defaults ...@@ -9,7 +9,7 @@ from pystache import defaults
from pystache.context import Context from pystache.context import Context
from pystache.loader import Loader from pystache.loader import Loader
from pystache.renderengine import RenderEngine from pystache.renderengine import RenderEngine
from pystache.spec_loader import SpecLoader from pystache.specloader import SpecLoader
from pystache.template_spec import TemplateSpec from pystache.template_spec import TemplateSpec
...@@ -64,10 +64,10 @@ class Renderer(object): ...@@ -64,10 +64,10 @@ class Renderer(object):
this class will only pass it unicode strings. The constructor this class will only pass it unicode strings. The constructor
assigns this function to the constructed instance's escape() assigns this function to the constructed instance's escape()
method. method.
The argument defaults to `cgi.escape(s, quote=True)`. To To disable escaping entirely, one can pass `lambda u: u`
disable escaping entirely, one can pass `lambda u: u` as the as the escape function, for example. One may also wish to
escape function, for example. One may also wish to consider consider using markupsafe's escape function: markupsafe.escape().
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 file_encoding: the name of the default encoding to use when reading
template files. All templates are converted to unicode prior template files. All templates are converted to unicode prior
...@@ -160,9 +160,16 @@ class Renderer(object): ...@@ -160,9 +160,16 @@ class Renderer(object):
""" """
return unicode(self.escape(self._to_unicode_soft(s))) 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: Raises:
...@@ -178,7 +185,7 @@ class Renderer(object): ...@@ -178,7 +185,7 @@ class Renderer(object):
# TODO: Wrap UnicodeDecodeErrors with a message about setting # TODO: Wrap UnicodeDecodeErrors with a message about setting
# the string_encoding and decode_errors attributes. # 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): def _make_loader(self):
""" """
......
...@@ -55,10 +55,10 @@ class AssertStringMixin: ...@@ -55,10 +55,10 @@ class AssertStringMixin:
description = details % reason description = details % reason
return format % description 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))) 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: class AssertIsMixin:
......
...@@ -39,7 +39,7 @@ class CommandsTestCase(unittest.TestCase): ...@@ -39,7 +39,7 @@ class CommandsTestCase(unittest.TestCase):
""" """
actual = self.callScript("Hi {{thing}}", '{"thing": "world"}') actual = self.callScript("Hi {{thing}}", '{"thing": "world"}')
self.assertEquals(actual, u"Hi world\n") self.assertEqual(actual, u"Hi world\n")
def tearDown(self): def tearDown(self):
sys.stdout = ORIGINAL_STDOUT sys.stdout = ORIGINAL_STDOUT
...@@ -58,7 +58,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -58,7 +58,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = {"foo": "bar"} item = {"foo": "bar"}
self.assertEquals(_get_value(item, "foo"), "bar") self.assertEqual(_get_value(item, "foo"), "bar")
def test_dictionary__callable_not_called(self): def test_dictionary__callable_not_called(self):
""" """
...@@ -87,7 +87,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -87,7 +87,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = {} item = {}
attr_name = "keys" attr_name = "keys"
self.assertEquals(getattr(item, attr_name)(), []) self.assertEqual(getattr(item, attr_name)(), [])
self.assertNotFound(item, attr_name) self.assertNotFound(item, attr_name)
def test_dictionary__dict_subclass(self): def test_dictionary__dict_subclass(self):
...@@ -100,7 +100,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -100,7 +100,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
item = DictSubclass() item = DictSubclass()
item["foo"] = "bar" item["foo"] = "bar"
self.assertEquals(_get_value(item, "foo"), "bar") self.assertEqual(_get_value(item, "foo"), "bar")
### Case: the item is an object. ### Case: the item is an object.
...@@ -110,7 +110,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -110,7 +110,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = SimpleObject() item = SimpleObject()
self.assertEquals(_get_value(item, "foo"), "bar") self.assertEqual(_get_value(item, "foo"), "bar")
def test_object__attribute_missing(self): def test_object__attribute_missing(self):
""" """
...@@ -126,7 +126,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -126,7 +126,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = SimpleObject() item = SimpleObject()
self.assertEquals(_get_value(item, "foo_callable"), "called...") self.assertEqual(_get_value(item, "foo_callable"), "called...")
def test_object__non_built_in_type(self): def test_object__non_built_in_type(self):
""" """
...@@ -134,7 +134,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -134,7 +134,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = datetime(2012, 1, 2) item = datetime(2012, 1, 2)
self.assertEquals(_get_value(item, "day"), 2) self.assertEqual(_get_value(item, "day"), 2)
def test_object__dict_like(self): def test_object__dict_like(self):
""" """
...@@ -142,7 +142,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -142,7 +142,7 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
""" """
item = DictLike() item = DictLike()
self.assertEquals(item["foo"], "bar") self.assertEqual(item["foo"], "bar")
self.assertNotFound(item, "foo") self.assertNotFound(item, "foo")
### Case: the item is an instance of a built-in type. ### Case: the item is an instance of a built-in type.
...@@ -168,10 +168,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -168,10 +168,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
# #
return return
self.assertEquals(item1.real, 10) self.assertEqual(item1.real, 10)
self.assertEquals(item2.real, 10) self.assertEqual(item2.real, 10)
self.assertEquals(_get_value(item1, 'real'), 10) self.assertEqual(_get_value(item1, 'real'), 10)
self.assertNotFound(item2, 'real') self.assertNotFound(item2, 'real')
def test_built_in_type__string(self): def test_built_in_type__string(self):
...@@ -184,10 +184,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -184,10 +184,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
item1 = MyStr('abc') item1 = MyStr('abc')
item2 = 'abc' item2 = 'abc'
self.assertEquals(item1.upper(), 'ABC') self.assertEqual(item1.upper(), 'ABC')
self.assertEquals(item2.upper(), 'ABC') self.assertEqual(item2.upper(), 'ABC')
self.assertEquals(_get_value(item1, 'upper'), 'ABC') self.assertEqual(_get_value(item1, 'upper'), 'ABC')
self.assertNotFound(item2, 'upper') self.assertNotFound(item2, 'upper')
def test_built_in_type__list(self): def test_built_in_type__list(self):
...@@ -200,10 +200,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin): ...@@ -200,10 +200,10 @@ class GetValueTests(unittest.TestCase, AssertIsMixin):
item1 = MyList([1, 2, 3]) item1 = MyList([1, 2, 3])
item2 = [1, 2, 3] item2 = [1, 2, 3]
self.assertEquals(item1.pop(), 3) self.assertEqual(item1.pop(), 3)
self.assertEquals(item2.pop(), 3) self.assertEqual(item2.pop(), 3)
self.assertEquals(_get_value(item1, 'pop'), 2) self.assertEqual(_get_value(item1, 'pop'), 2)
self.assertNotFound(item2, 'pop') self.assertNotFound(item2, 'pop')
...@@ -230,23 +230,23 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -230,23 +230,23 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
def test__repr(self): def test__repr(self):
context = Context() context = Context()
self.assertEquals(repr(context), 'Context()') self.assertEqual(repr(context), 'Context()')
context = Context({'foo': 'bar'}) context = Context({'foo': 'bar'})
self.assertEquals(repr(context), "Context({'foo': 'bar'},)") self.assertEqual(repr(context), "Context({'foo': 'bar'},)")
context = Context({'foo': 'bar'}, {'abc': 123}) context = Context({'foo': 'bar'}, {'abc': 123})
self.assertEquals(repr(context), "Context({'foo': 'bar'}, {'abc': 123})") self.assertEqual(repr(context), "Context({'foo': 'bar'}, {'abc': 123})")
def test__str(self): def test__str(self):
context = Context() context = Context()
self.assertEquals(str(context), 'Context()') self.assertEqual(str(context), 'Context()')
context = Context({'foo': 'bar'}) context = Context({'foo': 'bar'})
self.assertEquals(str(context), "Context({'foo': 'bar'},)") self.assertEqual(str(context), "Context({'foo': 'bar'},)")
context = Context({'foo': 'bar'}, {'abc': 123}) context = Context({'foo': 'bar'}, {'abc': 123})
self.assertEquals(str(context), "Context({'foo': 'bar'}, {'abc': 123})") self.assertEqual(str(context), "Context({'foo': 'bar'}, {'abc': 123})")
## Test the static create() method. ## Test the static create() method.
...@@ -256,7 +256,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -256,7 +256,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context.create({'foo': 'bar'}) context = Context.create({'foo': 'bar'})
self.assertEquals(context.get('foo'), 'bar') self.assertEqual(context.get('foo'), 'bar')
def test_create__none(self): def test_create__none(self):
""" """
...@@ -264,7 +264,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -264,7 +264,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context.create({'foo': 'bar'}, None) context = Context.create({'foo': 'bar'}, None)
self.assertEquals(context.get('foo'), 'bar') self.assertEqual(context.get('foo'), 'bar')
def test_create__object(self): def test_create__object(self):
""" """
...@@ -274,7 +274,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -274,7 +274,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
class Foo(object): class Foo(object):
foo = 'bar' foo = 'bar'
context = Context.create(Foo()) context = Context.create(Foo())
self.assertEquals(context.get('foo'), 'bar') self.assertEqual(context.get('foo'), 'bar')
def test_create__context(self): def test_create__context(self):
""" """
...@@ -283,7 +283,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -283,7 +283,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
obj = Context({'foo': 'bar'}) obj = Context({'foo': 'bar'})
context = Context.create(obj) context = Context.create(obj)
self.assertEquals(context.get('foo'), 'bar') self.assertEqual(context.get('foo'), 'bar')
def test_create__kwarg(self): def test_create__kwarg(self):
""" """
...@@ -291,7 +291,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -291,7 +291,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context.create(foo='bar') context = Context.create(foo='bar')
self.assertEquals(context.get('foo'), 'bar') self.assertEqual(context.get('foo'), 'bar')
def test_create__precedence_positional(self): def test_create__precedence_positional(self):
""" """
...@@ -299,7 +299,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -299,7 +299,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context.create({'foo': 'bar'}, {'foo': 'buzz'}) context = Context.create({'foo': 'bar'}, {'foo': 'buzz'})
self.assertEquals(context.get('foo'), 'buzz') self.assertEqual(context.get('foo'), 'buzz')
def test_create__precedence_keyword(self): def test_create__precedence_keyword(self):
""" """
...@@ -307,7 +307,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -307,7 +307,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context.create({'foo': 'bar'}, foo='buzz') context = Context.create({'foo': 'bar'}, foo='buzz')
self.assertEquals(context.get('foo'), 'buzz') self.assertEqual(context.get('foo'), 'buzz')
def test_get__key_present(self): def test_get__key_present(self):
""" """
...@@ -315,7 +315,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -315,7 +315,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context({"foo": "bar"}) context = Context({"foo": "bar"})
self.assertEquals(context.get("foo"), "bar") self.assertEqual(context.get("foo"), "bar")
def test_get__key_missing(self): def test_get__key_missing(self):
""" """
...@@ -331,7 +331,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -331,7 +331,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context() context = Context()
self.assertEquals(context.get("foo", "bar"), "bar") self.assertEqual(context.get("foo", "bar"), "bar")
def test_get__precedence(self): def test_get__precedence(self):
""" """
...@@ -339,7 +339,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -339,7 +339,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context({"foo": "bar"}, {"foo": "buzz"}) context = Context({"foo": "bar"}, {"foo": "buzz"})
self.assertEquals(context.get("foo"), "buzz") self.assertEqual(context.get("foo"), "buzz")
def test_get__fallback(self): def test_get__fallback(self):
""" """
...@@ -347,7 +347,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -347,7 +347,7 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
context = Context({"fuzz": "buzz"}, {"foo": "bar"}) context = Context({"fuzz": "buzz"}, {"foo": "bar"})
self.assertEquals(context.get("fuzz"), "buzz") self.assertEqual(context.get("fuzz"), "buzz")
def test_push(self): def test_push(self):
""" """
...@@ -356,10 +356,10 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -356,10 +356,10 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
key = "foo" key = "foo"
context = Context({key: "bar"}) context = Context({key: "bar"})
self.assertEquals(context.get(key), "bar") self.assertEqual(context.get(key), "bar")
context.push({key: "buzz"}) context.push({key: "buzz"})
self.assertEquals(context.get(key), "buzz") self.assertEqual(context.get(key), "buzz")
def test_pop(self): def test_pop(self):
""" """
...@@ -368,33 +368,33 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -368,33 +368,33 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
""" """
key = "foo" key = "foo"
context = Context({key: "bar"}, {key: "buzz"}) context = Context({key: "bar"}, {key: "buzz"})
self.assertEquals(context.get(key), "buzz") self.assertEqual(context.get(key), "buzz")
item = context.pop() item = context.pop()
self.assertEquals(item, {"foo": "buzz"}) self.assertEqual(item, {"foo": "buzz"})
self.assertEquals(context.get(key), "bar") self.assertEqual(context.get(key), "bar")
def test_top(self): def test_top(self):
key = "foo" key = "foo"
context = Context({key: "bar"}, {key: "buzz"}) context = Context({key: "bar"}, {key: "buzz"})
self.assertEquals(context.get(key), "buzz") self.assertEqual(context.get(key), "buzz")
top = context.top() top = context.top()
self.assertEquals(top, {"foo": "buzz"}) self.assertEqual(top, {"foo": "buzz"})
# Make sure calling top() didn't remove the item from the stack. # Make sure calling top() didn't remove the item from the stack.
self.assertEquals(context.get(key), "buzz") self.assertEqual(context.get(key), "buzz")
def test_copy(self): def test_copy(self):
key = "foo" key = "foo"
original = Context({key: "bar"}, {key: "buzz"}) original = Context({key: "bar"}, {key: "buzz"})
self.assertEquals(original.get(key), "buzz") self.assertEqual(original.get(key), "buzz")
new = original.copy() new = original.copy()
# Confirm that the copy behaves the same. # Confirm that the copy behaves the same.
self.assertEquals(new.get(key), "buzz") self.assertEqual(new.get(key), "buzz")
# Change the copy, and confirm it is changed. # Change the copy, and confirm it is changed.
new.pop() new.pop()
self.assertEquals(new.get(key), "bar") self.assertEqual(new.get(key), "bar")
# Confirm the original is unchanged. # Confirm the original is unchanged.
self.assertEquals(original.get(key), "buzz") self.assertEqual(original.get(key), "buzz")
...@@ -95,7 +95,7 @@ Again, Welcome!""") ...@@ -95,7 +95,7 @@ Again, Welcome!""")
view.template = '''{{>partial_in_partial}}''' view.template = '''{{>partial_in_partial}}'''
actual = renderer.render(view, {'prop': 'derp'}) actual = renderer.render(view, {'prop': 'derp'})
self.assertEquals(actual, 'Hi derp!') self.assertEqual(actual, 'Hi derp!')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -18,30 +18,30 @@ class LoaderTests(unittest.TestCase, AssertStringMixin): ...@@ -18,30 +18,30 @@ class LoaderTests(unittest.TestCase, AssertStringMixin):
def test_init__extension(self): def test_init__extension(self):
loader = Loader(extension='foo') loader = Loader(extension='foo')
self.assertEquals(loader.extension, 'foo') self.assertEqual(loader.extension, 'foo')
def test_init__extension__default(self): def test_init__extension__default(self):
# Test the default value. # Test the default value.
loader = Loader() loader = Loader()
self.assertEquals(loader.extension, 'mustache') self.assertEqual(loader.extension, 'mustache')
def test_init__file_encoding(self): def test_init__file_encoding(self):
loader = Loader(file_encoding='bar') loader = Loader(file_encoding='bar')
self.assertEquals(loader.file_encoding, 'bar') self.assertEqual(loader.file_encoding, 'bar')
def test_init__file_encoding__default(self): def test_init__file_encoding__default(self):
file_encoding = defaults.FILE_ENCODING file_encoding = defaults.FILE_ENCODING
try: try:
defaults.FILE_ENCODING = 'foo' defaults.FILE_ENCODING = 'foo'
loader = Loader() loader = Loader()
self.assertEquals(loader.file_encoding, 'foo') self.assertEqual(loader.file_encoding, 'foo')
finally: finally:
defaults.FILE_ENCODING = file_encoding defaults.FILE_ENCODING = file_encoding
def test_init__to_unicode(self): def test_init__to_unicode(self):
to_unicode = lambda x: x to_unicode = lambda x: x
loader = Loader(to_unicode=to_unicode) 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): def test_init__to_unicode__default(self):
loader = Loader() loader = Loader()
......
...@@ -26,10 +26,10 @@ class LocatorTests(unittest.TestCase): ...@@ -26,10 +26,10 @@ class LocatorTests(unittest.TestCase):
def test_init__extension(self): def test_init__extension(self):
# Test the default value. # Test the default value.
locator = Locator() locator = Locator()
self.assertEquals(locator.template_extension, 'mustache') self.assertEqual(locator.template_extension, 'mustache')
locator = Locator(extension='txt') locator = Locator(extension='txt')
self.assertEquals(locator.template_extension, 'txt') self.assertEqual(locator.template_extension, 'txt')
locator = Locator(extension=False) locator = Locator(extension=False)
self.assertTrue(locator.template_extension is False) self.assertTrue(locator.template_extension is False)
...@@ -40,40 +40,40 @@ class LocatorTests(unittest.TestCase): ...@@ -40,40 +40,40 @@ class LocatorTests(unittest.TestCase):
obj = SayHello() obj = SayHello()
actual = locator.get_object_directory(obj) 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): def test_get_object_directory__not_hasattr_module(self):
locator = Locator() locator = Locator()
obj = datetime(2000, 1, 1) obj = datetime(2000, 1, 1)
self.assertFalse(hasattr(obj, '__module__')) 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.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): def test_make_file_name(self):
locator = Locator() locator = Locator()
locator.template_extension = 'bar' 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 locator.template_extension = False
self.assertEquals(locator.make_file_name('foo'), 'foo') self.assertEqual(locator.make_file_name('foo'), 'foo')
locator.template_extension = '' 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): def test_make_file_name__template_extension_argument(self):
locator = Locator() 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): def test_find_name(self):
locator = Locator() locator = Locator()
path = locator.find_name(search_dirs=['examples'], template_name='simple') 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): def test_find_name__using_list_of_paths(self):
locator = Locator() locator = Locator()
...@@ -98,7 +98,7 @@ class LocatorTests(unittest.TestCase): ...@@ -98,7 +98,7 @@ class LocatorTests(unittest.TestCase):
dirpath = os.path.dirname(path) dirpath = os.path.dirname(path)
dirname = os.path.split(dirpath)[-1] dirname = os.path.split(dirpath)[-1]
self.assertEquals(dirname, 'locator') self.assertEqual(dirname, 'locator')
def test_find_name__non_existent_template_fails(self): def test_find_name__non_existent_template_fails(self):
locator = Locator() locator = Locator()
...@@ -113,7 +113,7 @@ class LocatorTests(unittest.TestCase): ...@@ -113,7 +113,7 @@ class LocatorTests(unittest.TestCase):
actual = locator.find_object(search_dirs=[], obj=obj, file_name='sample_view.mustache') 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')) 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): def test_find_object__none_file_name(self):
locator = Locator() locator = Locator()
...@@ -123,18 +123,18 @@ class LocatorTests(unittest.TestCase): ...@@ -123,18 +123,18 @@ class LocatorTests(unittest.TestCase):
actual = locator.find_object(search_dirs=[], obj=obj) actual = locator.find_object(search_dirs=[], obj=obj)
expected = os.path.abspath(os.path.join(DATA_DIR, 'say_hello.mustache')) 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): def test_find_object__none_object_directory(self):
locator = Locator() locator = Locator()
obj = None 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') actual = locator.find_object(search_dirs=[DATA_DIR], obj=obj, file_name='say_hello.mustache')
expected = os.path.join(DATA_DIR, '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): def test_make_template_name(self):
""" """
...@@ -147,4 +147,4 @@ class LocatorTests(unittest.TestCase): ...@@ -147,4 +147,4 @@ class LocatorTests(unittest.TestCase):
pass pass
foo = FooBar() 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. ...@@ -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. FILE_ENCODING = 'utf-8' # the encoding of the spec test files.
yaml = None
try: try:
# We try yaml first since it is more convenient when adding and modifying # We try yaml first since it is more convenient when adding and modifying
...@@ -31,28 +32,28 @@ else: ...@@ -31,28 +32,28 @@ else:
parser = yaml parser = yaml
import codecs
import glob import glob
import os.path import os.path
import unittest import unittest
import pystache import pystache
from pystache import common
from pystache.renderer import Renderer from pystache.renderer import Renderer
from pystache.tests.common import AssertStringMixin, SPEC_TEST_DIR 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):
def parse(u, file_extension):
""" """
Parse
Arguments: Arguments:
u: a unicode string. u: a unicode string.
""" """
# TODO: find a cleaner mechanism for choosing between the two. # TODO: find a cleaner mechanism for choosing between the two.
if file_extension[0] == 'j': if yaml is None:
# Then json. # Then use json.
# The only way to get the simplejson module to return unicode strings # The only way to get the simplejson module to return unicode strings
# is to pass it unicode. See, for example-- # is to pass it unicode. See, for example--
...@@ -156,20 +157,14 @@ def buildTest(testData, spec_filename, parser): ...@@ -156,20 +157,14 @@ def buildTest(testData, spec_filename, parser):
return test return test
for spec_path in spec_paths: spec_paths = glob.glob(os.path.join(SPEC_TEST_DIR, '*.%s' % file_extension))
for path in spec_paths:
file_name = os.path.basename(spec_path)
# We avoid use of the with keyword for Python 2.4 support. file_name = os.path.basename(path)
# TODO: share code here with pystache's open() code.
f = open(spec_path, 'r')
try:
s = f.read()
finally:
f.close()
u = s.decode(FILE_ENCODING) b = common.read(path)
spec_data = parse(u, file_extension) u = unicode(b, encoding=FILE_ENCODING)
spec_data = parse(u)
tests = spec_data['tests'] tests = spec_data['tests']
......
...@@ -9,15 +9,15 @@ class PystacheTests(unittest.TestCase): ...@@ -9,15 +9,15 @@ class PystacheTests(unittest.TestCase):
def _assert_rendered(self, expected, template, context): def _assert_rendered(self, expected, template, context):
actual = pystache.render(template, context) actual = pystache.render(template, context)
self.assertEquals(actual, expected) self.assertEqual(actual, expected)
def test_basic(self): def test_basic(self):
ret = pystache.render("Hi {{thing}}!", { 'thing': 'world' }) ret = pystache.render("Hi {{thing}}!", { 'thing': 'world' })
self.assertEquals(ret, "Hi world!") self.assertEqual(ret, "Hi world!")
def test_kwargs(self): def test_kwargs(self):
ret = pystache.render("Hi {{thing}}!", thing='world') ret = pystache.render("Hi {{thing}}!", thing='world')
self.assertEquals(ret, "Hi world!") self.assertEqual(ret, "Hi world!")
def test_less_basic(self): def test_less_basic(self):
template = "It's a nice day for {{beverage}}, right {{person}}?" template = "It's a nice day for {{beverage}}, right {{person}}?"
...@@ -42,7 +42,7 @@ class PystacheTests(unittest.TestCase): ...@@ -42,7 +42,7 @@ class PystacheTests(unittest.TestCase):
def test_comments(self): def test_comments(self):
template = "What {{! the }} what?" template = "What {{! the }} what?"
actual = pystache.render(template) actual = pystache.render(template)
self.assertEquals("What what?", actual) self.assertEqual("What what?", actual)
def test_false_sections_are_hidden(self): def test_false_sections_are_hidden(self):
template = "Ready {{#set}}set {{/set}}go!" template = "Ready {{#set}}set {{/set}}go!"
......
...@@ -5,10 +5,10 @@ Unit tests of renderengine.py. ...@@ -5,10 +5,10 @@ Unit tests of renderengine.py.
""" """
import cgi
import unittest import unittest
from pystache.context import Context from pystache.context import Context
from pystache import defaults
from pystache.parser import ParsingError from pystache.parser import ParsingError
from pystache.renderengine import RenderEngine from pystache.renderengine import RenderEngine
from pystache.tests.common import AssertStringMixin from pystache.tests.common import AssertStringMixin
...@@ -26,9 +26,9 @@ class RenderEngineTestCase(unittest.TestCase): ...@@ -26,9 +26,9 @@ class RenderEngineTestCase(unittest.TestCase):
# In real-life, these arguments would be functions # In real-life, these arguments would be functions
engine = RenderEngine(load_partial="foo", literal="literal", escape="escape") engine = RenderEngine(load_partial="foo", literal="literal", escape="escape")
self.assertEquals(engine.escape, "escape") self.assertEqual(engine.escape, "escape")
self.assertEquals(engine.literal, "literal") self.assertEqual(engine.literal, "literal")
self.assertEquals(engine.load_partial, "foo") self.assertEqual(engine.load_partial, "foo")
class RenderTests(unittest.TestCase, AssertStringMixin): class RenderTests(unittest.TestCase, AssertStringMixin):
...@@ -47,7 +47,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin): ...@@ -47,7 +47,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
Create and return a default RenderEngine for testing. 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) engine = RenderEngine(literal=unicode, escape=escape, load_partial=None)
return engine return engine
...@@ -230,7 +230,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin): ...@@ -230,7 +230,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
# #
# we need to resort to built-in attributes (double-underscored) on # we need to resort to built-in attributes (double-underscored) on
# the integer type. # 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): def test_interpolation__built_in_type__list(self):
""" """
...@@ -315,7 +315,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin): ...@@ -315,7 +315,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
try: try:
self._assert_render(None, template) self._assert_render(None, template)
except ParsingError, err: 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): def test_section__end_tag_mismatch(self):
""" """
...@@ -326,7 +326,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin): ...@@ -326,7 +326,7 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
try: try:
self._assert_render(None, template) self._assert_render(None, template)
except ParsingError, err: 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): def test_section__context_values(self):
""" """
......
...@@ -20,6 +20,22 @@ from pystache.tests.common import AssertStringMixin ...@@ -20,6 +20,22 @@ from pystache.tests.common import AssertStringMixin
from pystache.tests.data.views import SayHello from pystache.tests.data.views import SayHello
def _make_renderer():
"""
Return a default Renderer instance for testing purposes.
"""
renderer = Renderer(string_encoding='ascii', file_encoding='ascii')
return renderer
def mock_unicode(b, encoding=None):
if encoding is None:
encoding = 'ascii'
u = unicode(b, encoding=encoding)
return u.upper()
class RendererInitTestCase(unittest.TestCase): class RendererInitTestCase(unittest.TestCase):
""" """
...@@ -41,20 +57,24 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -41,20 +57,24 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(partials={'foo': 'bar'}) renderer = Renderer(partials={'foo': 'bar'})
self.assertEquals(renderer.partials, {'foo': 'bar'}) self.assertEqual(renderer.partials, {'foo': 'bar'})
def test_escape__default(self): def test_escape__default(self):
escape = Renderer().escape escape = Renderer().escape
self.assertEquals(escape(">"), ">") self.assertEqual(escape(">"), ">")
self.assertEquals(escape('"'), """) self.assertEqual(escape('"'), """)
# Single quotes are not escaped. # Single quotes are escaped in Python 3 but not Python 2.
self.assertEquals(escape("'"), "'") if sys.version_info < (3, ):
expected = "'"
else:
expected = '&#x27;'
self.assertEqual(escape("'"), expected)
def test_escape(self): def test_escape(self):
escape = lambda s: "**" + s escape = lambda s: "**" + s
renderer = Renderer(escape=escape) renderer = Renderer(escape=escape)
self.assertEquals(renderer.escape("bar"), "**bar") self.assertEqual(renderer.escape("bar"), "**bar")
def test_decode_errors__default(self): def test_decode_errors__default(self):
""" """
...@@ -62,7 +82,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -62,7 +82,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.decode_errors, 'strict') self.assertEqual(renderer.decode_errors, 'strict')
def test_decode_errors(self): def test_decode_errors(self):
""" """
...@@ -70,7 +90,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -70,7 +90,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(decode_errors="foo") renderer = Renderer(decode_errors="foo")
self.assertEquals(renderer.decode_errors, "foo") self.assertEqual(renderer.decode_errors, "foo")
def test_file_encoding__default(self): def test_file_encoding__default(self):
""" """
...@@ -78,7 +98,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -78,7 +98,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.file_encoding, renderer.string_encoding) self.assertEqual(renderer.file_encoding, renderer.string_encoding)
def test_file_encoding(self): def test_file_encoding(self):
""" """
...@@ -86,7 +106,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -86,7 +106,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(file_encoding='foo') renderer = Renderer(file_encoding='foo')
self.assertEquals(renderer.file_encoding, 'foo') self.assertEqual(renderer.file_encoding, 'foo')
def test_file_extension__default(self): def test_file_extension__default(self):
""" """
...@@ -94,7 +114,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -94,7 +114,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.file_extension, 'mustache') self.assertEqual(renderer.file_extension, 'mustache')
def test_file_extension(self): def test_file_extension(self):
""" """
...@@ -102,7 +122,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -102,7 +122,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(file_extension='foo') renderer = Renderer(file_extension='foo')
self.assertEquals(renderer.file_extension, 'foo') self.assertEqual(renderer.file_extension, 'foo')
def test_search_dirs__default(self): def test_search_dirs__default(self):
""" """
...@@ -110,7 +130,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -110,7 +130,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.search_dirs, [os.curdir]) self.assertEqual(renderer.search_dirs, [os.curdir])
def test_search_dirs__string(self): def test_search_dirs__string(self):
""" """
...@@ -118,7 +138,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -118,7 +138,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(search_dirs='foo') renderer = Renderer(search_dirs='foo')
self.assertEquals(renderer.search_dirs, ['foo']) self.assertEqual(renderer.search_dirs, ['foo'])
def test_search_dirs__list(self): def test_search_dirs__list(self):
""" """
...@@ -126,7 +146,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -126,7 +146,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(search_dirs=['foo']) renderer = Renderer(search_dirs=['foo'])
self.assertEquals(renderer.search_dirs, ['foo']) self.assertEqual(renderer.search_dirs, ['foo'])
def test_string_encoding__default(self): def test_string_encoding__default(self):
""" """
...@@ -134,7 +154,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -134,7 +154,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.string_encoding, sys.getdefaultencoding()) self.assertEqual(renderer.string_encoding, sys.getdefaultencoding())
def test_string_encoding(self): def test_string_encoding(self):
""" """
...@@ -142,7 +162,7 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -142,7 +162,7 @@ class RendererInitTestCase(unittest.TestCase):
""" """
renderer = Renderer(string_encoding="foo") renderer = Renderer(string_encoding="foo")
self.assertEquals(renderer.string_encoding, "foo") self.assertEqual(renderer.string_encoding, "foo")
class RendererTests(unittest.TestCase, AssertStringMixin): class RendererTests(unittest.TestCase, AssertStringMixin):
...@@ -166,7 +186,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -166,7 +186,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
self.assertRaises(UnicodeDecodeError, renderer.unicode, s) self.assertRaises(UnicodeDecodeError, renderer.unicode, s)
renderer.string_encoding = "utf-8" renderer.string_encoding = "utf-8"
self.assertEquals(renderer.unicode(s), u"é") self.assertEqual(renderer.unicode(s), u"é")
def test_unicode__decode_errors(self): def test_unicode__decode_errors(self):
""" """
...@@ -178,11 +198,11 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -178,11 +198,11 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
s = "déf" s = "déf"
renderer.decode_errors = "ignore" renderer.decode_errors = "ignore"
self.assertEquals(renderer.unicode(s), "df") self.assertEqual(renderer.unicode(s), "df")
renderer.decode_errors = "replace" renderer.decode_errors = "replace"
# 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.assertEqual(renderer.unicode(s), u'd\ufffd\ufffdf')
## Test the _make_loader() method. ## Test the _make_loader() method.
...@@ -194,7 +214,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -194,7 +214,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
renderer = Renderer() renderer = Renderer()
loader = renderer._make_loader() loader = renderer._make_loader()
self.assertEquals(type(loader), Loader) self.assertEqual(type(loader), Loader)
def test__make_loader__attributes(self): def test__make_loader__attributes(self):
""" """
...@@ -210,9 +230,9 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -210,9 +230,9 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
loader = renderer._make_loader() loader = renderer._make_loader()
self.assertEquals(loader.extension, 'ext') self.assertEqual(loader.extension, 'ext')
self.assertEquals(loader.file_encoding, 'enc') self.assertEqual(loader.file_encoding, 'enc')
self.assertEquals(loader.to_unicode, unicode_) self.assertEqual(loader.to_unicode, unicode_)
## Test the render() method. ## Test the render() method.
...@@ -223,22 +243,22 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -223,22 +243,22 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
""" """
renderer = Renderer() renderer = Renderer()
rendered = renderer.render('foo') rendered = renderer.render('foo')
self.assertEquals(type(rendered), unicode) self.assertEqual(type(rendered), unicode)
def test_render__unicode(self): def test_render__unicode(self):
renderer = Renderer() renderer = Renderer()
actual = renderer.render(u'foo') actual = renderer.render(u'foo')
self.assertEquals(actual, u'foo') self.assertEqual(actual, u'foo')
def test_render__str(self): def test_render__str(self):
renderer = Renderer() renderer = Renderer()
actual = renderer.render('foo') actual = renderer.render('foo')
self.assertEquals(actual, 'foo') self.assertEqual(actual, 'foo')
def test_render__non_ascii_character(self): def test_render__non_ascii_character(self):
renderer = Renderer() renderer = Renderer()
actual = renderer.render(u'Poincaré') actual = renderer.render(u'Poincaré')
self.assertEquals(actual, u'Poincaré') self.assertEqual(actual, u'Poincaré')
def test_render__context(self): def test_render__context(self):
""" """
...@@ -246,7 +266,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -246,7 +266,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.render('Hi {{person}}', {'person': 'Mom'}), 'Hi Mom') self.assertEqual(renderer.render('Hi {{person}}', {'person': 'Mom'}), 'Hi Mom')
def test_render__context_and_kwargs(self): def test_render__context_and_kwargs(self):
""" """
...@@ -255,7 +275,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -255,7 +275,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
""" """
renderer = Renderer() renderer = Renderer()
template = 'Hi {{person1}} and {{person2}}' template = 'Hi {{person1}} and {{person2}}'
self.assertEquals(renderer.render(template, {'person1': 'Mom'}, person2='Dad'), 'Hi Mom and Dad') self.assertEqual(renderer.render(template, {'person1': 'Mom'}, person2='Dad'), 'Hi Mom and Dad')
def test_render__kwargs_and_no_context(self): def test_render__kwargs_and_no_context(self):
""" """
...@@ -263,7 +283,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -263,7 +283,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.render('Hi {{person}}', person='Mom'), 'Hi Mom') self.assertEqual(renderer.render('Hi {{person}}', person='Mom'), 'Hi Mom')
def test_render__context_and_kwargs__precedence(self): def test_render__context_and_kwargs__precedence(self):
""" """
...@@ -271,7 +291,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -271,7 +291,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
""" """
renderer = Renderer() renderer = Renderer()
self.assertEquals(renderer.render('Hi {{person}}', {'person': 'Mom'}, person='Dad'), 'Hi Dad') self.assertEqual(renderer.render('Hi {{person}}', {'person': 'Mom'}, person='Dad'), 'Hi Dad')
def test_render__kwargs_does_not_modify_context(self): def test_render__kwargs_does_not_modify_context(self):
""" """
...@@ -281,23 +301,23 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -281,23 +301,23 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
context = {} context = {}
renderer = Renderer() renderer = Renderer()
renderer.render('Hi {{person}}', context=context, foo="bar") renderer.render('Hi {{person}}', context=context, foo="bar")
self.assertEquals(context, {}) self.assertEqual(context, {})
def test_render__nonascii_template(self): def test_render__nonascii_template(self):
""" """
Test passing a non-unicode template with non-ascii characters. Test passing a non-unicode template with non-ascii characters.
""" """
renderer = Renderer() renderer = _make_renderer()
template = "déf" template = u"déf".encode("utf-8")
# Check that decode_errors and string_encoding are both respected. # Check that decode_errors and string_encoding are both respected.
renderer.decode_errors = 'ignore' renderer.decode_errors = 'ignore'
renderer.string_encoding = 'ascii' renderer.string_encoding = 'ascii'
self.assertEquals(renderer.render(template), "df") self.assertEqual(renderer.render(template), "df")
renderer.string_encoding = 'utf_8' renderer.string_encoding = 'utf_8'
self.assertEquals(renderer.render(template), u"déf") self.assertEqual(renderer.render(template), u"déf")
def test_make_load_partial(self): def test_make_load_partial(self):
""" """
...@@ -309,8 +329,8 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -309,8 +329,8 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
load_partial = renderer._make_load_partial() load_partial = renderer._make_load_partial()
actual = load_partial('foo') actual = load_partial('foo')
self.assertEquals(actual, 'bar') self.assertEqual(actual, 'bar')
self.assertEquals(type(actual), unicode, "RenderEngine requires that " self.assertEqual(type(actual), unicode, "RenderEngine requires that "
"load_partial return unicode strings.") "load_partial return unicode strings.")
def test_make_load_partial__unicode(self): def test_make_load_partial__unicode(self):
...@@ -322,14 +342,14 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -322,14 +342,14 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
renderer.partials = {'partial': 'foo'} renderer.partials = {'partial': 'foo'}
load_partial = renderer._make_load_partial() load_partial = renderer._make_load_partial()
self.assertEquals(load_partial("partial"), "foo") self.assertEqual(load_partial("partial"), "foo")
# Now with a value that is already unicode. # Now with a value that is already unicode.
renderer.partials = {'partial': u'foo'} renderer.partials = {'partial': u'foo'}
load_partial = renderer._make_load_partial() load_partial = renderer._make_load_partial()
# If the next line failed, we would get the following error: # If the next line failed, we would get the following error:
# TypeError: decoding Unicode is not supported # TypeError: decoding Unicode is not supported
self.assertEquals(load_partial("partial"), "foo") self.assertEqual(load_partial("partial"), "foo")
def test_render_path(self): def test_render_path(self):
""" """
...@@ -339,7 +359,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -339,7 +359,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
renderer = Renderer() renderer = Renderer()
path = get_data_path('say_hello.mustache') path = get_data_path('say_hello.mustache')
actual = renderer.render_path(path, to='foo') actual = renderer.render_path(path, to='foo')
self.assertEquals(actual, "Hello, foo") self.assertEqual(actual, "Hello, foo")
def test_render__object(self): def test_render__object(self):
""" """
...@@ -350,10 +370,10 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -350,10 +370,10 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
say_hello = SayHello() say_hello = SayHello()
actual = renderer.render(say_hello) actual = renderer.render(say_hello)
self.assertEquals('Hello, World', actual) self.assertEqual('Hello, World', actual)
actual = renderer.render(say_hello, to='Mars') actual = renderer.render(say_hello, to='Mars')
self.assertEquals('Hello, Mars', actual) self.assertEqual('Hello, Mars', actual)
def test_render__template_spec(self): def test_render__template_spec(self):
""" """
...@@ -379,7 +399,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -379,7 +399,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
view = Simple() view = Simple()
actual = renderer.render(view) actual = renderer.render(view)
self.assertEquals('Hi pizza!', actual) self.assertEqual('Hi pizza!', actual)
# By testing that Renderer.render() constructs the right RenderEngine, # By testing that Renderer.render() constructs the right RenderEngine,
...@@ -393,6 +413,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -393,6 +413,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
""" """
def _make_renderer(self):
"""
Return a default Renderer instance for testing purposes.
"""
return _make_renderer()
## Test the engine's load_partial attribute. ## Test the engine's load_partial attribute.
def test__load_partial__returns_unicode(self): def test__load_partial__returns_unicode(self):
...@@ -410,13 +437,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -410,13 +437,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
actual = engine.load_partial('str') actual = engine.load_partial('str')
self.assertEquals(actual, "foo") self.assertEqual(actual, "foo")
self.assertEquals(type(actual), unicode) self.assertEqual(type(actual), unicode)
# Check that unicode subclasses are not preserved. # Check that unicode subclasses are not preserved.
actual = engine.load_partial('subclass') actual = engine.load_partial('subclass')
self.assertEquals(actual, "abc") self.assertEqual(actual, "abc")
self.assertEquals(type(actual), unicode) self.assertEqual(type(actual), unicode)
def test__load_partial__not_found(self): def test__load_partial__not_found(self):
""" """
...@@ -433,7 +460,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -433,7 +460,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
load_partial("foo") load_partial("foo")
raise Exception("Shouldn't get here") raise Exception("Shouldn't get here")
except Exception, err: except Exception, err:
self.assertEquals(str(err), "Partial not found with name: 'foo'") self.assertEqual(str(err), "Partial not found with name: 'foo'")
## Test the engine's literal attribute. ## Test the engine's literal attribute.
...@@ -442,13 +469,14 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -442,13 +469,14 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
Test that literal uses the renderer's unicode function. Test that literal uses the renderer's unicode function.
""" """
renderer = Renderer() renderer = self._make_renderer()
renderer.unicode = lambda s: s.upper() renderer.unicode = mock_unicode
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
literal = engine.literal literal = engine.literal
self.assertEquals(literal("foo"), "FOO") b = u"foo".encode("ascii")
self.assertEqual(literal(b), "FOO")
def test__literal__handles_unicode(self): def test__literal__handles_unicode(self):
""" """
...@@ -461,7 +489,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -461,7 +489,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
literal = engine.literal literal = engine.literal
self.assertEquals(literal(u"foo"), "foo") self.assertEqual(literal(u"foo"), "foo")
def test__literal__returns_unicode(self): def test__literal__returns_unicode(self):
""" """
...@@ -474,16 +502,16 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -474,16 +502,16 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
literal = engine.literal literal = engine.literal
self.assertEquals(type(literal("foo")), unicode) self.assertEqual(type(literal("foo")), unicode)
class MyUnicode(unicode): class MyUnicode(unicode):
pass pass
s = MyUnicode("abc") s = MyUnicode("abc")
self.assertEquals(type(s), MyUnicode) self.assertEqual(type(s), MyUnicode)
self.assertTrue(isinstance(s, unicode)) self.assertTrue(isinstance(s, unicode))
self.assertEquals(type(literal(s)), unicode) self.assertEqual(type(literal(s)), unicode)
## Test the engine's escape attribute. ## Test the engine's escape attribute.
...@@ -498,7 +526,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -498,7 +526,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
escape = engine.escape escape = engine.escape
self.assertEquals(escape("foo"), "**foo") self.assertEqual(escape("foo"), "**foo")
def test__escape__uses_renderer_unicode(self): def test__escape__uses_renderer_unicode(self):
""" """
...@@ -506,12 +534,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -506,12 +534,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
renderer.unicode = lambda s: s.upper() renderer.unicode = mock_unicode
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
escape = engine.escape escape = engine.escape
self.assertEquals(escape("foo"), "FOO") b = u"foo".encode('ascii')
self.assertEqual(escape(b), "FOO")
def test__escape__has_access_to_original_unicode_subclass(self): def test__escape__has_access_to_original_unicode_subclass(self):
""" """
...@@ -519,7 +548,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -519,7 +548,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
""" """
renderer = Renderer() renderer = Renderer()
renderer.escape = lambda s: type(s).__name__ renderer.escape = lambda s: unicode(type(s).__name__)
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
escape = engine.escape escape = engine.escape
...@@ -527,9 +556,9 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -527,9 +556,9 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
class MyUnicode(unicode): class MyUnicode(unicode):
pass pass
self.assertEquals(escape("foo"), "unicode") self.assertEqual(escape(u"foo".encode('ascii')), unicode.__name__)
self.assertEquals(escape(u"foo"), "unicode") self.assertEqual(escape(u"foo"), unicode.__name__)
self.assertEquals(escape(MyUnicode("foo")), "MyUnicode") self.assertEqual(escape(MyUnicode("foo")), MyUnicode.__name__)
def test__escape__returns_unicode(self): def test__escape__returns_unicode(self):
""" """
...@@ -542,7 +571,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -542,7 +571,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
escape = engine.escape escape = engine.escape
self.assertEquals(type(escape("foo")), unicode) self.assertEqual(type(escape("foo")), unicode)
# Check that literal doesn't preserve unicode subclasses. # Check that literal doesn't preserve unicode subclasses.
class MyUnicode(unicode): class MyUnicode(unicode):
...@@ -550,7 +579,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -550,7 +579,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
s = MyUnicode("abc") s = MyUnicode("abc")
self.assertEquals(type(s), MyUnicode) self.assertEqual(type(s), MyUnicode)
self.assertTrue(isinstance(s, unicode)) self.assertTrue(isinstance(s, unicode))
self.assertEquals(type(escape(s)), unicode) self.assertEqual(type(escape(s)), unicode)
...@@ -28,11 +28,11 @@ class TestSimple(unittest.TestCase, AssertStringMixin): ...@@ -28,11 +28,11 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
renderer = Renderer() renderer = Renderer()
actual = renderer.render(template, context) 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): def test_empty_context(self):
template = '{{#empty_list}}Shouldnt see me {{/empty_list}}{{^empty_list}}Should see me{{/empty_list}}' 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): def test_callables(self):
view = Lambdas() view = Lambdas()
...@@ -58,7 +58,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin): ...@@ -58,7 +58,7 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
def test_non_existent_value_renders_blank(self): def test_non_existent_value_renders_blank(self):
view = Simple() view = Simple()
template = '{{not_set}} {{blank}}' template = '{{not_set}} {{blank}}'
self.assertEquals(pystache.Renderer().render(template), ' ') self.assertEqual(pystache.Renderer().render(template), ' ')
def test_template_partial_extension(self): def test_template_partial_extension(self):
......
...@@ -18,7 +18,7 @@ from pystache import Renderer ...@@ -18,7 +18,7 @@ from pystache import Renderer
from pystache import TemplateSpec from pystache import TemplateSpec
from pystache.locator import Locator from pystache.locator import Locator
from pystache.loader import Loader 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 DATA_DIR
from pystache.tests.common import EXAMPLES_DIR from pystache.tests.common import EXAMPLES_DIR
from pystache.tests.common import AssertIsMixin from pystache.tests.common import AssertIsMixin
...@@ -49,7 +49,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -49,7 +49,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
# TODO: change this test to remove the following brittle line. # TODO: change this test to remove the following brittle line.
view.template_rel_directory = "../../examples" view.template_rel_directory = "../../examples"
actual = renderer.render(view) actual = renderer.render(view)
self.assertEquals(actual, "No tags...") self.assertEqual(actual, "No tags...")
def test_template_path_for_partials(self): def test_template_path_for_partials(self):
""" """
...@@ -65,7 +65,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -65,7 +65,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
self.assertRaises(IOError, renderer1.render, spec) self.assertRaises(IOError, renderer1.render, spec)
actual = renderer2.render(spec) actual = renderer2.render(spec)
self.assertEquals(actual, "Partial: No tags...") self.assertEqual(actual, "Partial: No tags...")
def test_basic_method_calls(self): def test_basic_method_calls(self):
renderer = Renderer() renderer = Renderer()
...@@ -79,7 +79,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -79,7 +79,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
renderer = Renderer() renderer = Renderer()
actual = renderer.render(view) actual = renderer.render(view)
self.assertEquals(actual, "Hi Chris!") self.assertEqual(actual, "Hi Chris!")
def test_complex(self): def test_complex(self):
renderer = Renderer() renderer = Renderer()
...@@ -95,7 +95,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -95,7 +95,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
def test_higher_order_replace(self): def test_higher_order_replace(self):
renderer = Renderer() renderer = Renderer()
actual = renderer.render(Lambdas()) 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): def test_higher_order_rot13(self):
view = Lambdas() view = Lambdas()
...@@ -119,7 +119,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -119,7 +119,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
renderer = Renderer(search_dirs=EXAMPLES_DIR) renderer = Renderer(search_dirs=EXAMPLES_DIR)
actual = renderer.render(view) actual = renderer.render(view)
self.assertEquals(actual, u'nopqrstuvwxyz') self.assertEqual(actual, u'nopqrstuvwxyz')
def test_hierarchical_partials_with_lambdas(self): def test_hierarchical_partials_with_lambdas(self):
view = Lambdas() view = Lambdas()
...@@ -152,6 +152,28 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin): ...@@ -152,6 +152,28 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
self.assertString(actual, u"""one, two, three, empty list""") 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): class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
""" """
...@@ -159,13 +181,16 @@ 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): def test_init__defaults(self):
custom = SpecLoader() spec_loader = SpecLoader()
# Check the loader attribute. # Check the loader attribute.
loader = custom.loader loader = spec_loader.loader
self.assertEquals(loader.extension, 'mustache') self.assertEqual(loader.extension, 'mustache')
self.assertEquals(loader.file_encoding, sys.getdefaultencoding()) self.assertEqual(loader.file_encoding, sys.getdefaultencoding())
# TODO: finish testing the other Loader attributes. # TODO: finish testing the other Loader attributes.
to_unicode = loader.to_unicode to_unicode = loader.to_unicode
...@@ -187,7 +212,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -187,7 +212,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec() custom = TemplateSpec()
custom.template = "abc" 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): def test_load__template__type_unicode(self):
""" """
...@@ -197,7 +223,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -197,7 +223,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec() custom = TemplateSpec()
custom.template = u"abc" 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): def test_load__template__unicode_non_ascii(self):
""" """
...@@ -207,7 +234,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -207,7 +234,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec() custom = TemplateSpec()
custom.template = u"é" 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): def test_load__template__with_template_encoding(self):
""" """
...@@ -217,10 +245,12 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -217,10 +245,12 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
custom = TemplateSpec() custom = TemplateSpec()
custom.template = u'é'.encode('utf-8') 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' custom.template_encoding = 'utf-8'
self._assert_template(SpecLoader(), custom, u'é') self._assert_template(spec_loader, custom, u'é')
# TODO: make this test complete. # TODO: make this test complete.
def test_load__template__correct_loader(self): def test_load__template__correct_loader(self):
...@@ -255,8 +285,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -255,8 +285,8 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
# Check that our unicode() above was called. # Check that our unicode() above was called.
self._assert_template(custom_loader, view, u'foo') self._assert_template(custom_loader, view, u'foo')
self.assertEquals(loader.s, "template-foo") self.assertEqual(loader.s, "template-foo")
self.assertEquals(loader.encoding, "encoding-foo") self.assertEqual(loader.encoding, "encoding-foo")
# TODO: migrate these tests into the SpecLoaderTests class. # TODO: migrate these tests into the SpecLoaderTests class.
...@@ -266,14 +296,13 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin): ...@@ -266,14 +296,13 @@ class SpecLoaderTests(unittest.TestCase, AssertIsMixin, AssertStringMixin):
# TemplateSpec attributes or something). # TemplateSpec attributes or something).
class TemplateSpecTests(unittest.TestCase): class TemplateSpecTests(unittest.TestCase):
# TODO: rename this method to _make_loader(). def _make_loader(self):
def _make_locator(self): return _make_specloader()
return SpecLoader()
def _assert_template_location(self, view, expected): def _assert_template_location(self, view, expected):
locator = self._make_locator() loader = self._make_loader()
actual = locator._find_relative(view) actual = loader._find_relative(view)
self.assertEquals(actual, expected) self.assertEqual(actual, expected)
def test_find_relative(self): def test_find_relative(self):
""" """
...@@ -334,38 +363,38 @@ class TemplateSpecTests(unittest.TestCase): ...@@ -334,38 +363,38 @@ class TemplateSpecTests(unittest.TestCase):
Test _find() with a view that has a directory specified. Test _find() with a view that has a directory specified.
""" """
locator = self._make_locator() loader = self._make_loader()
view = SampleView() view = SampleView()
view.template_rel_path = 'foo/bar.txt' 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')) 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): def test_find__without_directory(self):
""" """
Test _find() with a view that doesn't have a directory specified. Test _find() with a view that doesn't have a directory specified.
""" """
locator = self._make_locator() loader = self._make_loader()
view = SampleView() 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')) 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): def _assert_get_template(self, custom, expected):
locator = self._make_locator() loader = self._make_loader()
actual = locator.load(custom) actual = loader.load(custom)
self.assertEquals(type(actual), unicode) self.assertEqual(type(actual), unicode)
self.assertEquals(actual, expected) self.assertEqual(actual, expected)
def test_get_template(self): 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