Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pystache_custom
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pystache_custom
Commits
1953e28d
Commit
1953e28d
authored
May 04, 2012
by
Chris Jerdonek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished implementing strict mode for missing tags.
parent
4a4b4ddc
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
108 additions
and
49 deletions
+108
-49
pystache/renderengine.py
+20
-12
pystache/renderer.py
+32
-6
pystache/tests/test_renderengine.py
+20
-27
pystache/tests/test_renderer.py
+36
-4
No files found.
pystache/renderengine.py
View file @
1953e28d
...
...
@@ -7,10 +7,17 @@ Defines a class responsible for rendering logic.
import
re
from
pystache.context
import
KeyNotFoundError
from
pystache.parser
import
Parser
def
context_get
(
stack
,
name
):
"""
Find and return a name from a ContextStack instance.
"""
return
stack
.
get
(
name
)
class
RenderEngine
(
object
):
"""
...
...
@@ -30,14 +37,11 @@ class RenderEngine(object):
"""
def
__init__
(
self
,
resolve_partial
=
None
,
literal
=
None
,
escape
=
None
):
def
__init__
(
self
,
literal
=
None
,
escape
=
None
,
resolve_context
=
None
,
resolve_partial
=
None
):
"""
Arguments:
resolve_partial: the function to call when loading a partial.
The function should accept a string template name and return a
template string of type unicode (not a subclass).
literal: the function used to convert unescaped variable tag
values to unicode, e.g. the value corresponding to a tag
"{{{name}}}". The function should accept a string of type
...
...
@@ -59,17 +63,21 @@ class RenderEngine(object):
incoming strings of type markupsafe.Markup differently
from plain unicode strings.
resolve_context: the function to call to resolve a name against
a context stack. The function should accept two positional
arguments: a ContextStack instance and a name to resolve.
resolve_partial: the function to call when loading a partial.
The function should accept a template name string and return a
template string of type unicode (not a subclass).
"""
self
.
escape
=
escape
self
.
literal
=
literal
self
.
resolve_context
=
resolve_context
self
.
resolve_partial
=
resolve_partial
def
resolve_context
(
self
,
stack
,
name
):
try
:
return
stack
.
get
(
name
)
except
KeyNotFoundError
:
return
u''
# TODO: Rename context to stack throughout this module.
def
_get_string_value
(
self
,
context
,
tag_name
):
"""
Get a value from the given context as a basestring instance.
...
...
pystache/renderer.py
View file @
1953e28d
...
...
@@ -9,9 +9,9 @@ import sys
from
pystache
import
defaults
from
pystache.common
import
TemplateNotFoundError
,
MissingTags
from
pystache.context
import
ContextStack
from
pystache.context
import
ContextStack
,
KeyNotFoundError
from
pystache.loader
import
Loader
from
pystache.renderengine
import
RenderEngine
from
pystache.renderengine
import
context_get
,
RenderEngine
from
pystache.specloader
import
SpecLoader
from
pystache.template_spec
import
TemplateSpec
...
...
@@ -258,6 +258,13 @@ class Renderer(object):
return
load_partial
def
_is_missing_tags_strict
(
self
):
"""
Return whether missing_tags is set to strict.
"""
return
self
.
missing_tags
==
MissingTags
.
strict
def
_make_resolve_partial
(
self
):
"""
Return the resolve_partial function to pass to RenderEngine.__init__().
...
...
@@ -265,7 +272,7 @@ class Renderer(object):
"""
load_partial
=
self
.
_make_load_partial
()
if
self
.
missing_tags
==
MissingTags
.
strict
:
if
self
.
_is_missing_tags_strict
()
:
return
load_partial
# Otherwise, ignore missing tags.
...
...
@@ -277,16 +284,35 @@ class Renderer(object):
return
resolve_partial
def
_make_resolve_context
(
self
):
"""
Return the resolve_context function to pass to RenderEngine.__init__().
"""
if
self
.
_is_missing_tags_strict
():
return
context_get
# Otherwise, ignore missing tags.
def
resolve_context
(
stack
,
name
):
try
:
return
context_get
(
stack
,
name
)
except
KeyNotFoundError
:
return
u''
return
resolve_context
def
_make_render_engine
(
self
):
"""
Return a RenderEngine instance for rendering.
"""
resolve_context
=
self
.
_make_resolve_context
()
resolve_partial
=
self
.
_make_resolve_partial
()
engine
=
RenderEngine
(
resolve_partial
=
resolve_partial
,
literal
=
self
.
_to_unicode_hard
,
escape
=
self
.
_escape_to_unicode
)
engine
=
RenderEngine
(
literal
=
self
.
_to_unicode_hard
,
escape
=
self
.
_escape_to_unicode
,
resolve_context
=
resolve_context
,
resolve_partial
=
resolve_partial
)
return
engine
# TODO: add unit tests for this method.
...
...
pystache/tests/test_renderengine.py
View file @
1953e28d
...
...
@@ -7,11 +7,11 @@ Unit tests of renderengine.py.
import
unittest
from
pystache.context
import
ContextStack
from
pystache.context
import
ContextStack
,
KeyNotFoundError
from
pystache
import
defaults
from
pystache.parser
import
ParsingError
from
pystache.renderengine
import
RenderEngine
from
pystache.tests.common
import
AssertStringMixin
,
Attachable
from
pystache.renderengine
import
context_get
,
RenderEngine
from
pystache.tests.common
import
AssertStringMixin
,
A
ssertExceptionMixin
,
A
ttachable
def
mock_literal
(
s
):
...
...
@@ -52,7 +52,7 @@ class RenderEngineTestCase(unittest.TestCase):
self
.
assertEqual
(
engine
.
resolve_partial
,
"foo"
)
class
RenderTests
(
unittest
.
TestCase
,
AssertStringMixin
):
class
RenderTests
(
unittest
.
TestCase
,
AssertStringMixin
,
AssertExceptionMixin
):
"""
Tests RenderEngine.render().
...
...
@@ -69,7 +69,10 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
"""
escape
=
defaults
.
TAG_ESCAPE
engine
=
RenderEngine
(
literal
=
unicode
,
escape
=
escape
,
resolve_partial
=
None
)
engine
=
RenderEngine
(
literal
=
unicode
,
escape
=
escape
,
resolve_context
=
context_get
,
resolve_partial
=
None
)
return
engine
def
_assert_render
(
self
,
expected
,
template
,
*
context
,
**
kwargs
):
...
...
@@ -594,33 +597,15 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
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
):
"""
Test dot notation with missing keys or attributes.
Check that if a key or attribute in a dotted name does not exist, then
the tag renders as the empty string.
"""
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
):
"""
Test dot notation with multiple levels.
"""
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}}."""
I see you're back from {{person.travels.last.country.city}}."""
expected
=
u"""Hello, Mr. Pither.
I see you're back from Cornwall.
I'm missing some of your details: ."""
I see you're back from Cornwall."""
context
=
{
'person'
:
{
'name'
:
{
'firstname'
:
'unknown'
,
'lastname'
:
'Pither'
},
'travels'
:
{
'last'
:
{
'country'
:
{
'city'
:
'Cornwall'
}}},
'details'
:
{
'public'
:
'likes cycling'
}}}
...
...
@@ -652,6 +637,14 @@ class RenderTests(unittest.TestCase, AssertStringMixin):
https://github.com/mustache/spec/pull/48
"""
template
=
'{{a.b}} :: ({{#c}}{{a}} :: {{a.b}}{{/c}})'
context
=
{
'a'
:
{
'b'
:
'A.B'
},
'c'
:
{
'a'
:
'A'
}
}
self
.
_assert_render
(
u'A.B :: (A :: )'
,
template
,
context
)
template
=
'{{a.b}}'
self
.
_assert_render
(
u'A.B'
,
template
,
context
)
template
=
'{{#c}}{{a}}{{/c}}'
self
.
_assert_render
(
u'A'
,
template
,
context
)
template
=
'{{#c}}{{a.b}}{{/c}}'
self
.
assertException
(
KeyNotFoundError
,
"Key u'a.b' not found: missing u'b'"
,
self
.
_assert_render
,
u'A.B :: (A :: )'
,
template
,
context
)
pystache/tests/test_renderer.py
View file @
1953e28d
...
...
@@ -14,6 +14,7 @@ from examples.simple import Simple
from
pystache
import
Renderer
from
pystache
import
TemplateSpec
from
pystache.common
import
TemplateNotFoundError
from
pystache.context
import
ContextStack
,
KeyNotFoundError
from
pystache.loader
import
Loader
from
pystache.tests.common
import
get_data_path
,
AssertStringMixin
,
AssertExceptionMixin
...
...
@@ -461,7 +462,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
self
.
assertEqual
(
actual
,
"abc"
)
self
.
assertEqual
(
type
(
actual
),
unicode
)
def
test__resolve_partial__not_found
__default
(
self
):
def
test__resolve_partial__not_found
(
self
):
"""
Check that resolve_partial returns the empty string when a template is not found.
...
...
@@ -473,7 +474,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
self
.
assertString
(
resolve_partial
(
'foo'
),
u''
)
def
test__resolve_partial__not_found__
strict__defaul
t
(
self
):
def
test__resolve_partial__not_found__
missing_tags_stric
t
(
self
):
"""
Check that resolve_partial provides a nice message when a template is not found.
...
...
@@ -487,7 +488,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
self
.
assertException
(
TemplateNotFoundError
,
"File 'foo.mustache' not found in dirs: ['.']"
,
resolve_partial
,
"foo"
)
def
test__resolve_partial__not_found__dict
(
self
):
def
test__resolve_partial__not_found__
partials_
dict
(
self
):
"""
Check that resolve_partial returns the empty string when a template is not found.
...
...
@@ -500,7 +501,7 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
self
.
assertString
(
resolve_partial
(
'foo'
),
u''
)
def
test__resolve_partial__not_found__
strict__d
ict
(
self
):
def
test__resolve_partial__not_found__
partials_dict__missing_tags_str
ict
(
self
):
"""
Check that resolve_partial provides a nice message when a template is not found.
...
...
@@ -638,3 +639,34 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase, AssertStringMixin, Asser
self
.
assertTrue
(
isinstance
(
s
,
unicode
))
self
.
assertEqual
(
type
(
escape
(
s
)),
unicode
)
## Test the engine's resolve_context attribute.
def
test__resolve_context
(
self
):
"""
Check resolve_context(): default arguments.
"""
renderer
=
Renderer
()
engine
=
renderer
.
_make_render_engine
()
stack
=
ContextStack
({
'foo'
:
'bar'
})
self
.
assertEqual
(
'bar'
,
engine
.
resolve_context
(
stack
,
'foo'
))
self
.
assertString
(
u''
,
engine
.
resolve_context
(
stack
,
'missing'
))
def
test__resolve_context__missing_tags_strict
(
self
):
"""
Check resolve_context(): missing_tags 'strict'.
"""
renderer
=
Renderer
()
renderer
.
missing_tags
=
'strict'
engine
=
renderer
.
_make_render_engine
()
stack
=
ContextStack
({
'foo'
:
'bar'
})
self
.
assertEqual
(
'bar'
,
engine
.
resolve_context
(
stack
,
'foo'
))
self
.
assertException
(
KeyNotFoundError
,
"Key 'missing' not found: first part"
,
engine
.
resolve_context
,
stack
,
'missing'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment