diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/conftest.py | 48 | ||||
-rw-r--r-- | tests/io_files/multiple.yaml | 55 | ||||
-rw-r--r-- | tests/io_files/multiple_one_doc_error.yaml | 48 | ||||
-rw-r--r-- | tests/test_configuration.py | 70 | ||||
-rw-r--r-- | tests/test_utils.py | 162 | ||||
-rw-r--r-- | tests/test_yaml_parser.py | 4 |
6 files changed, 351 insertions, 36 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index b44fbf6..e2d6946 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,8 @@ import os import sys import pytest -from typing import Callable +from pathlib import Path +from typing import Any, Callable from pytest import MonkeyPatch from argparse import ArgumentParser from datetime import datetime, timezone @@ -70,3 +71,48 @@ def get_fmt_time() -> Callable[..., str]: def fmt_time(fmt: str) -> str: return datetime.now(tz=timezone.utc).strftime(fmt) return fmt_time + + +@pytest.fixture +def simple_dict() -> dict[str, Any]: + return {'define': '$PYSSG_HOME/pyssg/site_example/', + 'title': 'Example site', + 'path': { + 'src': '/tmp/pyssg/pyssg/site_example/src', + 'dst': '/tmp/pyssg/pyssg/site_example/dst', + 'plt': '/tmp/pyssg/pyssg/site_example/plt', + 'db': '/tmp/pyssg/pyssg/site_example/.files'}, + 'url': { + 'main': 'https://example.com', + 'static': 'https://static.example.com', + 'default_image': 'images/default.png'}, + 'fmt': { + 'date': '%a, %b %d, %Y @ %H:%M %Z', + 'list_date': '%b %d', + 'list_sep_date': '%B %Y'}, + 'dirs': { + '/': { + 'cfg': { + 'plt': 'page.html', + 'tags': False, + 'index': False, + 'rss': False, + 'sitemap': False, + 'exclude_dirs': []}}}} + + +@pytest.fixture(scope='function') +def tmp_dir_structure(tmp_path: Path) -> Path: + root: Path = tmp_path/'dir_str' + # order matters + dirs: list[Path] = [root, + root/'first', + root/'first/f1', + root/'first/f1/f2', + root/'second', + root/'second/s1'] + for i, d in enumerate(dirs): + d.mkdir() + for ext in ['txt', 'md', 'html']: + (d/f'f{i}.{ext}').write_text('sample') + return root diff --git a/tests/io_files/multiple.yaml b/tests/io_files/multiple.yaml new file mode 100644 index 0000000..8d99c40 --- /dev/null +++ b/tests/io_files/multiple.yaml @@ -0,0 +1,55 @@ +%YAML 1.2 +--- +define: &root "$PYSSG_HOME/pyssg/site_example/" + +title: "Example site" +path: + src: !join [*root, "src"] + dst: !join [*root, "dst"] + plt: !join [*root, "plt"] + db: !join [*root, ".files"] +url: + main: "https://example.com" + static: "https://static.example.com" + default_image: "images/default.png" +fmt: + date: "%a, %b %d, %Y @ %H:%M %Z" + list_date: "%b %d" + list_sep_date: "%B %Y" +dirs: + /: + cfg: + plt: "page.html" + tags: False + index: False + rss: False + sitemap: False + exclude_dirs: [] +... +--- +define: &root "$PYSSG_HOME/pyssg/site_example/" + +title: "Example site" +path: + src: !join [*root, "src"] + dst: !join [*root, "dst"] + plt: !join [*root, "plt"] + db: !join [*root, ".files"] +url: + main: "https://example.com" + static: "https://static.example.com" + default_image: "images/default.png" +fmt: + date: "%a, %b %d, %Y @ %H:%M %Z" + list_date: "%b %d" + list_sep_date: "%B %Y" +dirs: + /: + cfg: + plt: "page.html" + tags: False + index: False + rss: False + sitemap: False + exclude_dirs: [] +...
\ No newline at end of file diff --git a/tests/io_files/multiple_one_doc_error.yaml b/tests/io_files/multiple_one_doc_error.yaml new file mode 100644 index 0000000..86f6546 --- /dev/null +++ b/tests/io_files/multiple_one_doc_error.yaml @@ -0,0 +1,48 @@ +%YAML 1.2 +--- +define: &root "$PYSSG_HOME/pyssg/site_example/" + +title: "Example site" +path: + src: !join [*root, "src"] + dst: !join [*root, "dst"] + plt: !join [*root, "plt"] + db: !join [*root, ".files"] +url: + main: "https://example.com" + static: "https://static.example.com" + default_image: "images/default.png" +fmt: + date: "%a, %b %d, %Y @ %H:%M %Z" + list_date: "%b %d" + list_sep_date: "%B %Y" +dirs: + /: + cfg: + plt: "page.html" + tags: False + index: False + rss: False + sitemap: False + exclude_dirs: [] +... +--- +define: &root "$PYSSG_HOME/pyssg/site_example/" + +title: "Example site" +path: + src: !join [*root, "src"] + dst: !join [*root, "dst"] + plt: !join [*root, "plt"] + db: !join [*root, ".files"] +url: + main: "https://example.com" + static: "https://static.example.com" + default_image: "images/default.png" +fmt: + date: "%a, %b %d, %Y @ %H:%M %Z" + list_date: "%b %d" + list_sep_date: "%B %Y" +dirs: + # just removing all paths as it will cause an error +...
\ No newline at end of file diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 0db8094..68f7808 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1,16 +1,16 @@ import pytest from pytest import LogCaptureFixture from typing import Any, Callable -from logging import DEBUG, INFO, WARNING, ERROR +from logging import ERROR from pyssg.configuration import get_static_config, get_parsed_config # this test is a bit sketchy, as the way the datetimes are calculated could vary # by milliseconds or even have a difference in seconds def test_static_default(rss_date_fmt: str, - sitemap_date_fmt: str, - get_fmt_time: Callable[..., str], - version: str) -> None: + sitemap_date_fmt: str, + get_fmt_time: Callable[..., str], + version: str) -> None: rss_run_date: str = get_fmt_time(rss_date_fmt) sitemap_run_date: str = get_fmt_time(sitemap_date_fmt) sc_dict: dict[str, Any] = {'fmt': {'rss_date': rss_date_fmt, @@ -22,35 +22,13 @@ def test_static_default(rss_date_fmt: str, assert static_config == sc_dict -def test_simple(test_dir: str) -> None: - yaml_dict: dict[str, Any] = {'define': '$PYSSG_HOME/pyssg/site_example/', - 'title': 'Example site', - 'path': { - 'src': '/tmp/pyssg/pyssg/site_example/src', - 'dst': '/tmp/pyssg/pyssg/site_example/dst', - 'plt': '/tmp/pyssg/pyssg/site_example/plt', - 'db': '/tmp/pyssg/pyssg/site_example/.files'}, - 'url': { - 'main': 'https://example.com', - 'static': 'https://static.example.com', - 'default_image': 'images/default.png'}, - 'fmt': { - 'date': '%a, %b %d, %Y @ %H:%M %Z', - 'list_date': '%b %d', - 'list_sep_date': '%B %Y'}, - 'dirs': { - '/': { - 'cfg': { - 'plt': 'page.html', - 'tags': False, - 'index': False, - 'rss': False, - 'sitemap': False, - 'exclude_dirs': []}}}} - yaml_path: str = f'{test_dir}/io_files/simple.yaml' +def test_simple(test_dir: str, + simple_yaml: str, + simple_dict: dict[str, Any]) -> None: + yaml_path: str = f'{test_dir}/io_files/{simple_yaml}' yaml: list[dict[str, Any]] = get_parsed_config(yaml_path) assert len(yaml) == 1 - assert yaml[0] == yaml_dict + assert yaml[0] == simple_dict def test_simple_mising_key(test_dir: str, @@ -67,10 +45,10 @@ def test_simple_mising_key(test_dir: str, def test_simple_mising_dirs(test_dir: str, - caplog: LogCaptureFixture) -> None: + caplog: LogCaptureFixture) -> None: err: tuple[str, int, str] = ('pyssg.configuration', ERROR, - 'config doesn\'t have any dirs configs (dirs.*)') + 'config doesn\'t have any dirs (dirs.*)') yaml_path: str = f'{test_dir}/io_files/simple_missing_dirs.yaml' with pytest.raises(SystemExit) as system_exit: get_parsed_config(yaml_path) @@ -90,3 +68,29 @@ def test_simple_root_dir(test_dir: str, assert system_exit.type == SystemExit assert system_exit.value.code == 1 assert caplog.record_tuples[-1] == err + + +# this really just tests that both documents in the yaml file are read, +# multiple.yaml is just simple.yaml with the same document twice, +# shouldn't be an issue as the yaml package handles this +def test_multiple(test_dir: str, simple_dict: dict[str, Any]) -> None: + yaml_path: str = f'{test_dir}/io_files/multiple.yaml' + yaml: list[dict[str, Any]] = get_parsed_config(yaml_path) + assert len(yaml) == 2 + assert yaml[0] == simple_dict + assert yaml[1] == simple_dict + + +# also, this just tests that the checks for a well formed config file are +# processed for all documents +def test_multiple_one_doc_error(test_dir: str, + caplog: LogCaptureFixture) -> None: + err: tuple[str, int, str] = ('pyssg.configuration', + ERROR, + 'config doesn\'t have any dirs (dirs.*)') + yaml_path: str = f'{test_dir}/io_files/multiple_one_doc_error.yaml' + with pytest.raises(SystemExit) as system_exit: + get_parsed_config(yaml_path) + assert system_exit.type == SystemExit + assert system_exit.value.code == 1 + assert caplog.record_tuples[-1] == err diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..b7c9754 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,162 @@ +import pytest +from pytest import LogCaptureFixture +from pathlib import Path +from logging import INFO +from pyssg.utils import (get_expanded_path, get_checksum, copy_file, create_dir, + get_dir_structure, get_file_list) + + +# $PYSSG_HOME is the only env var set +# in the project settings that resemble a path +@pytest.mark.parametrize('path, expected_expanded', [ + ('$PYSSG_HOME', '/tmp/pyssg'), + ('$PYSSG_HOME/', '/tmp/pyssg'), + ('/test$PYSSG_HOME/', '/test/tmp/pyssg'), + ('/test/$PYSSG_HOME/', '/test/tmp/pyssg'), + ('/test/$PYSSG_HOME/test', '/test/tmp/pyssg/test') +]) +def test_path_expansion(path: str, expected_expanded: str) -> None: + expanded: str = get_expanded_path(path) + assert expanded == expected_expanded + + +@pytest.mark.parametrize('path', [ + ('$'), + ('$NON_EXISTENT_VARIABLE'), + ('/path/to/something/$'), + ('/path/to/something/$NON_EXISTENT_VARIABLE') +]) +def test_path_expansion_failure(path: str) -> None: + with pytest.raises(SystemExit) as system_exit: + get_expanded_path(path) + assert system_exit.type == SystemExit + assert system_exit.value.code == 1 + + +def test_checksum(test_dir: str, simple_yaml: str) -> None: + path: str = f'{test_dir}/io_files/{simple_yaml}' + simple_yaml_checksum: str = 'd4f0a3ed56fd530d3ea485dced25534c' + checksum: str = get_checksum(path) + assert checksum == simple_yaml_checksum + + +def test_copy_file(tmp_path: Path, caplog: LogCaptureFixture) -> None: + src: Path = tmp_path/'src' + dst: Path = tmp_path/'dst' + src.mkdir() + dst.mkdir() + src_file: Path = src/'tmp_file.txt' + dst_file: Path = dst/'tmp_file.txt' + src_file.write_text('something') + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'copied file "{src_file}" to "{dst_file}"') + copy_file(str(src_file), str(dst_file)) + assert caplog.record_tuples[-1] == inf + + +def test_copy_file_failure(tmp_path: Path, caplog: LogCaptureFixture) -> None: + src: Path = tmp_path/'src' + dst: Path = tmp_path/'dst' + src.mkdir() + dst.mkdir() + src_file: Path = src/'tmp_file.txt' + dst_file: Path = dst/'tmp_file.txt' + src_file.write_text('something') + dst_file.write_text('something') + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'file "{dst_file}" already exists, ignoring') + copy_file(str(src_file), str(dst_file)) + assert caplog.record_tuples[-1] == inf + + +def test_create_dir(tmp_path: Path, caplog: LogCaptureFixture) -> None: + path: Path = tmp_path/'new_dir' + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'created directory "{path}"') + assert path.exists() is False + create_dir(str(path), False, False) + assert path.exists() is True + assert caplog.record_tuples[-1] == inf + + +def test_create_dir_failure(tmp_path: Path, caplog: LogCaptureFixture) -> None: + path: Path = tmp_path/'new_dir' + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'directory "{path}" exists, ignoring') + path.mkdir() + create_dir(str(path), False, False) + assert caplog.record_tuples[-1] == inf + + +def test_create_dirs(tmp_path: Path, caplog: LogCaptureFixture) -> None: + path: Path = tmp_path/'new_dir' + sub_path: Path = path/'sub_dir' + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'created directory "{sub_path}"') + assert path.exists() is False + assert sub_path.exists() is False + create_dir(str(sub_path), True, False) + assert path.exists() is True + assert sub_path.exists() is True + assert caplog.record_tuples[-1] == inf + + +def test_create_dirs_failure(tmp_path: Path, caplog: LogCaptureFixture) -> None: + path: Path = tmp_path/'new_dir' + sub_path: Path = path/'sub_dir' + inf: tuple[str, int, str] = ('pyssg.utils', + INFO, + f'directory "{sub_path}" exists, ignoring') + path.mkdir() + sub_path.mkdir() + create_dir(str(sub_path), True, False) + assert caplog.record_tuples[-1] == inf + + +@pytest.mark.parametrize('exclude, exp_dir_str', [ + ([], ['second/s1', 'first/f1/f2']), + (['f2'], ['second/s1', 'first/f1']), + (['f1'], ['second/s1', 'first']), + (['second'], ['first/f1/f2']), + (['s1', 'f2'], ['second', 'first/f1']), + (['s1', 'f1'], ['second', 'first']), + (['s1', 'first'], ['second']) +]) +def test_dir_structure(tmp_dir_structure: Path, + exclude: list[str], + exp_dir_str: list[str]) -> None: + dir_str: list[str] = get_dir_structure(str(tmp_dir_structure), exclude) + # order doesn't matter + assert sorted(dir_str) == sorted(exp_dir_str) + + +@pytest.mark.parametrize('exts, exclude_dirs, exp_flist', [ + (('txt',), [], ['f0.txt', 'second/f4.txt', + 'second/s1/f5.txt', 'first/f1.txt', + 'first/f1/f2.txt', 'first/f1/f2/f3.txt']), + (('txt', 'html'), [], ['f0.html', 'f0.txt', + 'second/f4.txt', 'second/f4.html', + 'second/s1/f5.html', 'second/s1/f5.txt', + 'first/f1.html', 'first/f1.txt', + 'first/f1/f2.txt', 'first/f1/f2.html', + 'first/f1/f2/f3.txt', 'first/f1/f2/f3.html']), + (('md',), [], ['f0.md', 'second/f4.md', + 'second/s1/f5.md', 'first/f1.md', + 'first/f1/f2.md', 'first/f1/f2/f3.md']), + (('md',), ['first'], ['f0.md', 'second/f4.md', 'second/s1/f5.md']), + (('md',), ['first', 's1'], ['f0.md', 'second/f4.md']), + (('md',), ['f2', 's1'], ['f0.md', 'second/f4.md', + 'first/f1.md', 'first/f1/f2.md',]), +]) +def test_file_list(tmp_dir_structure: Path, + exts: tuple[str], + exclude_dirs: list[str], + exp_flist: list[str]) -> None: + flist: list[str] = get_file_list(str(tmp_dir_structure), exts, exclude_dirs) + # order doesn't matter + assert sorted(flist) == sorted(exp_flist) diff --git a/tests/test_yaml_parser.py b/tests/test_yaml_parser.py index dd4c6d4..906c7e6 100644 --- a/tests/test_yaml_parser.py +++ b/tests/test_yaml_parser.py @@ -5,7 +5,7 @@ from pyssg.yaml_parser import get_parsed_yaml # and test the join functionality -def test_yaml_resource_read(simple_yaml:str, test_resource: str) -> None: +def test_yaml_resource_read(simple_yaml: str, test_resource: str) -> None: yaml: list[dict[str, Any]] = get_parsed_yaml(simple_yaml, test_resource) assert len(yaml) == 1 @@ -16,7 +16,7 @@ def test_yaml_path_read(test_dir: str) -> None: assert len(yaml) == 1 -def test_yaml_join(simple_yaml:str, test_resource: str) -> None: +def test_yaml_join(simple_yaml: str, test_resource: str) -> None: yaml: dict[str, Any] = get_parsed_yaml(simple_yaml, test_resource)[0] define_str: str = '$PYSSG_HOME/pyssg/site_example/' assert yaml['define'] == define_str |