# -*- 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() %} {% 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 %} """ 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()