Commit 17919ab6 by Chris Jerdonek

More Python 3 unit test fixes.

parent 4af76cab
...@@ -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.
# #
......
...@@ -44,8 +44,9 @@ SEARCH_DIRS = [os.curdir] # i.e. ['.'] ...@@ -44,8 +44,9 @@ 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/dev/library/html.html#html.escape
# http://docs.python.org/library/cgi.html#cgi.escape # http://docs.python.org/library/cgi.html#cgi.escape
......
...@@ -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.
""" """
......
...@@ -164,6 +164,13 @@ class Renderer(object): ...@@ -164,6 +164,13 @@ class Renderer(object):
""" """
Convert a byte 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:
TypeError: Because this method calls Python's built-in unicode() TypeError: Because this method calls Python's built-in unicode()
......
...@@ -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.assertEqual(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.assertEqual(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):
""" """
...@@ -48,8 +64,12 @@ class RendererInitTestCase(unittest.TestCase): ...@@ -48,8 +64,12 @@ class RendererInitTestCase(unittest.TestCase):
self.assertEqual(escape(">"), ">") self.assertEqual(escape(">"), ">")
self.assertEqual(escape('"'), """) self.assertEqual(escape('"'), """)
# Single quotes are not escaped. # Single quotes are escaped in Python 3 but not Python 2.
self.assertEqual(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
...@@ -288,8 +308,8 @@ class RendererTests(unittest.TestCase, AssertStringMixin): ...@@ -288,8 +308,8 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
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'
...@@ -398,8 +418,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -398,8 +418,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
Return a default Renderer instance for testing purposes. Return a default Renderer instance for testing purposes.
""" """
renderer = Renderer(string_encoding='ascii', file_encoding='ascii') return _make_renderer()
return renderer
## Test the engine's load_partial attribute. ## Test the engine's load_partial attribute.
...@@ -451,8 +470,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -451,8 +470,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
""" """
renderer = self._make_renderer() renderer = self._make_renderer()
# This function renderer.unicode = mock_unicode
renderer.unicode = lambda b: unicode(b, encoding='ascii').upper()
engine = renderer._make_render_engine() engine = renderer._make_render_engine()
literal = engine.literal literal = engine.literal
...@@ -516,12 +534,13 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -516,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.assertEqual(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):
""" """
...@@ -529,7 +548,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -529,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
...@@ -537,9 +556,9 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase): ...@@ -537,9 +556,9 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
class MyUnicode(unicode): class MyUnicode(unicode):
pass pass
self.assertEqual(escape("foo"), "unicode") self.assertEqual(escape(u"foo".encode('ascii')), unicode.__name__)
self.assertEqual(escape(u"foo"), "unicode") self.assertEqual(escape(u"foo"), unicode.__name__)
self.assertEqual(escape(MyUnicode("foo")), "MyUnicode") self.assertEqual(escape(MyUnicode("foo")), MyUnicode.__name__)
def test__escape__returns_unicode(self): def test__escape__returns_unicode(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