def test_inline_css_dev(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.html': '{{inline_css("theme/main.css")}}',
                'bar.html': "{{ url('theme/main.css') }}",
            },
            'theme': {
                'sass/main.scss': 'body {width: 10px + 10px;}',
            },
        })
    build(tmpdir, mode=Mode.development)
    assert gettree(tmpdir.join('dist')) == {
        'foo': {
            'index.html': ('body {\n'
                           '  width: 20px; }\n'
                           '\n'
                           '/*# sourceMappingURL=/theme/main.css.map */\n'),
        },
        'bar': {
            'index.html': RegexStr(r'/theme/main.css\?t=\d+\n'),
        },
        'theme': {
            'main.css.map':
            RegexStr('{.*'),
            'main.css': ('body {\n'
                         '  width: 20px; }\n'
                         '\n'
                         '/*# sourceMappingURL=main.css.map */'),
            '.src': {
                'main.scss': 'body {width: 10px + 10px;}',
            },
        },
    }
def test_ignore_no_template(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'ignore_this.md':
                'this file is ignored',
                'normal.md':
                'hello this is normal',
                'no_template.md':
                'this should be passed through as-is',
                'normal_but_no_output.md': ('---\n'
                                            'output: false\n'
                                            '---\n'
                                            'hello this is normal\n')
            },
            'theme': {
                'templates/foobar.jinja': 'rendered {{ content }}',
            },
            'harrier.yml': ('default_template: "foobar.jinja"\n'
                            'ignore:\n'
                            '- "**/ignore*"\n'
                            'defaults:\n'
                            '  "/no_temp*":\n'
                            '    pass_through: true\n')
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'no_template': {
            'index.html': 'this should be passed through as-is',
        },
        'normal': {
            'index.html': 'rendered <p>hello this is normal</p>\n',
        },
    }
def test_jinja_md_extensions(input, output, tmpdir):
    mktree(tmpdir, {
        'pages/index.html': input,
    })
    build(tmpdir, mode=Mode.production)
    # debug(tmpdir.join('dist/index.html').read_text('utf8'))
    assert tmpdir.join('dist/index.html').read_text('utf8') == output
Example #4
0
def test_full_build(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.html': ('{{ url("foobar.png") }}\n'
                                '{{ resolve_url("theme/main.css") }}\n'
                                '{{ resolve_url("another") }}\n'),
                'another.md':
                '# Hello',
                'third.yaml':
                'content: "hello there"',
            },
            'theme': {
                'sass/main.scss': 'body {width: 10px + 10px;}',
                'assets/foobar.png': '*',
            },
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'foobar': {
            'index.html': ('/foobar.3389dae.png\n'
                           '/theme/main.a1ac3a7.css\n'
                           '/another/\n'),
        },
        'another': {
            'index.html': '<h1 id="1-hello">Hello</h1>\n'
        },
        'theme': {
            'main.a1ac3a7.css': 'body{width:20px}\n',
        },
        'third': {
            'index.html': 'hello there\n'
        },
        'foobar.3389dae.png': '*',
    }
def test_markdown_extensions(input, output, tmpdir):
    mktree(tmpdir, {
        'pages': {
            'foobar.md': input,
        },
    })
    build(tmpdir, mode=Mode.production)
    assert tmpdir.join('dist/foobar/index.html').read_text('utf8') == output
Example #6
0
def test_extensions_ok(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
                'bar.html': '{{ 4|add_one }} {{ dynamic }}',
                'spam.html': 'before',
                'splat.html': '{{ 3 is two }} {{ 2 is two }}',
            },
            'theme/templates/main.jinja':
            '{{ content }}',
            'extensions.py':
            """
from harrier.extensions import modify, template

@modify.pages('/foo.*')
def modify_foo(page, config):
    page['content'] += ' changed by extension'
    return page

@modify.som
def add_var(site):
    site['dynamic'] = 42
    return site

@modify.som
def change_pages(site):
    site['pages']['/spam.html']['content'] = 'after'
    return site

@template.filter
def add_one(v):
    return v + 1

@template.test
def two(v):
    return v == 2
        """
        })

    build(str(tmpdir))
    assert gettree(tmpdir.join('dist')) == {
        'foo': {
            'index.html':
            '<h1 id="1-foo-changed-by-extension">foo changed by extension</h1>\n',
        },
        'bar': {
            'index.html': '5 42\n',
        },
        'spam': {
            'index.html': 'after\n',
        },
        'splat': {
            'index.html': 'False True\n',
        },
    }
Example #7
0
def test_build_no_templates(tmpdir):
    mktree(tmpdir, {
        'pages': {
            'foobar.md': ('### Whatever'),
        },
    })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'foobar': {
            'index.html': ('<h3 id="3-whatever">Whatever</h3>\n'),
        },
    }
Example #8
0
def test_bad_python(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
            },
            'theme/templates/main.jinja': '{{ content }}',
            'extensions.py': 'xxx'
        })

    with pytest.raises(ExtensionError):
        build(str(tmpdir))
def test_xml_no_front_matter(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.xml': ('<x><y>{{ config.whatever }}</y></x>'),
            },
            'harrier.yml': 'whatever: 123'
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'foobar.xml': '<x><y>{{ config.whatever }}</y></x>'
    }
Example #10
0
def test_pages_function(infile, outfile, tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': '1',
                'foobar.md': '2',
                'robots.txt': '3',
                'testing.html': infile,
            }
        })
    build(tmpdir, mode=Mode.production)
    # debug(tmpdir.join('dist/testing/index.html').read_text('utf8'))
    assert tmpdir.join('dist/testing/index.html').read_text('utf8') == outfile
Example #11
0
def test_render_error(tmpdir, caplog):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.html': '{{ 1/0 }}',
            },
            'theme': {
                'templates/main.jinja': '{{ content }}',
            },
        })
    with pytest.raises(HarrierProblem):
        build(tmpdir, mode=Mode.production)
    assert 'ZeroDivisionError: division by zero' in caplog.text
Example #12
0
def test_jinja_functions(input, output, tmpdir):
    mktree(
        tmpdir, {
            'pages/index.html': input,
            'theme/assets': {},
            'harrier.yml': 'paginate_by: 3',
        })
    img = Image.new('RGB', (60, 30), (255, 255, 255))
    img.save(str(tmpdir.join('theme/assets/image.png')), 'PNG')

    build(tmpdir, mode=Mode.production)
    # debug(tmpdir.join('dist/index.html').read_text('utf8'))
    assert tmpdir.join('dist/index.html').read_text('utf8') == output.replace(
        '{tmpdir}', str(tmpdir))
Example #13
0
def test_render_code_lang(tmpdir):
    mktree(tmpdir, {
        'pages': {
            'foobar.md': ('testing\n\n'
                          '```py\n'
                          'x = 4\n'
                          '```\n'),
        },
    })
    build(tmpdir, mode=Mode.production)
    assert tmpdir.join('dist/foobar/index.html').read_text('utf8') == (
        '<p>testing</p>\n'
        '<div class="hi"><pre><span></span><span class="n">x</span> '
        '<span class="o">=</span> <span class="mi">4</span>\n'
        '</pre></div>\n')
Example #14
0
def test_jinja_format(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html':
                '{{"{:0.2f}"|format(3.1415)}}',
                '2032-06-02-date.txt':
                '---\nx: 1\n---\n{{ "{:%b %d, %Y}"|format(page.created) }}',
            },
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'index.html': '3.14\n',
        'date.txt': 'Jun 02, 2032\n'
    }
Example #15
0
def test_no_trailing_slash(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': '<a href="{{ url("other") }}">link to other</a>',
                'other.html': 'xxx'
            },
            'harrier.yml': 'apply_trailing_slash: false'
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'other': {
            'index.html': 'xxx\n',
        },
        'index.html': '<a href="/other">link to other</a>\n',
    }
Example #16
0
def test_uri_key_error(tmpdir, caplog):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.html': ('---\n'
                                'uri: "{foo}/whatever"\n'
                                '---\n'
                                'hello'),
            },
            'theme': {
                'templates/main.jinja': '{{ content }}',
            },
        })
    with pytest.raises(KeyError):
        build(tmpdir, mode=Mode.production)
    assert 'missing format variable "foo" for "{foo}/whatever"' in caplog.text
Example #17
0
def test_generate_pages(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': 'hello',
            },
            'extensions.py':
            """
from pathlib import Path
from harrier.extensions import modify
THIS_DIR = Path(__file__).parent.resolve()

@modify.generate_pages
def add_extra_pages(som):
    config: Config = som['config']
    yield {
        'path': Path('extra/index.md'),
        'content': '# this is a test\\n\\nwith of generating pages dynamically',
    }
    yield {
        'path': Path('more/index.html'),
        'content': 'testing {{ page.x }}',
        'data': {
            'uri': '/foo-bar-whatever',
            'x': 123,
        }
    }
    (THIS_DIR / 'pages' / 'binary_file').write_bytes(b'xxx')
    yield {
        'path': 'binary_file',
        'content': None,
    }
    """
        })
    build(str(tmpdir))
    assert gettree(tmpdir.join('dist')) == {
        'extra': {
            'index.html': ('<h1 id="1-this-is-a-test">this is a test</h1>\n'
                           '\n'
                           '<p>with of generating pages dynamically</p>\n'),
        },
        'foo-bar-whatever': {
            'index.html': 'testing 123\n'
        },
        'index.html': 'hello\n',
        'binary_file': 'xxx',
    }
Example #18
0
def test_generate_pages_error(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': 'hello',
            },
            'extensions.py':
            """
from pathlib import Path
from harrier.extensions import modify

@modify.generate_pages
def add_extra_pages(som):
    raise RuntimeError('xx')
    """
        })
    with pytest.raises(ExtensionError):
        build(str(tmpdir))
Example #19
0
def test_yaml_render(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'test.yml': ('template: foobar.jinja\n'
                             'foo:\n'
                             '  bar: 42\n'),
            },
            'theme': {
                'templates/foobar.jinja': 'foo bar: {{ page.foo.bar }}',
            },
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'test': {
            'index.html': 'foo bar: 42\n'
        }
    }
Example #20
0
def test_pages_error(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
            },
            'extensions.py':
            """
from harrier.extensions import modify

@modify.pages('**/*')
def modify_pages(data, config):
    raise ValueError('xxx')
        """
        })

    with pytest.raises(ExtensionError) as exc_info:
        build(str(tmpdir), steps={BuildSteps.pages})
    assert exc_info.value.args[0] == 'xxx'
Example #21
0
def test_inline_css_prod(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.html': '{{inline_css("theme/main.css")}}'
            },
            'theme': {
                'sass/main.scss': 'body {width: 10px + 10px;}',
            },
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'foobar': {
            'index.html': ('body{width:20px}\n'),
        },
        'theme': {
            'main.a1ac3a7.css': 'body{width:20px}\n',
        },
    }
Example #22
0
def test_frontmatter_maybe(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foobar.xml': ('---\n'
                               'foo: bar\n'
                               '---\n'
                               '<x><y>{{ config.whatever }}</y></x>'),
                'foobar.txt': ('---\n'
                               'x: 1\n'
                               '---\n'
                               '{{ page.x }}'),
            },
            'harrier.yml': 'whatever: 123'
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'foobar.xml': '<x><y>123</y></x>\n',
        'foobar.txt': '1\n',
    }
Example #23
0
def test_copy_extensions_error(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': 'hello',
            },
            'theme/assets': {
                'foo/bar.svg': 'b',
            },
            'extensions.py':
            """
from harrier.extensions import modify, template

@modify.copy('/foo/*')
def modify_foo(in_path, out_path, config):
    raise RuntimeError('x')
    """
        })
    with pytest.raises(ExtensionError):
        build(str(tmpdir))
Example #24
0
def test_ext_error(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
            },
            'theme/templates/main.jinja':
            '{{ content }}',
            'extensions.py':
            """
from harrier.extensions import modify

@modify.config
def before(site):
    raise RuntimeError('xxx')
        """
        })

    with pytest.raises(ExtensionError) as exc_info:
        build(str(tmpdir))
    assert exc_info.value.args[0] == 'xxx'
Example #25
0
def test_broken_ext(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
            },
            'theme/templates/main.jinja':
            '{{ content }}',
            'extensions.py':
            """
from harrier.extensions import modify

@modify.config
def before(site):
    pass
        """
        })

    with pytest.raises(HarrierProblem) as exc_info:
        build(str(tmpdir))
    assert exc_info.value.args[
        0] == 'extension "before" did not return a Config object as expected'
Example #26
0
def test_generate_pages_invalid(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': 'hello',
            },
            'extensions.py':
            """
from pathlib import Path
from harrier.extensions import modify

@modify.generate_pages
def add_extra_pages(som):
    config: Config = som['config']
    yield {
        'path': Path('extra/index.md'),
        'content': [1, 2, 3],
    }
    """
        })
    with pytest.raises(ExtensionError):
        build(str(tmpdir))
Example #27
0
def test_pages_broken(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'foo.md': '# foo',
            },
            'theme/templates/main.jinja':
            '{{ content }}',
            'extensions.py':
            """
from harrier.extensions import modify

@modify.pages('**/*')
def modify_pages(data, config):
    return None
        """
        })

    with pytest.raises(ExtensionError) as exc_info:
        build(str(tmpdir))
    assert exc_info.value.args[
        0] == 'extension "modify_pages" did not return a dict'
Example #28
0
def test_copy_extensions(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'index.html': 'hello',
            },
            'theme/assets': {
                'image1.png': 'a',
                'image2.png': 'c',
                'foo/bar.svg': 'c',
            },
            'extensions.py':
            """
from harrier.extensions import modify, template

@modify.copy('/foo/*')
def modify_foo(in_path, out_path, config):
    out_path.write_text(f'{in_path.name} {in_path.read_text()} custom')
    return 1  # prevent default copy

@modify.copy('/image2.png')
def print_in_path(in_path, out_path, config):
    out_path.with_name(out_path.name + '.alt').write_bytes(in_path.read_bytes() + b'2')
    # return nothing so normal copy also happens
    """
        })

    build(str(tmpdir))
    assert gettree(tmpdir.join('dist')) == {
        'index.html': 'hello\n',
        'foo': {
            'bar.4a8a08f.svg': 'bar.svg c custom',
        },
        'image1.0cc175b.png': 'a',
        'image2.4a8a08f.png': 'c',
        'image2.4a8a08f.png.alt': 'c2',
    }
Example #29
0
def test_build_multi_part(tmpdir):
    mktree(
        tmpdir, {
            'pages': {
                'multipart_list.md': ('---\n'
                                      'uri: /list_md.html\n'
                                      'template: list.jinja\n'
                                      '---\n'
                                      'part 1\n'
                                      '--- . ---\n'
                                      'part **2**\n'
                                      '---.---\n'
                                      'this is part *3*\n'),
                'multipart_dict.md': ('---\n'
                                      'uri: /dict_md.html\n'
                                      'template: dict.jinja\n'
                                      '---\n'
                                      'the main **section**\n'
                                      '--- other ---\n'
                                      'part *2*\n'),
                'multipart_list.html': ('---\n'
                                        'uri: /list_html.html\n'
                                        'template: list.jinja\n'
                                        '---\n'
                                        'part 1\n'
                                        '--- . ---\n'
                                        'part 2\n'
                                        '---.---\n'
                                        'this is part 3\n'),
                'multipart_dict.html': ('---\n'
                                        'uri: /dict_html.html\n'
                                        'template: dict.jinja\n'
                                        '---\n'
                                        'the main section\n'
                                        '--- other ---\n'
                                        'part 2\n'),
            },
            'theme': {
                'templates/': {
                    'list.jinja': ('{% for v in content %}\n'
                                   '  {{ v.content }}\n'
                                   '{% endfor %}\n'),
                    'dict.jinja': ('{{ content.main.content }}\n'
                                   '{{ content.other.content }}\n'),
                },
            },
        })
    build(tmpdir, mode=Mode.production)
    assert gettree(tmpdir.join('dist')) == {
        'list_md.html': ('\n'
                         '  <p>part 1</p>\n'
                         '\n\n'
                         '  <p>part <strong>2</strong></p>\n'
                         '\n\n'
                         '  <p>this is part <em>3</em></p>\n'),
        'dict_md.html': ('<p>the main <strong>section</strong></p>\n'
                         '\n'
                         '<p>part <em>2</em></p>\n'),
        'list_html.html': ('\n'
                           '  part 1\n'
                           '\n'
                           '  part 2\n'
                           '\n'
                           '  this is part 3\n'),
        'dict_html.html': ('the main section\n'
                           'part 2\n'),
    }