Files
omicron-ssg/tests/unit/test_config.py
T

189 lines
5.8 KiB
Python

from pathlib import Path
import pytest
from omicron.ssg.config import SiteConfig, ConfigError, DEFAULT_ITEMS_PER_PAGE
@pytest.mark.parametrize(
"value, expected_origin, expected_path",
[
(None, "", Path("/")),
("http://example.com/blog", "http://example.com", Path("/blog")),
("http://example.com", "http://example.com", Path("/")),
("//example.com/blog", "//example.com", Path("/blog")),
("/blog", "", Path("/blog")),
],
)
def test_parse_base_url(value, expected_origin, expected_path):
origin, path = SiteConfig.parse_base_url(value)
assert origin == expected_origin
assert path == expected_path
@pytest.mark.parametrize(
"value, expected_message",
[
("https://[::1", "invalid url format"),
("relative/path", "relative path"),
],
)
def test_parse_base_url_error(value, expected_message):
with pytest.raises(ConfigError, match=expected_message):
origin, path = SiteConfig.parse_base_url(value)
def test_from_dict_minimal():
config = SiteConfig.from_dict({"name": "My Site", "template": "plain"})
assert config.name == "My Site"
assert config.template == "plain"
assert config.items_per_page == DEFAULT_ITEMS_PER_PAGE
assert config.origin == ""
assert config.base_dir == Path("/")
def test_from_dict_full():
config = SiteConfig.from_dict(
{
"name": "My Site",
"template": "plain",
"base_url": "http://example.com/blog",
"items_per_page": 42,
}
)
assert config.name == "My Site"
assert config.template == "plain"
assert config.items_per_page == 42
assert config.origin == "http://example.com"
assert config.base_dir == Path("/blog")
MISSING = object()
@pytest.mark.parametrize(
"overrides, expected_message",
[
({"name": MISSING}, "must contain a name property"),
({"template": MISSING}, "must contain a template property"),
({"name": 123}, "name config property must be a string"),
({"template": 123}, "template config property must be a string"),
({"base_url": 123}, "base_url config property must be a string"),
({"base_url": "relative/path"}, "relative path"),
({"base_url": "https://[::1"}, "invalid url format"),
(
{"items_per_page": "10"},
"items_per_page config property must be a positive integer",
),
(
{"items_per_page": 0},
"items_per_page config property must be a positive integer",
),
(
{"items_per_page": -1},
"items_per_page config property must be a positive integer",
),
],
)
def test_from_dict_error(overrides, expected_message):
config = {"name": "My Site", "template": "plain"}
for key, value in overrides.items():
if value is MISSING:
config.pop(key, None)
else:
config[key] = value
with pytest.raises(ConfigError, match=expected_message):
SiteConfig.from_dict(config)
def test_from_file_minimal(tmp_path):
path = tmp_path / "config.yml"
path.write_text("name: My Site\ntemplate: plain\n")
config = SiteConfig.from_file(path)
assert config.name == "My Site"
assert config.template == "plain"
assert config.items_per_page == DEFAULT_ITEMS_PER_PAGE
assert config.origin == ""
assert config.base_dir == Path("/")
def test_from_file_full(tmp_path):
path = tmp_path / "config.yml"
path.write_text(
"name: My Site\n"
"template: plain\n"
"base_url: http://example.com/blog\n"
"items_per_page: 42\n"
)
config = SiteConfig.from_file(path)
assert config.name == "My Site"
assert config.template == "plain"
assert config.items_per_page == 42
assert config.origin == "http://example.com"
assert config.base_dir == Path("/blog")
def test_from_file_missing(tmp_path):
path = tmp_path / "config.yml"
with pytest.raises(ConfigError, match="config file missing"):
SiteConfig.from_file(path)
@pytest.mark.parametrize(
"yaml_text, expected_message",
[
("- a\n- b\n", "must be a YAML mapping"),
("just a string\n", "must be a YAML mapping"),
("123: value\n", "must be a YAML mapping"),
("name: [1, 2]\n", "must be a YAML mapping"),
("name: true\n", "must be a YAML mapping"),
(":\n bad: yaml: here\n", "must be a valid YAML file"),
("template: plain\n", "must contain a name property"),
("name: My Site\n", "must contain a template property"),
(
"name: 123\ntemplate: plain\n",
"name config property must be a string",
),
(
"name: My Site\ntemplate: 123\n",
"template config property must be a string",
),
(
"name: My Site\ntemplate: plain\nbase_url: 123\n",
"base_url config property must be a string",
),
(
"name: My Site\ntemplate: plain\nbase_url: relative/path\n",
"relative path",
),
(
"name: My Site\ntemplate: plain\nbase_url: https://[::1\n",
"invalid url format",
),
(
'name: My Site\ntemplate: plain\nitems_per_page: "10"\n',
"items_per_page config property must be a positive integer",
),
(
"name: My Site\ntemplate: plain\nitems_per_page: 0\n",
"items_per_page config property must be a positive integer",
),
(
"name: My Site\ntemplate: plain\nitems_per_page: -1\n",
"items_per_page config property must be a positive integer",
),
],
)
def test_from_file_error(tmp_path, yaml_text, expected_message):
path = tmp_path / "config.yml"
path.write_text(yaml_text)
with pytest.raises(ConfigError, match=expected_message):
SiteConfig.from_file(path)