Skip to content

Commit

Permalink
more tests, drop tracking of deleted content files/dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
fastily committed Oct 14, 2022
1 parent ea7fa57 commit 8126bab
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 20 deletions.
11 changes: 6 additions & 5 deletions jinja2html/build_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Union

from jinja2 import Environment, FileSystemLoader
from watchfiles import DefaultFilter
from watchfiles import Change, DefaultFilter

from .utils import is_html

Expand Down Expand Up @@ -60,16 +60,17 @@ def stub_of(self, f: Path) -> Path:
"""
return f.relative_to(self.input_dir)

def is_template(self, f: Union[Path, str]) -> bool:
def is_template(self, f: Union[Path, str], change: Change = None) -> bool:
"""Convienience method, determines whether a file is a template (i.e. in the `self.template_dir` directory)
Args:
f (Union[Path, str]): The file to check. Use an absolute `Path` for best results.
change (Change, optional): The type of `Change` to associate with this check. Defaults to None.
Returns:
bool: `True` if `f` is a template in the `self.template_dir` directory.
"""
return (f := _abs_path_of(f)).is_file() and self.template_dir in f.parents and is_html(f)
return ((f := _abs_path_of(f)).is_file() or change == Change.deleted) and self.template_dir in f.parents and is_html(f)

def is_config_json(self, f: Union[Path, str]) -> bool:
"""Convienience method, determines whether `f` is the `config.json` file.
Expand All @@ -86,12 +87,12 @@ def is_content_file(self, p: Union[Path, str]) -> bool:
"""Determines whether a file should be watched.
Args:
entry (Union[Path, str]): The path to the file to check.
p (Union[Path, str]): The path to the file to check.
Returns:
bool: `True` if the file should be watched.
"""
return bool((p := Path(p)).is_file() and Context._FILE_PATTERN.match(p.name) and not self.is_template(p))
return bool((p := Path(p)).is_file() and Context._FILE_PATTERN.match(p.name) and self.template_dir not in p.parents)

def is_content_dir(self, p: Union[Path, str]) -> bool:
"""Determines if `p` is a directory containing jinja content. Filters out template directories and ignored dirs.
Expand Down
12 changes: 4 additions & 8 deletions jinja2html/web_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,11 @@ async def changed_files_handler(wm: WebsiteManager) -> None:
p = Path(p)
log.debug("change of type '%s' detected on '%s'", change.raw_str(), p)

# handle deleted content files/directories
# handle deleted
if change == Change.deleted:
target = wm.context.output_dir / wm.context.stub_of(p)
if wm.context.is_content_file(p):
target.unlink()
elif wm.context.is_content_dir(p):
rmtree(target)
else: # rebuild all if user deleted template or config
# l = wm.find_acceptable_files()
# TODO: handle deleted subdirs of templates
# only acknowledge config/template deletion. not doing content files/dirs bc this is a time sink and low roi for what is supposed to be a simple tool.
if wm.context.is_config_json(p) or wm.context.is_template(p, change):
build_all = True
break

Expand Down
2 changes: 1 addition & 1 deletion jinja2html/website_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ def __call__(self, change: Change, path: str) -> bool:
Returns:
bool: `True` if the change should be reported.
"""
return self.context.is_content_file(path) or self.context.is_content_dir(path) or self.context.is_config_json(path) or self.context.is_template(path)
return self.context.is_content_file(path) or self.context.is_content_dir(path) or self.context.is_config_json(path) or self.context.is_template(path, change)
7 changes: 3 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
beautifulsoup4==4.11.1
Jinja2==3.1.2
lxml==4.9.1
rich==12.5.1
starlette==0.20.4
uvicorn[standard]==0.18.3
# watchfiles==0.17.0
rich==12.6.0
starlette==0.21.0
uvicorn[standard]==0.18.3
10 changes: 10 additions & 0 deletions tests/test_build_context.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
from unittest.mock import Mock, patch
from pathlib import Path
from tempfile import TemporaryDirectory

from jinja2html.build_context import Context
from jinja2html.website_manager import WebsiteManager

from .base import J2hTestCase


class TestContext(J2hTestCase):
"""Test methods supporting the build context"""


@patch("jinja2html.build_context.rmtree")
def test_clean(self, mock:Mock):
with TemporaryDirectory() as tempdir:
WebsiteManager(c := Context(self.SAMPLE_PROJECT, expected_output_dir := Path(tempdir))).build_files(auto_find=True)
c.clean()
mock.assert_called_once_with(expected_output_dir.resolve(), ignore_errors=True)

def test_is_stub_of(self):
with TemporaryDirectory() as tempdir:
c = Context(self.SAMPLE_PROJECT, Path(tempdir))
Expand Down
25 changes: 25 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pathlib import Path
from unittest.case import TestCase

from jinja2html.utils import is_css_js, is_html


class TestContext(TestCase):
"""Test methods supporting the build context"""

def test_is_css_js(self):
self.assertTrue(is_css_js(Path("a/b/c/test.js")))
self.assertTrue(is_css_js(Path("a.css")))
self.assertFalse(is_css_js(Path("index.html")))
self.assertFalse(is_css_js(Path("config.json")))
self.assertFalse(is_css_js(Path("x/y/z/index.json")))
self.assertFalse(is_css_js(Path("x.png")))

def test_is_html(self):
self.assertTrue(is_html(Path("index.html")))
self.assertTrue(is_html(Path("sub/index.html")))
self.assertFalse(is_html(Path("a/b/c/test.js")))
self.assertFalse(is_html(Path("a.css")))
self.assertFalse(is_html(Path("config.json")))
self.assertFalse(is_html(Path("x/y/z/index.json")))
self.assertFalse(is_html(Path("x.png")))
32 changes: 30 additions & 2 deletions tests/test_website_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from pathlib import Path
from tempfile import TemporaryDirectory

from watchfiles import Change

from jinja2html.build_context import Context
from jinja2html.website_manager import WebsiteManager
from jinja2html.website_manager import JinjaFilter, WebsiteManager

from .base import J2hTestCase

Expand All @@ -18,8 +20,34 @@ def test_find_acceptable_files(self):
self.assertSetEqual({self.SAMPLE_PROJECT / s for s in ("content1.html", "content2.html", "index.html", "sub/index.html", "shared.css", "shared.js")},
WebsiteManager(Context(self.SAMPLE_PROJECT, Path(tempdir))).find_acceptable_files())

def test_process_files(self):
def test_build_files(self):
with TemporaryDirectory() as tempdir:
WebsiteManager(Context(self.SAMPLE_PROJECT, Path(tempdir))).build_files(auto_find=True)

self.assertFalse(dircmp(self.RES_DIR / "expected_output", tempdir).diff_files)


class TestJinjaFilter(J2hTestCase):

def test_call(self):
with TemporaryDirectory() as tempdir:
jf = JinjaFilter(Context(self.SAMPLE_PROJECT, Path(tempdir)))

self.assertTrue(jf(Change.modified, str(self.SAMPLE_TEMPLATES / "base.html")))
self.assertTrue(jf(Change.deleted, str(self.SAMPLE_TEMPLATES / "a.html")))
self.assertTrue(jf(Change.deleted, str(self.SAMPLE_TEMPLATES / "deleted.html")))
self.assertFalse(jf(Change.deleted, str(self.SAMPLE_TEMPLATES / "x.css")))

self.assertTrue(jf(Change.modified, str(self.SAMPLE_PROJECT / "index.html")))
self.assertTrue(jf(Change.modified, str(self.SAMPLE_PROJECT / "shared.css")))
self.assertFalse(jf(Change.deleted, str(self.SAMPLE_PROJECT / "a.html"))) # ignore deleted content files

self.assertTrue(jf(Change.added, str(self.SAMPLE_PROJECT / "sub")))
self.assertFalse(jf(Change.deleted, str(self.SAMPLE_PROJECT / "nothere"))) # ignore deleted content dirs

self.assertTrue(jf(Change.modified, str(self.SAMPLE_PROJECT / "config.json")))
self.assertTrue(jf(Change.deleted, str(self.SAMPLE_PROJECT / "config.json")))

self.assertFalse(jf(Change.modified, str(self.SAMPLE_PROJECT / "foobar.txt")))
self.assertFalse(jf(Change.deleted, str(self.SAMPLE_PROJECT / "foobar.txt")))
self.assertFalse(jf(Change.deleted, str(self.SAMPLE_TEMPLATES / "meh.svg")))

0 comments on commit 8126bab

Please sign in to comment.