Commit ca2cd4c0 by Rodrigo Bernardo Pimentel

Merge branch 'spec-1.1.2-compliant' into development

parents d23da511 02a2472d
...@@ -54,8 +54,9 @@ def _get_value(item, key): ...@@ -54,8 +54,9 @@ def _get_value(item, key):
value = attr value = attr
for part in parts[1:]: for part in parts[1:]:
if value is not _NOT_FOUND: if value is _NOT_FOUND:
value = _get_value(value, part) break
value = _get_value(value, part)
return value return value
......
...@@ -51,3 +51,20 @@ class AssertIsMixin: ...@@ -51,3 +51,20 @@ class AssertIsMixin:
# http://docs.python.org/library/unittest.html#unittest.TestCase.assertIsNone # http://docs.python.org/library/unittest.html#unittest.TestCase.assertIsNone
def assertIs(self, first, second): def assertIs(self, first, second):
self.assertTrue(first is second, msg="%s is not %s" % (repr(first), repr(second))) self.assertTrue(first is second, msg="%s is not %s" % (repr(first), repr(second)))
class Attachable(object):
"""A trivial object that attaches all constructor named parameters as attributes.
For instance,
>>> o = Attachable(foo=42, size="of the universe")
>>> o.foo
42
>>> o.size
of the universe
"""
def __init__(self, **kwargs):
for arg, value in kwargs.iteritems():
setattr(self, arg, value)
...@@ -11,7 +11,7 @@ import unittest ...@@ -11,7 +11,7 @@ import unittest
from pystache.context import _NOT_FOUND from pystache.context import _NOT_FOUND
from pystache.context import _get_value from pystache.context import _get_value
from pystache.context import Context from pystache.context import Context
from tests.common import AssertIsMixin from tests.common import AssertIsMixin, Attachable
class SimpleObject(object): class SimpleObject(object):
...@@ -398,3 +398,39 @@ class ContextTests(unittest.TestCase, AssertIsMixin): ...@@ -398,3 +398,39 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
# Confirm the original is unchanged. # Confirm the original is unchanged.
self.assertEquals(original.get(key), "buzz") self.assertEquals(original.get(key), "buzz")
def test_dot_notation__dict(self):
key = "foo.bar"
original = Context({"foo": {"bar": "baz"}})
self.assertEquals(original.get(key), "baz")
# Works all the way down
key = "a.b.c.d.e.f.g"
original = Context({"a": {"b": {"c": {"d": {"e": {"f": {"g": "w00t!"}}}}}}})
self.assertEquals(original.get(key), "w00t!")
def test_dot_notation__user_object(self):
key = "foo.bar"
original = Context({"foo": Attachable(bar="baz")})
self.assertEquals(original.get(key), "baz")
# Works on multiple levels, too
key = "a.b.c.d.e.f.g"
Obj = Attachable
original = Context({"a": Obj(b=Obj(c=Obj(d=Obj(e=Obj(f=Obj(g="w00t!"))))))})
self.assertEquals(original.get(key), "w00t!")
def test_dot_notation__mixed_dict_and_obj(self):
key = "foo.bar.baz.bak"
original = Context({"foo": Attachable(bar={"baz": Attachable(bak=42)})})
self.assertEquals(original.get(key), 42)
def test_dot_notation__missing_attr_or_key(self):
key = "foo.bar.baz.bak"
original = Context({"foo": {"bar": {}}})
self.assertEquals(original.get(key), None)
original = Context({"foo": Attachable(bar=Attachable())})
self.assertEquals(original.get(key), None)
...@@ -11,7 +11,7 @@ import unittest ...@@ -11,7 +11,7 @@ import unittest
from pystache.context import Context from pystache.context import Context
from pystache.parser import ParsingError from pystache.parser import ParsingError
from pystache.renderengine import RenderEngine from pystache.renderengine import RenderEngine
from tests.common import AssertStringMixin from tests.common import AssertStringMixin, Attachable
class RenderEngineTestCase(unittest.TestCase): class RenderEngineTestCase(unittest.TestCase):
...@@ -453,3 +453,47 @@ class RenderTests(unittest.TestCase, AssertStringMixin): ...@@ -453,3 +453,47 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
expected = u' {{foo}} ' expected = u' {{foo}} '
self._assert_render(expected, '{{=$ $=}} {{foo}} ') self._assert_render(expected, '{{=$ $=}} {{foo}} ')
self._assert_render(expected, '{{=$ $=}} {{foo}} $={{ }}=$') # was yielding u' '. self._assert_render(expected, '{{=$ $=}} {{foo}} $={{ }}=$') # was yielding u' '.
def test_dot_notation(self):
"""
Check that we can use dot notation when the variable is a dict,
a used-defined object, or a combination of both
"""
template = 'Hello, {{person.name}}. I see you are {{person.details.age}}.'
person = Attachable(name='Biggles', details={'age': 42})
context = {'person': person}
self._assert_render(u'Hello, Biggles. I see you are 42.', template, context)
def test_dot_notation__missing_attributes_or_keys(self):
"""
Check that, when using dot notation, if the key or attribute does not
exist then its value is rendered as empty
"""
template = """I cannot see {{person.name}}'s age: {{person.age}}.
Nor {{other_person.name}}'s: ."""
expected = u"""I cannot see Biggles's age: .
Nor Mr. Bradshaw's: ."""
context = {'person': {'name': 'Biggles'},
'other_person': Attachable(name='Mr. Bradshaw')}
self._assert_render(expected, template, context)
def test_dot_notation__multiple_levels(self):
"""
Check that using multiple levels of dot attributes works as expected
"""
template = """Hello, Mr. {{person.name.lastname}}.
I see you're back from {{person.travels.last.country.city}}.
I'm missing some of your details: {{person.details.private.editor}}."""
expected = u"""Hello, Mr. Pither.
I see you're back from Cornwall.
I'm missing some of your details: ."""
context = {'person': {'name': {'firstname': 'unknown', 'lastname': 'Pither'},
'travels': {'last': {'country': {'city': 'Cornwall'}}},
'details': {'public': 'likes cycling'}}}
self._assert_render(expected, template, context)
# It should also work with user-defined objects
context = {'person': Attachable(name={'firstname': 'unknown', 'lastname': 'Pither'},
travels=Attachable(last=Attachable(country=Attachable(city='Cornwall'))),
details=Attachable())}
self._assert_render(expected, template, context)
...@@ -60,26 +60,6 @@ class TestSimple(unittest.TestCase, AssertStringMixin): ...@@ -60,26 +60,6 @@ class TestSimple(unittest.TestCase, AssertStringMixin):
template = '{{not_set}} {{blank}}' template = '{{not_set}} {{blank}}'
self.assertEquals(pystache.Renderer().render(template), ' ') self.assertEquals(pystache.Renderer().render(template), ' ')
def test_dot_notation_with_dict(self):
template = 'Name: {{person.name}}. Age: {{person.details.age}}. Intimate details (should be empty): {{person.details.intimate}}.'
renderer = Renderer()
context = {'person': {'name': 'Biggles', 'details': {'age': 42}}}
actual = renderer.render(template, context)
self.assertEquals(actual, 'Name: Biggles. Age: 42. Intimate details (should be empty): .')
def test_dot_notation_with_user_objects(self):
template = 'Name: {{person.name}}. Age: {{person.details.age}}. Intimate details (should be empty): {{person.details.intimate}}.'
renderer = Renderer()
class Person(object):
def __init__(self, name, details):
self.name = name
self.details = details
context = {'person': Person('Biggles', {'age': 42})}
actual = renderer.render(template, context)
self.assertEquals(actual, 'Name: Biggles. Age: 42. Intimate details (should be empty): .')
def test_template_partial_extension(self): def test_template_partial_extension(self):
""" """
Side note: Side note:
......
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