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
5a94c93b
Commit
5a94c93b
authored
May 03, 2012
by
Chris Jerdonek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Addressed issue #115: "Match spec expectation for partials not found"
parent
27f2ae76
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
78 additions
and
26 deletions
+78
-26
HISTORY.rst
+1
-0
ext/spec
+1
-1
pystache/commands/render.py
+2
-1
pystache/common.py
+11
-1
pystache/locator.py
+2
-2
pystache/parsed.py
+3
-0
pystache/parser.py
+9
-4
pystache/renderengine.py
+2
-1
pystache/renderer.py
+3
-3
pystache/tests/common.py
+14
-0
pystache/tests/test_locator.py
+5
-3
pystache/tests/test_renderer.py
+21
-8
pystache/tests/test_specloader.py
+4
-2
No files found.
HISTORY.rst
View file @
5a94c93b
...
@@ -5,6 +5,7 @@ History
...
@@ -5,6 +5,7 @@ History
-----------
-----------
* Added support for dot notation and version 1.1.2 of the spec (issue #99). [rbp]
* Added support for dot notation and version 1.1.2 of the spec (issue #99). [rbp]
* Missing partials now render as empty string per latest version of spec (issue #115).
* Bugfix: falsey values now coerced to strings using str().
* Bugfix: falsey values now coerced to strings using str().
* Bugfix: lambda return values for sections no longer pushed onto context stack (issue #113).
* Bugfix: lambda return values for sections no longer pushed onto context stack (issue #113).
* Bugfix: lists of lambdas for sections were not rendered (issue #114).
* Bugfix: lists of lambdas for sections were not rendered (issue #114).
...
...
spec
@
9b1bc7ad
Subproject commit
bf6288ed6bd0ce8ccea6f1dac070b3d779132c3b
Subproject commit
9b1bc7ad19247e9671304af02078f2ce30132665
pystache/commands/render.py
View file @
5a94c93b
...
@@ -35,6 +35,7 @@ import sys
...
@@ -35,6 +35,7 @@ import sys
#
#
# ValueError: Attempted relative import in non-package
# ValueError: Attempted relative import in non-package
#
#
from
pystache.common
import
TemplateNotFoundError
from
pystache.renderer
import
Renderer
from
pystache.renderer
import
Renderer
...
@@ -78,7 +79,7 @@ def main(sys_argv=sys.argv):
...
@@ -78,7 +79,7 @@ def main(sys_argv=sys.argv):
try
:
try
:
template
=
renderer
.
load_template
(
template
)
template
=
renderer
.
load_template
(
template
)
except
IO
Error
:
except
TemplateNotFound
Error
:
pass
pass
try
:
try
:
...
...
pystache/common.py
View file @
5a94c93b
# coding: utf-8
# coding: utf-8
"""
"""
Exposes
common functions
.
Exposes
functionality needed throughout the project
.
"""
"""
...
@@ -24,3 +24,13 @@ def read(path):
...
@@ -24,3 +24,13 @@ def read(path):
return
f
.
read
()
return
f
.
read
()
finally
:
finally
:
f
.
close
()
f
.
close
()
class
PystacheError
(
Exception
):
"""Base class for Pystache exceptions."""
pass
class
TemplateNotFoundError
(
PystacheError
):
"""An exception raised when a template is not found."""
pass
pystache/locator.py
View file @
5a94c93b
...
@@ -9,6 +9,7 @@ import os
...
@@ -9,6 +9,7 @@ import os
import
re
import
re
import
sys
import
sys
from
pystache.common
import
TemplateNotFoundError
from
pystache
import
defaults
from
pystache
import
defaults
...
@@ -117,8 +118,7 @@ class Locator(object):
...
@@ -117,8 +118,7 @@ class Locator(object):
path
=
self
.
_find_path
(
search_dirs
,
file_name
)
path
=
self
.
_find_path
(
search_dirs
,
file_name
)
if
path
is
None
:
if
path
is
None
:
# TODO: we should probably raise an exception of our own type.
raise
TemplateNotFoundError
(
'File
%
s not found in dirs:
%
s'
%
raise
IOError
(
'Template file
%
s not found in directories:
%
s'
%
(
repr
(
file_name
),
repr
(
search_dirs
)))
(
repr
(
file_name
),
repr
(
search_dirs
)))
return
path
return
path
...
...
pystache/parsed.py
View file @
5a94c93b
...
@@ -32,6 +32,9 @@ class ParsedTemplate(object):
...
@@ -32,6 +32,9 @@ class ParsedTemplate(object):
"""
"""
self
.
_parse_tree
=
parse_tree
self
.
_parse_tree
=
parse_tree
def
__repr__
(
self
):
return
"[
%
s]"
%
(
", "
.
join
([
repr
(
part
)
for
part
in
self
.
_parse_tree
]))
def
render
(
self
,
context
):
def
render
(
self
,
context
):
"""
"""
Returns: a string of type unicode.
Returns: a string of type unicode.
...
...
pystache/parser.py
View file @
5a94c93b
...
@@ -9,12 +9,13 @@ This module is only meant for internal use by the renderengine module.
...
@@ -9,12 +9,13 @@ This module is only meant for internal use by the renderengine module.
import
re
import
re
from
pystache.common
import
TemplateNotFoundError
from
pystache.parsed
import
ParsedTemplate
from
pystache.parsed
import
ParsedTemplate
DEFAULT_DELIMITERS
=
(
'{{'
,
'}}'
)
DEFAULT_DELIMITERS
=
(
u'{{'
,
u
'}}'
)
END_OF_LINE_CHARACTERS
=
[
'
\r
'
,
'
\n
'
]
END_OF_LINE_CHARACTERS
=
[
u'
\r
'
,
u
'
\n
'
]
NON_BLANK_RE
=
re
.
compile
(
r'^(.)'
,
re
.
M
)
NON_BLANK_RE
=
re
.
compile
(
u
r'^(.)'
,
re
.
M
)
def
_compile_template_re
(
delimiters
=
None
):
def
_compile_template_re
(
delimiters
=
None
):
...
@@ -215,10 +216,14 @@ class Parser(object):
...
@@ -215,10 +216,14 @@ class Parser(object):
elif
tag_type
==
'>'
:
elif
tag_type
==
'>'
:
try
:
# TODO: make engine.load() and test it separately.
template
=
engine
.
load_partial
(
tag_key
)
template
=
engine
.
load_partial
(
tag_key
)
except
TemplateNotFoundError
:
template
=
u''
# Indent before rendering.
# Indent before rendering.
template
=
re
.
sub
(
NON_BLANK_RE
,
leading_whitespace
+
r'\1'
,
template
)
template
=
re
.
sub
(
NON_BLANK_RE
,
leading_whitespace
+
u
r'\1'
,
template
)
func
=
engine
.
_make_get_partial
(
template
)
func
=
engine
.
_make_get_partial
(
template
)
...
...
pystache/renderengine.py
View file @
5a94c93b
...
@@ -35,7 +35,8 @@ class RenderEngine(object):
...
@@ -35,7 +35,8 @@ class RenderEngine(object):
load_partial: the function to call when loading a partial. The
load_partial: the function to call when loading a partial. The
function should accept a string template name and return a
function should accept a string template name and return a
template string of type unicode (not a subclass).
template string of type unicode (not a subclass). If the
template is not found, it should raise a TemplateNotFoundError.
literal: the function used to convert unescaped variable tag
literal: the function used to convert unescaped variable tag
values to unicode, e.g. the value corresponding to a tag
values to unicode, e.g. the value corresponding to a tag
...
...
pystache/renderer.py
View file @
5a94c93b
...
@@ -8,6 +8,7 @@ This module provides a Renderer class to render templates.
...
@@ -8,6 +8,7 @@ This module provides a Renderer class to render templates.
import
sys
import
sys
from
pystache
import
defaults
from
pystache
import
defaults
from
pystache.common
import
TemplateNotFoundError
from
pystache.context
import
ContextStack
from
pystache.context
import
ContextStack
from
pystache.loader
import
Loader
from
pystache.loader
import
Loader
from
pystache.renderengine
import
RenderEngine
from
pystache.renderengine
import
RenderEngine
...
@@ -239,9 +240,8 @@ class Renderer(object):
...
@@ -239,9 +240,8 @@ class Renderer(object):
template
=
partials
.
get
(
name
)
template
=
partials
.
get
(
name
)
if
template
is
None
:
if
template
is
None
:
# TODO: make a TemplateNotFoundException type that provides
raise
TemplateNotFoundError
(
"Name
%
s not found in partials:
%
s"
%
# the original partials as an attribute.
(
repr
(
name
),
type
(
partials
)))
raise
Exception
(
"Partial not found with name:
%
s"
%
repr
(
name
))
# RenderEngine requires that the return value be unicode.
# RenderEngine requires that the return value be unicode.
return
self
.
_to_unicode_hard
(
template
)
return
self
.
_to_unicode_hard
(
template
)
...
...
pystache/tests/common.py
View file @
5a94c93b
...
@@ -168,6 +168,20 @@ class AssertIsMixin:
...
@@ -168,6 +168,20 @@ class AssertIsMixin:
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
AssertExceptionMixin
:
"""A unittest.TestCase mixin adding assertException()."""
# unittest.assertRaisesRegexp() is not available until Python 2.7:
# http://docs.python.org/library/unittest.html#unittest.TestCase.assertRaisesRegexp
def
assertException
(
self
,
exception_type
,
msg
,
callable
,
*
args
,
**
kwds
):
try
:
callable
(
*
args
,
**
kwds
)
raise
Exception
(
"Expected exception:
%
s:
%
s"
%
(
exception_type
,
repr
(
msg
)))
except
exception_type
,
err
:
self
.
assertEqual
(
str
(
err
),
msg
)
class
SetupDefaults
(
object
):
class
SetupDefaults
(
object
):
"""
"""
...
...
pystache/tests/test_locator.py
View file @
5a94c93b
...
@@ -11,14 +11,15 @@ import sys
...
@@ -11,14 +11,15 @@ import sys
import
unittest
import
unittest
# TODO: remove this alias.
# TODO: remove this alias.
from
pystache.common
import
TemplateNotFoundError
from
pystache.loader
import
Loader
as
Reader
from
pystache.loader
import
Loader
as
Reader
from
pystache.locator
import
Locator
from
pystache.locator
import
Locator
from
pystache.tests.common
import
DATA_DIR
,
EXAMPLES_DIR
from
pystache.tests.common
import
DATA_DIR
,
EXAMPLES_DIR
,
AssertExceptionMixin
from
pystache.tests.data.views
import
SayHello
from
pystache.tests.data.views
import
SayHello
class
LocatorTests
(
unittest
.
TestCase
):
class
LocatorTests
(
unittest
.
TestCase
,
AssertExceptionMixin
):
def
_locator
(
self
):
def
_locator
(
self
):
return
Locator
(
search_dirs
=
DATA_DIR
)
return
Locator
(
search_dirs
=
DATA_DIR
)
...
@@ -110,7 +111,8 @@ class LocatorTests(unittest.TestCase):
...
@@ -110,7 +111,8 @@ class LocatorTests(unittest.TestCase):
def
test_find_name__non_existent_template_fails
(
self
):
def
test_find_name__non_existent_template_fails
(
self
):
locator
=
Locator
()
locator
=
Locator
()
self
.
assertRaises
(
IOError
,
locator
.
find_name
,
search_dirs
=
[],
template_name
=
'doesnt_exist'
)
self
.
assertException
(
TemplateNotFoundError
,
"File 'doesnt_exist.mustache' not found in dirs: []"
,
locator
.
find_name
,
search_dirs
=
[],
template_name
=
'doesnt_exist'
)
def
test_find_object
(
self
):
def
test_find_object
(
self
):
locator
=
Locator
()
locator
=
Locator
()
...
...
pystache/tests/test_renderer.py
View file @
5a94c93b
...
@@ -13,9 +13,10 @@ import unittest
...
@@ -13,9 +13,10 @@ import unittest
from
examples.simple
import
Simple
from
examples.simple
import
Simple
from
pystache
import
Renderer
from
pystache
import
Renderer
from
pystache
import
TemplateSpec
from
pystache
import
TemplateSpec
from
pystache.common
import
TemplateNotFoundError
from
pystache.loader
import
Loader
from
pystache.loader
import
Loader
from
pystache.tests.common
import
get_data_path
,
AssertStringMixin
from
pystache.tests.common
import
get_data_path
,
AssertStringMixin
,
AssertExceptionMixin
from
pystache.tests.data.views
import
SayHello
from
pystache.tests.data.views
import
SayHello
...
@@ -405,7 +406,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
...
@@ -405,7 +406,7 @@ class RendererTests(unittest.TestCase, AssertStringMixin):
# we no longer need to exercise all rendering code paths through
# we no longer need to exercise all rendering code paths through
# the Renderer. It suffices to test rendering paths through the
# the Renderer. It suffices to test rendering paths through the
# RenderEngine for the same amount of code coverage.
# RenderEngine for the same amount of code coverage.
class
Renderer_MakeRenderEngineTests
(
unittest
.
TestCase
):
class
Renderer_MakeRenderEngineTests
(
unittest
.
TestCase
,
AssertExceptionMixin
):
"""
"""
Check the RenderEngine returned by Renderer._make_render_engine().
Check the RenderEngine returned by Renderer._make_render_engine().
...
@@ -444,7 +445,20 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
...
@@ -444,7 +445,20 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
self
.
assertEqual
(
actual
,
"abc"
)
self
.
assertEqual
(
actual
,
"abc"
)
self
.
assertEqual
(
type
(
actual
),
unicode
)
self
.
assertEqual
(
type
(
actual
),
unicode
)
def
test__load_partial__not_found
(
self
):
def
test__load_partial__not_found__default
(
self
):
"""
Check that load_partial provides a nice message when a template is not found.
"""
renderer
=
Renderer
()
engine
=
renderer
.
_make_render_engine
()
load_partial
=
engine
.
load_partial
self
.
assertException
(
TemplateNotFoundError
,
"File 'foo.mustache' not found in dirs: ['.']"
,
load_partial
,
"foo"
)
def
test__load_partial__not_found__dict
(
self
):
"""
"""
Check that load_partial provides a nice message when a template is not found.
Check that load_partial provides a nice message when a template is not found.
...
@@ -455,11 +469,10 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
...
@@ -455,11 +469,10 @@ class Renderer_MakeRenderEngineTests(unittest.TestCase):
engine
=
renderer
.
_make_render_engine
()
engine
=
renderer
.
_make_render_engine
()
load_partial
=
engine
.
load_partial
load_partial
=
engine
.
load_partial
try
:
# Include dict directly since str(dict) is different in Python 2 and 3:
load_partial
(
"foo"
)
# <type 'dict'> versus <class 'dict'>, respectively.
raise
Exception
(
"Shouldn't get here"
)
self
.
assertException
(
TemplateNotFoundError
,
"Name 'foo' not found in partials:
%
s"
%
dict
,
except
Exception
,
err
:
load_partial
,
"foo"
)
self
.
assertEqual
(
str
(
err
),
"Partial not found with name: 'foo'"
)
## Test the engine's literal attribute.
## Test the engine's literal attribute.
...
...
pystache/tests/test_specloader.py
View file @
5a94c93b
...
@@ -16,6 +16,7 @@ from examples.lambdas import Lambdas
...
@@ -16,6 +16,7 @@ from examples.lambdas import Lambdas
from
examples.inverted
import
Inverted
,
InvertedLists
from
examples.inverted
import
Inverted
,
InvertedLists
from
pystache
import
Renderer
from
pystache
import
Renderer
from
pystache
import
TemplateSpec
from
pystache
import
TemplateSpec
from
pystache.common
import
TemplateNotFoundError
from
pystache.locator
import
Locator
from
pystache.locator
import
Locator
from
pystache.loader
import
Loader
from
pystache.loader
import
Loader
from
pystache.specloader
import
SpecLoader
from
pystache.specloader
import
SpecLoader
...
@@ -42,7 +43,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
...
@@ -42,7 +43,7 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
view
=
Tagless
()
view
=
Tagless
()
renderer
=
Renderer
()
renderer
=
Renderer
()
self
.
assertRaises
(
IO
Error
,
renderer
.
render
,
view
)
self
.
assertRaises
(
TemplateNotFound
Error
,
renderer
.
render
,
view
)
# 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"
...
@@ -60,7 +61,8 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
...
@@ -60,7 +61,8 @@ class ViewTestCase(unittest.TestCase, AssertStringMixin):
renderer1
=
Renderer
()
renderer1
=
Renderer
()
renderer2
=
Renderer
(
search_dirs
=
EXAMPLES_DIR
)
renderer2
=
Renderer
(
search_dirs
=
EXAMPLES_DIR
)
self
.
assertRaises
(
IOError
,
renderer1
.
render
,
spec
)
actual
=
renderer1
.
render
(
spec
)
self
.
assertString
(
actual
,
u"Partial: "
)
actual
=
renderer2
.
render
(
spec
)
actual
=
renderer2
.
render
(
spec
)
self
.
assertEqual
(
actual
,
"Partial: No tags..."
)
self
.
assertEqual
(
actual
,
"Partial: No tags..."
)
...
...
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