diff --git a/.coveragerc b/.coveragerc index fdd2cad6..6347d80b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,4 @@ [report] -omit = pelican/tests/* +omit = + pelican/tests/* + pelican/signals.py diff --git a/.gitignore b/.gitignore index 473efea2..65e4d759 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,9 @@ samples/output *.lock .pdm-python .venv + +# direnv +.envrc + +# pycharm +.idea diff --git a/docs/contribute.rst b/docs/contribute.rst index 6a5a417e..07cf998a 100644 --- a/docs/contribute.rst +++ b/docs/contribute.rst @@ -64,6 +64,27 @@ your bug fix or feature:: Now you can make changes to Pelican, its documentation, and/or other aspects of the project. +Setting up ``git blame`` (optional) +----------------------------------- + +``git blame`` annotates lines in a file with information about the pull request +that last modified it. Sweeping shallow changes (like formatting) can make that +information less useful, so we keep a list of such changes to be ignored. Run the +following command to set this up in your repository, adding ``--global`` if you +want this setting to apply to all repositories:: + + git config blame.ignoreRevsFile .git-blame-ignore-revs + +As noted in a `useful article`_ about ``git blame``, there are other related +settings you may find to be beneficial:: + + # Add `?` to any lines that have had a commit skipped using --ignore-rev + git config --global blame.markIgnoredLines true + # Add `*` to any lines that were added in a skipped commit and can not be attributed + git config --global blame.markUnblamableLines true + +.. _useful article: https://www.michaelheap.com/git-ignore-rev/ + Running the test suite ---------------------- @@ -108,6 +129,21 @@ environments. .. _Tox: https://tox.readthedocs.io/en/latest/ +Running a code coverage report +------------------------------ + +Code is more likely to stay robust if it is tested. Coverage_ is a library that +measures how much of the code is tested. To run it:: + + invoke coverage + +This will show overall coverage, coverage per file, and even line-by-line coverage. +There is also an HTML report available:: + + open htmlcov/index.html + +.. _Coverage: https://github.com/nedbat/coveragepy + Building the docs ----------------- diff --git a/pelican/tests/simple_content/article_with_md_extension.md b/pelican/tests/simple_content/article_with_md_extension.md new file mode 120000 index 00000000..00a11ad3 --- /dev/null +++ b/pelican/tests/simple_content/article_with_md_extension.md @@ -0,0 +1 @@ +../content/article_with_md_extension.md \ No newline at end of file diff --git a/pelican/tests/test_pelican.py b/pelican/tests/test_pelican.py index ba03b529..add5f576 100644 --- a/pelican/tests/test_pelican.py +++ b/pelican/tests/test_pelican.py @@ -1,3 +1,5 @@ +import contextlib +import io import locale import logging import os @@ -6,9 +8,12 @@ import sys import unittest from collections.abc import Sequence from shutil import rmtree -from tempfile import mkdtemp +from tempfile import TemporaryDirectory, mkdtemp +from unittest.mock import patch -from pelican import Pelican +from rich.console import Console + +from pelican import Pelican, __version__, main from pelican.generators import StaticGenerator from pelican.settings import read_settings from pelican.tests.support import ( @@ -270,3 +275,31 @@ class TestPelican(LoggedTestCase): [sys.executable, "-m", "pelican", "--help"] ).decode("ascii", "replace") assert "usage:" in output + + def test_main_version(self): + """Run main --version.""" + out = io.StringIO() + with contextlib.redirect_stdout(out): + with self.assertRaises(SystemExit): + main(["--version"]) + self.assertEqual(f"{__version__}\n", out.getvalue()) + + def test_main_help(self): + """Run main --help.""" + out = io.StringIO() + with contextlib.redirect_stdout(out): + with self.assertRaises(SystemExit): + main(["--help"]) + self.assertIn("A tool to generate a static blog", out.getvalue()) + + def test_main_on_content(self): + """Invoke main on simple_content directory.""" + out, err = io.StringIO(), io.StringIO() + with contextlib.redirect_stdout(out), contextlib.redirect_stderr(err): + with TemporaryDirectory() as temp_dir: + # Don't highlight anything. + # See https://rich.readthedocs.io/en/stable/highlighting.html + with patch("pelican.console", new=Console(highlight=False)): + main(["-o", temp_dir, "pelican/tests/simple_content"]) + self.assertIn("Processed 1 article", out.getvalue()) + self.assertEqual("", err.getvalue()) diff --git a/tasks.py b/tasks.py index 64409e20..9a7564b2 100644 --- a/tasks.py +++ b/tasks.py @@ -47,7 +47,11 @@ def tests(c): @task def coverage(c): """Generate code coverage of running the test suite.""" - c.run(f"{VENV_BIN}/pytest --cov=pelican", pty=PTY) + c.run( + f"{VENV_BIN}/pytest --cov=pelican --cov-report term-missing " + "--cov-fail-under 74.8", + pty=PTY, + ) c.run(f"{VENV_BIN}/coverage html", pty=PTY)