diff --git a/TODO.todo b/TODO.todo index efe3316..f7c5ce0 100644 --- a/TODO.todo +++ b/TODO.todo @@ -26,7 +26,10 @@ Documentation: Functionality: ☐ Replace loggers with `click.echo` for command outputs. Keep logging messages for actual logging messages? - ☐ Make options a property on the class, add to abstract + ☐ Refactor the tembo new command so the cli is split out into manageable methods + ☐ Use the complicated CLI example so the tembo new has its own module to define functions in + ☐ Replace all logger errors with exceptions, move logger messages to the cli. + ✔ Make options a property on the class, add to abstract @done(21-10-30 19:31) ☐ Use the python runner Duty ☐ Run tests diff --git a/dev/notes/test.md b/dev/notes/test.md index 607a988..4a1a293 100644 --- a/dev/notes/test.md +++ b/dev/notes/test.md @@ -1,10 +1,10 @@ # testing notes optional: -- template_path +- user_input - example - template_filename -- user_input +- template_path required: - base_path @@ -14,13 +14,44 @@ required: - name -- page using/not using input tokens - page with/without a template -- user input does not match number of input tokens - user input is None - the given base path does not exist +- page using/not using input tokens +- user input does not match number of input tokens + - no user input + - mismatched user input + - with/without example - page using/not using date tokens - page using/not using name tokens - path/page filenames can contain spaces and they are converted + + + +@dataclass +class PageCreatorOptions: + """Options dataclass to create a Page. + + Attributes: + base_path (str): + page_path (str): + filename (str): + extension (str): + name (str): + user_input (Collection[str] | None, optional): + example (str | None, optional): + template_filename (str | None, optional): + template_path (str | None, optional): + """ + + base_path: str + page_path: str + filename: str + extension: str + name: str + user_input: Collection[str] | None = None + example: str | None = None + template_filename: str | None = None + template_path: str | None = None diff --git a/tembo/exceptions.py b/tembo/exceptions.py index a71ea99..9746128 100644 --- a/tembo/exceptions.py +++ b/tembo/exceptions.py @@ -3,3 +3,7 @@ class MismatchedTokenError(Exception): pass + + +class BasePathDoesNotExistError(Exception): + pass diff --git a/tembo/journal/pages.py b/tembo/journal/pages.py index a305d36..4870b47 100644 --- a/tembo/journal/pages.py +++ b/tembo/journal/pages.py @@ -45,11 +45,16 @@ class PageCreator: def __init__(self, options: PageCreatorOptions) -> None: raise NotImplementedError + @property + @abstractmethod + def options(self) -> PageCreatorOptions: + raise NotImplementedError + @abstractmethod def create_page(self, options: PageCreatorOptions) -> Page: raise NotImplementedError - def _convert_to_path(self) -> pathlib.Path: + def _convert_base_path_to_path(self) -> pathlib.Path: # check if Tembo base path exists if not pathlib.Path(self.options.base_path).expanduser().exists(): tembo.logger.critical( @@ -74,27 +79,24 @@ class PageCreator: # return path with a file return path_to_file.with_suffix(f".{extension}") - def _load_template( - self, base_path: str, template_filename: str, template_path: str | None - ) -> str: - # check for overriden template_path - if template_path is not None: - converted_template_path = pathlib.Path(template_path).expanduser() + def _load_template(self) -> str: + if self.options.template_filename is None: + return "" + if self.options.template_path is not None: + converted_template_path = pathlib.Path( + self.options.template_path + ).expanduser() else: - # default template_path is base_path / .templates - converted_template_path = self._convert_to_path( - base_path, ".templates", "", "" - ) - # load the template folder + converted_template_path = pathlib.Path() + file_loader = jinja2.FileSystemLoader(converted_template_path) env = jinja2.Environment(loader=file_loader, autoescape=True) - # load the template contents try: - loaded_template = env.get_template(template_filename) + loaded_template = env.get_template(self.options.template_filename) except TemplateNotFound as template_not_found: tembo.logger.critical( "Template file %s not found - exiting", - str(template_path) + "/" + str(template_not_found.message), + str(self.options.template_path) + "/" + str(template_not_found.message), ) raise SystemExit(1) from template_not_found return loaded_template.render() @@ -112,39 +114,27 @@ class ScopedPageCreator(PageCreator): def __init__(self) -> None: self._all_input_tokens: list[str] = [] - self.options: PageCreatorOptions + self._options: PageCreatorOptions + + @property + def options(self) -> PageCreatorOptions: + return self._options def create_page(self, options: PageCreatorOptions) -> Page: - self.options = options + self._options = options self._all_input_tokens = self._get_input_tokens() self._verify_input_tokens() - path = self._convert_to_path( - self.options.base_path, - self.options.page_path, - self.options.filename, - self.options.extension, - ) + path = self._convert_base_path_to_path() path = pathlib.Path(self._substitute_tokens(str(path))) - template_contents = self._get_template_contents() + template_contents = self._load_template() if options.template_filename is not None: template_contents = self._substitute_tokens(template_contents) return ScopedPage(path, template_contents) - def _get_template_contents(self) -> str: - return ( - self._load_template( - self.options.base_path, - self.options.template_filename, - self.options.template_path, - ) - if self.options.template_filename is not None - else "" - ) - def _get_input_tokens(self) -> list[str]: path = str( pathlib.Path( @@ -154,7 +144,7 @@ class ScopedPageCreator(PageCreator): self.options.extension, ).expanduser() ) - template_contents = self._get_template_contents() + template_contents = self._load_template() # get the input tokens from both the path and the template all_input_tokens = [] for tokenified_string in (path, template_contents): diff --git a/tests/test_journal/old_test_pages.py b/tests/test_journal/old_test_pages.py index 03c62d6..7805193 100644 --- a/tests/test_journal/old_test_pages.py +++ b/tests/test_journal/old_test_pages.py @@ -15,7 +15,7 @@ def test_page_creator_convert_to_path_missing_base_path(caplog): # act with pytest.raises(SystemExit) as system_exit: - PageCreator._convert_to_path( + PageCreator._convert_base_path_to_path( base_path=base_path, page_path=page_path, filename=filename, @@ -50,7 +50,7 @@ def test_page_creator_convert_to_path_full_path_to_file( base_path = tmpdir # act - converted_path = PageCreator._convert_to_path( + converted_path = PageCreator._convert_base_path_to_path( base_path, page_path, filename, extension ) @@ -67,7 +67,7 @@ def test_page_creator_convert_to_path_full_path_no_file(tmpdir): extension = "" # act - converted_path = PageCreator._convert_to_path( + converted_path = PageCreator._convert_base_path_to_path( base_path, page_path, filename, extension ) diff --git a/tests/test_journal/test_pages.py b/tests/test_journal/test_pages.py index abc14c5..d751287 100644 --- a/tests/test_journal/test_pages.py +++ b/tests/test_journal/test_pages.py @@ -1,13 +1,31 @@ import pytest -from tembo.journal.pages import PageCreatorOptions +from tembo.journal.pages import PageCreatorOptions, ScopedPageCreator -def test_scoped_page_creator_create_page_missing_base_path(): +def test_create_page_base_path_does_not_exist(tmpdir, caplog): # arrange - options = PageCreatorOptions() + base_path = str(tmpdir / "nonexistent" / "path") + options = PageCreatorOptions( + base_path=base_path, + page_path="", + filename="", + extension="", + name="", + user_input=None, + example=None, + template_filename=None, + template_path=None, + ) # act + with pytest.raises(SystemExit) as system_exit: + scoped_page_creator = ScopedPageCreator().create_page(options) # assert - pass + assert system_exit.value.code == 1 + assert ( + caplog.records[0].message + == f"Tembo base path of {base_path} does not exist - exiting" + ) + assert caplog.records[0].levelname == "CRITICAL"