# -*- coding: utf-8 -*-
"""
Use nose
`$ pip install nose`
`$ nosetests`
Some code borrowed from rwbench.py from the jinja2 examples
"""
from datetime import datetime
from random import choice, randrange
from hyde._compat import PY3
from hyde.ext.templates.jinja import Jinja2Template
from hyde.site import Site
from hyde.generator import Generator
from hyde.model import Config
from fswrap import File
from jinja2.utils import generate_lorem_ipsum
from nose.plugins.skip import SkipTest
from nose.tools import nottest, eq_
from pyquery import PyQuery
import yaml
ROOT = File(__file__).parent
JINJA2 = ROOT.child_folder('templates/jinja2')
class Article(object):
def __init__(self, id):
self.id = id
self.href = '/article/%d' % self.id
self.title = generate_lorem_ipsum(1, False, 5, 10)
self.user = choice(users)
self.body = generate_lorem_ipsum()
self.pub_date = datetime.utcfromtimestamp(
randrange(10 ** 9, 2 * 10 ** 9))
self.published = True
def dateformat(x):
return x.strftime('%Y-%m-%d')
class User(object):
def __init__(self, username):
self.href = '/user/%s' % username
self.username = username
users = list(map(User, [u'John Doe', u'Jane Doe', u'Peter Somewhat']))
articles = map(Article, range(20))
navigation = [
('index', 'Index'),
('about', 'About'),
('foo?bar=1', 'Foo with Bar'),
('foo?bar=2&s=x', 'Foo with X'),
('blah', 'Blub Blah'),
('hehe', 'Haha'),
] * 5
context = dict(users=users, articles=articles, page_navigation=navigation)
def test_render():
"""
Uses pyquery to test the html structure for validity
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
source = File(JINJA2.child('index.html')).read_all()
html = t.render(source, context)
actual = PyQuery(html)
assert actual(".navigation li").length == 30
assert actual("div.article").length == 20
assert actual("div.article h2").length == 20
assert actual("div.article h2 a").length == 20
assert actual("div.article p.meta").length == 20
assert actual("div.article div.text").length == 20
def test_typogrify():
source = """
{%filter typogrify%}
One & two
{%endfilter%}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
html = t.render(source, {}).strip()
assert html == u'One & two'
def test_spaceless():
source = """
{%spaceless%}
{%endspaceless%}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
html = t.render(source, {}).strip()
expected = u"""
"""
assert html.strip() == expected.strip()
def test_asciidoc():
if PY3:
# asciidoc is not supported under Python 3. Supporting it is out
# of the scope of this project, so its tests are simply skipped
# when run under Python 3.
raise SkipTest
source = """
{%asciidoc%}
== Heading 2 ==
* test1
* test2
* test3
{%endasciidoc%}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(source, {}).strip()
assert html
q = PyQuery(html)
assert q
assert q("li").length == 3
assert q("li:nth-child(1)").text().strip() == "test1"
assert q("li:nth-child(2)").text().strip() == "test2"
assert q("li:nth-child(3)").text().strip() == "test3"
def test_markdown():
source = """
{%markdown%}
### Heading 3
{%endmarkdown%}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(source, {}).strip()
assert html == u'Heading 3
'
def test_restructuredtext():
source = """
{% restructuredtext %}
Hello
=====
{% endrestructuredtext %}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(source, {}).strip()
assert html == u"""
Hello
""", html
def test_restructuredtext_with_sourcecode():
source = """
{% restructuredtext %}
Code
====
.. sourcecode:: python
def add(a, b):
return a + b
See `Example`_
.. _Example: example.html
{% endrestructuredtext %}
"""
expected = ("""
Code
def """
"""add("""
"""a"""
""", b"""
"""):
return a """
"""+ b
See Example
""")
t = Jinja2Template(JINJA2.path)
s = Site(JINJA2.path)
c = Config(JINJA2.path, config_dict=dict(
restructuredtext=dict(highlight_source=True)))
s.config = c
t.configure(s)
html = t.render(source, {}).strip()
eq_(html.strip(), expected.strip())
def test_markdown_with_extensions():
source = """
{%markdown%}
### Heading 3
{%endmarkdown%}
"""
t = Jinja2Template(JINJA2.path)
s = Site(JINJA2.path)
c = Config(JINJA2.path, config_dict=dict(
markdown=dict(extensions=['headerid'])))
s.config = c
t.configure(s)
t.env.filters['dateformat'] = dateformat
html = t.render(source, {}).strip()
assert html == u'Heading 3
'
def test_markdown_with_sourcecode():
source = """
{%markdown%}
# Code
:::python
def add(a, b):
return a + b
See [Example][]
[Example]: example.html
{%endmarkdown%}
"""
expected = ("""
Code
def """
"""add("""
"""a, """
"""b):
return a +"""
""" b
See Example
""")
t = Jinja2Template(JINJA2.path)
s = Site(JINJA2.path)
c = Config(JINJA2.path, config_dict=dict(
markdown=dict(extensions=['codehilite'])))
s.config = c
t.configure(s)
html = t.render(source, {}).strip()
eq_(html.strip(), expected.strip())
def test_line_statements():
source = """
$$$ markdown
### Heading 3
$$$ endmarkdown
"""
t = Jinja2Template(JINJA2.path)
s = Site(JINJA2.path)
c = Config(JINJA2.path, config_dict=dict(
markdown=dict(extensions=['headerid'])))
s.config = c
t.configure(s)
t.env.filters['dateformat'] = dateformat
html = t.render(source, {}).strip()
assert html == u'Heading 3
'
def test_line_statements_with_config():
source = """
%% markdown
### Heading 3
%% endmarkdown
"""
config = """
markdown:
extensions:
- headerid
jinja2:
line_statement_prefix: '%%'
"""
t = Jinja2Template(JINJA2.path)
s = Site(JINJA2.path)
s.config = Config(JINJA2.path, config_dict=yaml.load(config))
t.configure(s)
t.env.filters['dateformat'] = dateformat
html = t.render(source, {}).strip()
assert html == u'Heading 3
'
TEST_SITE = File(__file__).parent.child_folder('_test')
@nottest
def assert_markdown_typogrify_processed_well(include_text, includer_text):
site = Site(TEST_SITE)
site.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin']
inc = File(TEST_SITE.child('content/inc.md'))
inc.write(include_text)
site.load()
gen = Generator(site)
gen.load_template_if_needed()
template = gen.template
html = template.render(includer_text, {}).strip()
assert html
q = PyQuery(html)
assert "is_processable" not in html
assert "This is a" in q("h1").text()
assert "heading" in q("h1").text()
assert q(".amp").length == 1
return html
class TestJinjaTemplate(object):
def setUp(self):
TEST_SITE.make()
TEST_SITE.parent.child_folder(
'sites/test_jinja').copy_contents_to(TEST_SITE)
def tearDown(self):
TEST_SITE.delete()
def test_depends(self):
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
deps = list(t.get_dependencies('index.html'))
assert len(deps) == 2
assert 'helpers.html' in deps
assert 'layout.html' in deps
def test_depends_multi_level(self):
site = Site(TEST_SITE)
JINJA2.copy_contents_to(site.content.source)
inc = File(TEST_SITE.child('content/inc.md'))
inc.write("{% extends 'index.html' %}")
site.load()
gen = Generator(site)
gen.load_template_if_needed()
t = gen.template
deps = list(t.get_dependencies('inc.md'))
assert len(deps) == 3
assert 'helpers.html' in deps
assert 'layout.html' in deps
assert 'index.html' in deps
def test_line_statements_with_blocks(self):
site = Site(TEST_SITE)
JINJA2.copy_contents_to(site.content.source)
text = """
{% extends 'index.html' %}
$$$ block body
Heya
$$$ endblock
"""
site.load()
gen = Generator(site)
gen.load_template_if_needed()
template = gen.template
template.env.filters['dateformat'] = dateformat
html = template.render(text, {}).strip()
assert html
q = PyQuery(html)
article = q("#article")
assert article.length == 1
assert article.text() == "Heya"
def test_depends_with_reference_tag(self):
site = Site(TEST_SITE)
JINJA2.copy_contents_to(site.content.source)
inc = File(TEST_SITE.child('content/inc.md'))
inc.write("{% refer to 'index.html' as index%}")
site.load()
gen = Generator(site)
gen.load_template_if_needed()
t = gen.template
deps = list(t.get_dependencies('inc.md'))
assert len(deps) == 3
assert 'helpers.html' in deps
assert 'layout.html' in deps
assert 'index.html' in deps
def test_cant_find_depends_with_reference_tag_var(self):
site = Site(TEST_SITE)
JINJA2.copy_contents_to(site.content.source)
inc = File(TEST_SITE.child('content/inc.md'))
inc.write("{% set ind = 'index.html' %}{% refer to ind as index %}")
site.load()
gen = Generator(site)
gen.load_template_if_needed()
t = gen.template
deps = list(t.get_dependencies('inc.md'))
assert len(deps) == 1
assert not deps[0]
def test_can_include_templates_with_processing(self):
text = """
===
is_processable: False
===
{% filter typogrify %}{% markdown %}
This is a heading
=================
Hyde & Jinja.
{% endmarkdown %}{% endfilter %}
"""
text2 = """{% include "inc.md" %}"""
assert_markdown_typogrify_processed_well(text, text2)
def test_includetext(self):
text = """
===
is_processable: False
===
This is a heading
=================
Hyde & Jinja.
"""
text2 = """{% includetext "inc.md" %}"""
assert_markdown_typogrify_processed_well(text, text2)
def test_reference_is_noop(self):
text = """
===
is_processable: False
===
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
"""
text2 = """{% includetext "inc.md" %}"""
html = assert_markdown_typogrify_processed_well(text, text2)
assert "mark" not in html
assert "reference" not in html
def test_reference_is_not_callable(self):
text = """
===
is_processable: False
===
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
{% mark repeated %}
Junk
{% endmark %}
{{ self.repeated() }}
{{ self.repeated }}
"""
text2 = """{% includetext "inc.md" %}"""
html = assert_markdown_typogrify_processed_well(text, text2)
assert "mark" not in html
assert "reference" not in html
q = PyQuery(html)
assert q("span.junk").length == 1
def test_refer(self):
text = """
===
is_processable: False
===
{% filter markdown|typogrify %}
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
{% endfilter %}
"""
text2 = """
{% refer to "inc.md" as inc %}
{% filter markdown|typogrify %}
{{ inc.heading }}
{{ inc.content }}
{% endfilter %}
"""
html = assert_markdown_typogrify_processed_well(text, text2)
assert "mark" not in html
assert "reference" not in html
def test_refer_with_full_html(self):
text = """
===
is_processable: False
===
{% filter markdown|typogrify %}
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
{% endfilter %}
"""
text2 = """
{% refer to "inc.md" as inc %}
{{ inc.html('.fulltext') }}
"""
html = assert_markdown_typogrify_processed_well(text, text2)
assert "mark" not in html
assert "reference" not in html
def test_two_level_refer_with_var(self):
text = """
===
is_processable: False
===
{% filter markdown|typogrify %}
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
{% endfilter %}
"""
text2 = """
{% set super = 'super.md' %}
{% refer to super as sup %}
{% mark child %}
{{ sup.heading }}
{% endmark %}
{% mark cont %}
{{ sup.content }}
{% endmark %}
"""
text3 = """
{% set incu = 'inc.md' %}
{% refer to incu as inc %}
{% filter markdown|typogrify %}
{{ inc.child }}
{{ inc.cont }}
{% endfilter %}
"""
superinc = File(TEST_SITE.child('content/super.md'))
superinc.write(text)
html = assert_markdown_typogrify_processed_well(text2, text3)
assert "mark" not in html
assert "reference" not in html
def test_refer_with_var(self):
text = """
===
is_processable: False
===
{% filter markdown|typogrify %}
{% mark heading %}
This is a heading
=================
{% endmark %}
{% reference content %}
Hyde & Jinja.
{% endreference %}
{% endfilter %}
"""
text2 = """
{% set incu = 'inc.md' %}
{% refer to incu as inc %}
{{ inc.html('.fulltext') }}
"""
html = assert_markdown_typogrify_processed_well(text, text2)
assert "mark" not in html
assert "reference" not in html
def test_yaml_tag(self):
text = """
{% yaml test %}
one:
- A
- B
- C
two:
- D
- E
- F
{% endyaml %}
{% for section, values in test.items() %}
{% for value in values %}
- {{ value }}
{% endfor %}
{% endfor %}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
html = t.render(text, {}).strip()
actual = PyQuery(html)
assert actual("ul").length == 2
assert actual("ul.one").length == 1
assert actual("ul.two").length == 1
assert actual("li").length == 6
assert actual("ul.one li").length == 3
assert actual("ul.two li").length == 3
ones = [item.text for item in actual("ul.one li")]
assert ones == ["A", "B", "C"]
twos = [item.text for item in actual("ul.two li")]
assert twos == ["D", "E", "F"]
def test_top_filter(self):
text = """
{% yaml test %}
item_list:
- A
- B
- C
- D
- E
- F
{% endyaml %}
{% for value in test.item_list|top(3) %}
- {{ value }}
{% endfor %}
{% for value in test.item_list|islice(3, 6) %}
- {{ value }}
{% endfor %}
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
t.env.filters['dateformat'] = dateformat
html = t.render(text, {}).strip()
actual = PyQuery(html)
assert actual("ul").length == 2
assert actual("li").length == 6
items = [item.text for item in actual("ul.top li")]
assert items == ["A", "B", "C"]
items = [item.text for item in actual("ul.mid li")]
assert items == ["D", "E", "F"]
def test_raw_tag(self):
expected = """
"""
text = "{%% raw %%}%s{%% endraw %%}" % expected
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(text, {}).strip()
assert html.strip() == expected.strip()
def test_raw_tag_with_markdown_typogrify(self):
expected = """
"""
text = """{%% filter markdown|typogrify %%}{%% raw
%%}%s{%% endraw %%}{%% endfilter %%}""" % expected
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(text, {}).strip()
assert html.strip() == expected.strip()
def test_urlencode_filter(self):
text = u"""
фотографияquoted
"""
expected = u"""
фотографияquoted
"""
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(text, {}).strip()
assert html.strip() == expected.strip()
def test_urldecode_filter(self):
text = u"""
{{
"%D1%84%D0%BE%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F.jpg"|urldecode
}}
"""
expected = (u'
фотография.jpg')
t = Jinja2Template(JINJA2.path)
t.configure(None)
html = t.render(text, {}).strip()
assert html.strip() == expected.strip()