diff options
Diffstat (limited to 'tests/test_metadata_extractors.py')
| -rw-r--r-- | tests/test_metadata_extractors.py | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/tests/test_metadata_extractors.py b/tests/test_metadata_extractors.py new file mode 100644 index 0000000..58dd7b5 --- /dev/null +++ b/tests/test_metadata_extractors.py @@ -0,0 +1,225 @@ +"""Test metadata extractors.""" + +import os +from unittest import mock + +import pytest + +from nikola.metadata_extractors import ( + MetaCondition, + check_conditions, + default_metadata_extractors_by, + load_defaults, +) +from nikola.plugins.compile.rest import CompileRest +from nikola.plugins.compile.markdown import CompileMarkdown +from nikola.plugins.compile.ipynb import CompileIPynb +from nikola.plugins.compile.html import CompileHtml +from nikola.post import get_meta + +from .helper import FakeSite + + +@pytest.mark.parametrize( + "filecount, expected, unexpected", + [(1, "onefile", "twofile"), (2, "twofile", "onefile")], +) +@pytest.mark.parametrize( + "format_lc, format_friendly", + [("nikola", "Nikola"), ("toml", "TOML"), ("yaml", "YAML")], +) +def test_builtin_extractors_rest( + metadata_extractors_by, + testfiledir, + filecount, + expected, + unexpected, + format_lc, + format_friendly, +): + is_two_files = filecount == 2 + + source_filename = "f-rest-{0}-{1}.rst".format(filecount, format_lc) + metadata_filename = "f-rest-{0}-{1}.meta".format(filecount, format_lc) + source_path = os.path.join(testfiledir, source_filename) + metadata_path = os.path.join(testfiledir, metadata_filename) + post = FakePost(source_path, metadata_path, {}, None, metadata_extractors_by) + + assert os.path.exists(source_path) + if is_two_files: + assert os.path.exists(metadata_path) + + meta, extractor = get_meta(post, None) + + assert meta + assert extractor is metadata_extractors_by["name"][format_lc] + + assert meta["title"] == "T: reST, {0}, {1}".format(filecount, format_friendly) + assert meta["slug"] == "s-rest-{0}-{1}".format(filecount, format_lc) + assert expected in meta["tags"] + assert unexpected not in meta["tags"] + assert "meta" in meta["tags"] + assert format_friendly in meta["tags"] + assert "reST" in meta["tags"] + assert meta["date"] == "2017-07-01 00:00:00 UTC" + + +@pytest.mark.parametrize( + "filecount, expected, unexpected", + [(1, "onefile", "twofile"), (2, "twofile", "onefile")], +) +def test_nikola_meta_markdown( + metadata_extractors_by, testfiledir, filecount, expected, unexpected +): + is_two_files = filecount == 2 + + source_filename = "f-markdown-{0}-nikola.md".format(filecount) + metadata_filename = "f-markdown-{0}-nikola.meta".format(filecount) + source_path = os.path.join(testfiledir, source_filename) + metadata_path = os.path.join(testfiledir, metadata_filename) + post = FakePost(source_path, metadata_path, {}, None, metadata_extractors_by) + + assert os.path.exists(source_path) + if is_two_files: + assert os.path.exists(metadata_path) + + meta, extractor = get_meta(post, None) + assert extractor is metadata_extractors_by["name"]["nikola"] + + assert meta["title"] == "T: Markdown, {0}, Nikola".format(filecount) + assert meta["slug"] == "s-markdown-{0}-nikola".format(filecount) + assert expected in meta["tags"] + assert unexpected not in meta["tags"] + assert "meta" in meta["tags"] + assert "Nikola" in meta["tags"] + assert "Markdown" in meta["tags"] + assert meta["date"] == "2017-07-01 00:00:00 UTC" + + +@pytest.mark.parametrize( + "compiler, fileextension, compiler_lc, name", + [ + (CompileRest, "rst", "rest", "reST"), + (CompileMarkdown, "md", "markdown", "Markdown"), + (CompileIPynb, "ipynb", "ipynb", "Jupyter Notebook"), + (CompileHtml, "html", "html", "HTML"), + ], +) +def test_compiler_metadata( + metadata_extractors_by, testfiledir, compiler, fileextension, compiler_lc, name +): + source_filename = "f-{0}-1-compiler.{1}".format(compiler_lc, fileextension) + metadata_filename = "f-{0}-1-compiler.meta".format(compiler_lc) + title = "T: {0}, 1, compiler".format(name) + slug = "s-{0}-1-compiler".format(compiler_lc) + source_path = os.path.join(testfiledir, source_filename) + metadata_path = os.path.join(testfiledir, metadata_filename) + + config = { + "USE_REST_DOCINFO_METADATA": True, + "MARKDOWN_EXTENSIONS": ["markdown.extensions.meta"], + } + site = FakeSite() + site.config.update(config) + compiler_obj = compiler() + compiler_obj.set_site(site) + + post = FakePost( + source_path, metadata_path, config, compiler_obj, metadata_extractors_by + ) + + class FakeBorg: + current_lang = "en" + + def __call__(self): + return self + + with mock.patch("nikola.plugins.compile." + compiler_lc + ".LocaleBorg", FakeBorg): + meta, extractor = get_meta(post, None) + + assert meta["title"] == title + assert meta["slug"] == slug + assert "meta" in meta["tags"] + assert "onefile" in meta["tags"] + assert "compiler" in meta["tags"] + assert name in meta["tags"] + assert meta["date"] == "2017-07-01 00:00:00 UTC" + + +def test_yaml_none_handling(metadata_extractors_by): + yaml_extractor = metadata_extractors_by["name"]["yaml"] + meta = yaml_extractor.extract_text("---\ntitle: foo\nslug: null") + assert meta["title"] == "foo" + assert meta["slug"] == "" + + +@pytest.mark.parametrize( + "conditions", + [ + [(MetaCondition.config_bool, "baz"), (MetaCondition.config_present, "quux")], + pytest.param( + [(MetaCondition.config_bool, "quux")], marks=pytest.mark.xfail(strict=True) + ), + pytest.param( + [(MetaCondition.config_present, "foobar")], + marks=pytest.mark.xfail(strict=True), + ), + [(MetaCondition.extension, "bar")], + pytest.param( + [(MetaCondition.extension, "baz")], marks=pytest.mark.xfail(strict=True) + ), + [(MetaCondition.compiler, "foo")], + pytest.param( + [(MetaCondition.compiler, "foobar")], marks=pytest.mark.xfail(strict=True) + ), + pytest.param( + [(MetaCondition.never, None), (MetaCondition.config_present, "bar")], + marks=pytest.mark.xfail(strict=True), + ), + ], +) +def test_check_conditions(conditions, dummy_post): + filename = "foo.bar" + config = {"baz": True, "quux": False} + assert check_conditions(dummy_post, filename, conditions, config, "") + + +class FakePost: + def __init__( + self, source_path, metadata_path, config, compiler, metadata_extractors_by + ): + self.source_path = source_path + self.metadata_path = metadata_path + self.is_two_file = True + self.config = {"TRANSLATIONS": {"en": "./"}, "DEFAULT_LANG": "en"} + self.config.update(config) + self.default_lang = self.config["DEFAULT_LANG"] + self.metadata_extractors_by = metadata_extractors_by + if compiler: + self.compiler = compiler + + def translated_source_path(self, _): + return self.source_path + + +@pytest.fixture +def metadata_extractors_by(): + metadata_extractors = default_metadata_extractors_by() + load_defaults(None, metadata_extractors) + return metadata_extractors + + +@pytest.fixture(scope="module") +def testfiledir(test_dir): + return os.path.join(test_dir, "data", "metadata_extractors") + + +@pytest.fixture(scope="module") +def dummy_post(): + class DummyCompiler: + name = "foo" + + class DummyPost: + compiler = DummyCompiler() + + return DummyPost() |
