def test_args_pretty(testapp, pretty, lines): """Sitemap processor has to respect pretty argument.""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": pathlib.Path("1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }) ], pretty=pretty, ) assert isinstance(stream, collections.abc.Iterable) items = list(stream) assert items == [ holocron.WebSiteItem({ "destination": pathlib.Path("1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }), holocron.WebSiteItem({ "source": pathlib.Path("sitemap://sitemap.xml"), "destination": pathlib.Path("sitemap.xml"), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], }), ] assert len(items[-1]["content"].splitlines()) == lines
def test_args_save_as(testapp, save_as): """Sitemap processor has to respect save_as argument.""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": pathlib.Path("posts", "1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }) ], save_as=str(save_as), ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "destination": pathlib.Path("posts", "1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }), holocron.WebSiteItem({ "source": pathlib.Path("sitemap://", save_as), "destination": pathlib.Path(save_as), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], }), ]
def test_websiteitem_init_setitem(supported_value): """Properties can be initialized and set.""" instance = holocron.WebSiteItem({ "x": supported_value, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) instance["y"] = 42 assert instance["x"] == supported_value assert instance["y"] == 42 assert instance["destination"] == pathlib.Path("path", "to", "item") assert instance["baseurl"] == "https://yoda.ua" assert instance["url"] == "/path/to/item" assert instance["absurl"] == "https://yoda.ua/path/to/item" assert instance == holocron.WebSiteItem({ "x": supported_value, "y": 42, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", })
def test_websiteitem_init_mapping_kwargs(supported_value): """Properties can be initialized.""" instance = holocron.WebSiteItem( { "x": supported_value, "destination": pathlib.Path("path", "to", "item"), }, baseurl="https://yoda.ua", ) assert instance["x"] == supported_value assert instance["destination"] == pathlib.Path("path", "to", "item") assert instance["baseurl"] == "https://yoda.ua" assert instance["url"] == "/path/to/item" assert instance["absurl"] == "https://yoda.ua/path/to/item" assert instance == holocron.WebSiteItem({ "x": supported_value, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", })
def test_item_many(testapp, amount): """Sitemap processor has to work with stream.""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": pathlib.Path(str(i)), "updated": timepoint, "baseurl": testapp.metadata["url"], }) for i in range(amount) ], ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == list( itertools.chain( [ holocron.WebSiteItem({ "destination": pathlib.Path(str(i)), "updated": timepoint, "baseurl": testapp.metadata["url"], }) for i in range(amount) ], [ holocron.WebSiteItem({ "source": pathlib.Path("sitemap://sitemap.xml"), "destination": pathlib.Path("sitemap.xml"), "content": _pytest_xmlasdict( { "urlset": { "@xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9", "url": [{ "loc": "https://yoda.ua/%d" % i, "lastmod": "1970-01-01T00:00:00+00:00", } for i in range(amount)], } }, force_list=["url"], ), "baseurl": testapp.metadata["url"], }) ], ))
def test_args_template(testapp): """Archive processor has respect 'template' argument.""" stream = archive.process( testapp, [holocron.Item({ "title": "The Force", "content": "Obi-Wan" })], template="foobar.txt", ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.Item({ "title": "The Force", "content": "Obi-Wan" }), holocron.WebSiteItem({ "source": pathlib.Path("archive://index.html"), "destination": pathlib.Path("index.html"), "template": "foobar.txt", "items": [holocron.Item({ "title": "The Force", "content": "Obi-Wan" })], "baseurl": testapp.metadata["url"], }), ]
def test_args_save_as(testapp, save_as): """Archive processor has to respect 'save_as' argument.""" stream = archive.process( testapp, [holocron.Item({ "title": "The Force", "content": "Obi-Wan" })], save_as=str(save_as), ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.Item({ "title": "The Force", "content": "Obi-Wan" }), holocron.WebSiteItem({ "source": pathlib.Path("archive://", save_as), "destination": save_as, "template": "archive.j2", "items": [holocron.Item({ "title": "The Force", "content": "Obi-Wan" })], "baseurl": testapp.metadata["url"], }), ]
def test_item_many(testapp, amount): """Archive processor has to work with stream.""" stream = archive.process( testapp, [ holocron.Item({"title": "The Force (part #%d)" % i}) for i in range(amount) ], ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == list( itertools.chain( [ holocron.Item({"title": "The Force (part #%d)" % i}) for i in range(amount) ], [ holocron.WebSiteItem({ "source": pathlib.Path("archive://index.html"), "destination": pathlib.Path("index.html"), "template": "archive.j2", "items": [ holocron.Item({"title": "The Force (part #%d)" % i}) for i in range(amount) ], "baseurl": testapp.metadata["url"], }) ], ))
def test_item(testapp, monkeypatch, tmpdir, path): """Source processor has to work.""" monkeypatch.chdir(tmpdir) tmpdir.ensure(*path).write_text("Obi-Wan", encoding="UTF-8") stream = source.process(testapp, []) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "source": pathlib.Path(*path), "destination": pathlib.Path(*path), "content": "Obi-Wan", "created": _pytest_timestamp(tmpdir.join(*path).stat().ctime), "updated": _pytest_timestamp(tmpdir.join(*path).stat().mtime), "baseurl": testapp.metadata["url"], }) ]
def test_item_empty(testapp, monkeypatch, tmpdir): """Source processor has to properly read empty items.""" monkeypatch.chdir(tmpdir) tmpdir.ensure("cv.md").write_binary(b"") stream = source.process(testapp, []) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "source": pathlib.Path("cv.md"), "destination": pathlib.Path("cv.md"), "content": "", "created": _pytest_timestamp(tmpdir.join("cv.md").stat().ctime), "updated": _pytest_timestamp(tmpdir.join("cv.md").stat().mtime), "baseurl": testapp.metadata["url"], }) ]
def test_item_content_types(testapp, monkeypatch, tmpdir, data): """Source processor has to properly read items" content.""" monkeypatch.chdir(tmpdir) localpath = tmpdir.ensure("cv.md") if isinstance(data, bytes): localpath.write_binary(data) else: localpath.write_text(data, encoding="UTF-8") stream = source.process(testapp, []) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "source": pathlib.Path("cv.md"), "destination": pathlib.Path("cv.md"), "content": data, "created": _pytest_timestamp(tmpdir.join("cv.md").stat().ctime), "updated": _pytest_timestamp(tmpdir.join("cv.md").stat().mtime), "baseurl": testapp.metadata["url"], }) ]
def test_args_save_as_unsupported(testapp, document_path, sitemap_path): """Sitemap process has to check enlisted URLs for compatibility.""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": document_path, "updated": timepoint, "baseurl": testapp.metadata["url"], }) ], save_as=str(sitemap_path), ) assert isinstance(stream, collections.abc.Iterable) with pytest.raises(ValueError) as excinfo: next(stream) excinfo.match( "The location of a Sitemap file determines the set of URLs " "that can be included in that Sitemap. A Sitemap file located " "at .* can include any URLs starting with .* but can not " "include .*.")
def test_args_gzip(testapp): """Sitemap processor has to respect gzip argument.""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": pathlib.Path("1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }) ], gzip=True, ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "destination": pathlib.Path("1.html"), "updated": timepoint, "baseurl": testapp.metadata["url"], }), holocron.WebSiteItem({ "source": pathlib.Path("sitemap://sitemap.xml.gz"), "destination": pathlib.Path("sitemap.xml.gz"), "content": _pytest_xmlasdict( { "urlset": { "@xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9", "url": { "loc": "https://yoda.ua/1.html", "lastmod": "1970-01-01T00:00:00+00:00", }, } }, ungzip=True, ), "baseurl": testapp.metadata["url"], }), ]
def test_args_pattern(testapp, monkeypatch, tmpdir): """Source processor has to respect pattern argument.""" monkeypatch.chdir(tmpdir) tmpdir.join("1.md").write_text("Skywalker", encoding="UTF-8") tmpdir.join("2.txt").write_text("Obi-Wan", encoding="UTF-8") tmpdir.join("3.rst").write_text("Vader", encoding="UTF-8") tmpdir.join("4.markdown").write_text("Yoda", encoding="UTF-8") stream = source.process(testapp, [], pattern=r".*\.(md|markdown)") assert isinstance(stream, collections.abc.Iterable) # Since we don"t know in which order items are discovered, we sort them so # we can avoid possible flakes of the test. assert sorted(stream, key=lambda item: item["source"]) == [ holocron.WebSiteItem({ "source": pathlib.Path("1.md"), "destination": pathlib.Path("1.md"), "content": "Skywalker", "created": _pytest_timestamp(tmpdir.join("1.md").stat().ctime), "updated": _pytest_timestamp(tmpdir.join("1.md").stat().mtime), "baseurl": testapp.metadata["url"], }), holocron.WebSiteItem({ "source": pathlib.Path("4.markdown"), "destination": pathlib.Path("4.markdown"), "content": "Yoda", "created": _pytest_timestamp(tmpdir.join("4.markdown").stat().ctime), "updated": _pytest_timestamp(tmpdir.join("4.markdown").stat().mtime), "baseurl": testapp.metadata["url"], }), ]
def test_websiteitem_url(destination, url): """'url' property is based on 'destination'.""" instance = holocron.WebSiteItem({ "destination": destination, "baseurl": "https://yoda.ua" }) assert instance["url"] == url
def test_websiteitem_init_multiple_mappings(supported_value): """Passing 2+ mappings is prohibited.""" with pytest.raises(TypeError) as excinfo: holocron.WebSiteItem( {"destination": pathlib.Path("path", "to", "item")}, {"baseurl": "https://yoda.ua"}, ) assert str(excinfo.value) == "expected at most 1 argument, got 2"
def test_websiteitem_keys(): """.keys() iterates over properties.""" instance = holocron.WebSiteItem({ "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) assert set(instance.keys()) == {"destination", "baseurl", "url", "absurl"}
def test_item(testapp, filename, escaped): """Sitemap processor has to work!""" timepoint = datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc) stream = sitemap.process( testapp, [ holocron.WebSiteItem({ "destination": pathlib.Path(filename), "updated": timepoint, "baseurl": testapp.metadata["url"], }) ], ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "destination": pathlib.Path(filename), "updated": timepoint, "baseurl": testapp.metadata["url"], }), holocron.WebSiteItem({ "source": pathlib.Path("sitemap://sitemap.xml"), "destination": pathlib.Path("sitemap.xml"), "content": _pytest_xmlasdict({ "urlset": { "@xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9", "url": { "loc": "https://yoda.ua/" + escaped, "lastmod": "1970-01-01T00:00:00+00:00", }, } }), "baseurl": testapp.metadata["url"], }), ]
def test_websiteitem_getitem_keyerror(): """KeyError is raised if key is not found.""" instance = holocron.WebSiteItem({ "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) with pytest.raises(KeyError, match="'the-key'"): instance["the-key"]
def test_item_many(testapp, syndication_format, amount): """Feed processor has to work with stream.""" stream = feed.process( testapp, [ holocron.Item( { "content": "the key is %d" % i, "published": datetime.date(2017, 9, 25), } ) for i in range(amount) ], syndication_format=syndication_format, feed={ "id": "kenobi-way", "title": "Kenobi's Way", "description": "Labours of Obi-Wan", "link": {"href": testapp.metadata["url"]}, }, item={ "id": "day-one", "title": "Day 1", "content": "Once upon a time", }, ) assert isinstance(stream, collections.abc.Iterable) items = list(stream) assert items == list( itertools.chain( [ holocron.Item( { "content": "the key is %d" % i, "published": datetime.date(2017, 9, 25), } ) for i in range(amount) ], [ holocron.WebSiteItem( { "source": pathlib.Path("feed://feed.xml"), "destination": pathlib.Path("feed.xml"), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], } ) ], ) )
def process(app, stream, *, template="archive.j2", save_as="index.html"): passthrough, stream = itertools.tee(stream) index = holocron.WebSiteItem({ "source": pathlib.Path("archive://", save_as), "destination": pathlib.Path(save_as), "template": template, "items": list(stream), "baseurl": app.metadata["url"], }) yield from passthrough yield index
def test_websiteitem_getitem(): """Properties can be retrieved.""" instance = holocron.WebSiteItem({ "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) assert instance["destination"] == pathlib.Path("path", "to", "item") assert instance["baseurl"] == "https://yoda.ua" assert instance["url"] == "/path/to/item" assert instance["absurl"] == "https://yoda.ua/path/to/item"
def test_websiteitem_values(): """.values() iterates over properties.""" instance = holocron.WebSiteItem({ "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) assert set(instance.values()) == { pathlib.Path("path", "to", "item"), "https://yoda.ua", "/path/to/item", "https://yoda.ua/path/to/item", }
def test_args_pretty(testapp, syndication_format, pretty, check_fn): """Feed processor has to respect pretty argument.""" stream = feed.process( testapp, [ holocron.Item( { "content": "the way of the Force", "published": datetime.date(2017, 9, 25), } ) ], syndication_format=syndication_format, pretty=pretty, feed={ "id": "kenobi-way", "title": "Kenobi's Way", "description": "Labours of Obi-Wan", "link": {"href": testapp.metadata["url"]}, }, item={ "id": "day-one", "title": "Day 1", "content": "Once upon a time", }, ) assert isinstance(stream, collections.abc.Iterable) items = list(stream) assert items == [ holocron.Item( { "content": "the way of the Force", "published": datetime.date(2017, 9, 25), } ), holocron.WebSiteItem( { "source": pathlib.Path("feed://feed.xml"), "destination": pathlib.Path("feed.xml"), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], } ), ] assert check_fn(len(items[-1]["content"].splitlines()))
def test_args_save_as(testapp, syndication_format, save_as): """Feed processor has to respect save_as argument.""" stream = feed.process( testapp, [ holocron.Item( { "content": "the way of the Force", "published": datetime.date(2017, 9, 25), } ) ], syndication_format=syndication_format, save_as=str(save_as), feed={ "id": "kenobi-way", "title": "Kenobi's Way", "description": "Labours of Obi-Wan", "link": {"href": testapp.metadata["url"]}, }, item={ "id": "day-one", "title": "Day 1", "content": "Once upon a time", }, ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.Item( { "content": "the way of the Force", "published": datetime.date(2017, 9, 25), } ), holocron.WebSiteItem( { "source": pathlib.Path("feed://", save_as), "destination": pathlib.Path(save_as), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], } ), ]
def test_args_themes(testapp, tmpdir): """Jinja2 processor has to respect themes argument.""" tmpdir.ensure("theme_a", "templates", "item.j2").write_text( textwrap.dedent("""\ template: my super template rendered: {{ item.title }} """), encoding="UTF-8", ) tmpdir.ensure("theme_a", "static", "style.css").write_text("article { margin: 0 }", encoding="UTF-8") stream = jinja2.process( testapp, [ holocron.Item({ "title": "History of the Force", "content": "the Force" }) ], themes=[tmpdir.join("theme_a").strpath], ) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.Item({ "title": "History of the Force", "content": textwrap.dedent("""\ template: my super template rendered: History of the Force"""), }), holocron.WebSiteItem({ "content": "article { margin: 0 }", "source": pathlib.Path("static", "style.css"), "destination": pathlib.Path("static", "style.css"), "created": unittest.mock.ANY, "updated": unittest.mock.ANY, "baseurl": testapp.metadata["url"], }), ]
def test_websiteitem_contains(): """Properties can be tested for membership.""" instance = holocron.WebSiteItem({ "x": supported_value, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) assert "x" in instance assert "destination" in instance assert "baseurl" in instance assert "url" in instance assert "absurl" in instance assert "z" not in instance
def test_args_encoding_fallback(testapp, syndication_format, encoding): """Feed processor has to respect encoding argument (fallback).""" testapp.metadata.update({"encoding": encoding}) published = datetime.datetime(2017, 9, 25, tzinfo=datetime.timezone.utc) stream = feed.process( testapp, [ holocron.Item( {"content": "the way of the Force", "published": published} ) ], syndication_format=syndication_format, feed={ "id": "kenobi-way", "title": "Kenobi's Way", "description": "Labours of Obi-Wan", "link": {"href": testapp.metadata["url"]}, }, item={ "id": "day-one", "title": "Day 1", "content": "Once upon a time", }, ) assert isinstance(stream, collections.abc.Iterable) items = list(stream) assert items == [ holocron.Item( {"content": "the way of the Force", "published": published} ), holocron.WebSiteItem( { "source": pathlib.Path("feed://feed.xml"), "destination": pathlib.Path("feed.xml"), "content": unittest.mock.ANY, "baseurl": testapp.metadata["url"], } ), ] assert untangle.parse(items[-1]["content"].decode(encoding))
def test_websiteitem_as_mapping(supported_value): """Properties can be inspected.""" instance = holocron.WebSiteItem({ "x": supported_value, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", }) assert instance.as_mapping() == { "x": supported_value, "destination": pathlib.Path("path", "to", "item"), "baseurl": "https://yoda.ua", "url": "/path/to/item", "absurl": "https://yoda.ua/path/to/item", }
def test_args_encoding(testapp, monkeypatch, tmpdir, encoding): """Source processor has to respect encoding argument.""" monkeypatch.chdir(tmpdir) tmpdir.ensure("cv.md").write_text("Оби-Ван", encoding=encoding) stream = source.process(testapp, [], encoding=encoding) assert isinstance(stream, collections.abc.Iterable) assert list(stream) == [ holocron.WebSiteItem({ "source": pathlib.Path("cv.md"), "destination": pathlib.Path("cv.md"), "content": "Оби-Ван", "created": unittest.mock.ANY, "updated": unittest.mock.ANY, "baseurl": testapp.metadata["url"], }) ]