diff --git a/.gitignore b/.gitignore index 1ef8410..fb90e13 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ **/__pycache__ +.coverage jean_website.egg-info diff --git a/jwebsite/content.py b/jwebsite/content.py new file mode 100644 index 0000000..a697818 --- /dev/null +++ b/jwebsite/content.py @@ -0,0 +1,35 @@ +from functools import cache +from pathlib import Path + + +class Content: + def __init__(self, path: Path) -> None: + self.__path = path + + @property + def path(self) -> Path: + return self.__path + + +class ContentDirectory(Content): + def load(self, subpath: Path) -> Content: + current: Content = self + for part in subpath.parts: + if not isinstance(current, ContentDirectory): + raise NotADirectoryError(self.path) + + current = current.__load_children(part) + + return current + + @cache # noqa: B019 + def __load_children(self, name: str) -> Content: + child_path = self.path / name + + if not child_path.exists(): + raise FileNotFoundError(child_path) + + if child_path.is_dir(): + return ContentDirectory(child_path) + + raise NotImplementedError() diff --git a/noxfile.py b/noxfile.py index c7312c9..c2f6dcd 100644 --- a/noxfile.py +++ b/noxfile.py @@ -17,6 +17,13 @@ def mypy(session: Session) -> None: session.run("mypy") +@session(python=["3.10", "3.11"]) +def unit_tests(session: Session) -> None: + """Run unit tests.""" + devenv(session) + session.run("python", "-m", "pytest", "--cov=jwebsite", "--cov-report=html") + + @session() def devenv(session: Session) -> None: session.install("-e", ".[dev]") diff --git a/pyproject.toml b/pyproject.toml index 2ebc963..01ec75a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,9 @@ dependencies = [ [project.optional-dependencies] dev = [ "nox", + "pytest", + "pytest-datadir", + "pytest-coverage" ] [project.scripts] @@ -49,6 +52,3 @@ select = [ "ASYNC", "RUF" ] - -[tool.pytest.ini_options] -asyncio_mode = "auto" diff --git a/tests/test_content.py b/tests/test_content.py new file mode 100644 index 0000000..afb78b3 --- /dev/null +++ b/tests/test_content.py @@ -0,0 +1,18 @@ +from pathlib import Path + +from pytest import raises + +from jwebsite.content import ContentDirectory + + +def test_load_directory(datadir: Path) -> None: + content = ContentDirectory(datadir) + otters = content.load(Path("otters")) + assert isinstance(otters, ContentDirectory) + + +def test_load_errors(datadir: Path) -> None: + directory = ContentDirectory(datadir) + + with raises(FileNotFoundError): + directory.load(Path("otters/i-dont-exist")) diff --git a/tests/test_content/otters/steven.yml b/tests/test_content/otters/steven.yml new file mode 100644 index 0000000..e69de29