Refactor handlers to be in their own classes for easier maintainability
This commit is contained in:
parent
d1ca60b779
commit
85f21e739d
19 changed files with 1826 additions and 1463 deletions
114
tests/test_toml_handler.py
Normal file
114
tests/test_toml_handler.py
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
)
|
||||
from jinjaturtle.handlers.toml import TomlHandler
|
||||
import jinjaturtle.handlers.toml as toml_module
|
||||
|
||||
SAMPLES_DIR = Path(__file__).parent / "samples"
|
||||
|
||||
|
||||
def test_toml_sample_roundtrip():
|
||||
toml_path = SAMPLES_DIR / "tom.toml"
|
||||
assert toml_path.is_file(), f"Missing sample TOML file: {toml_path}"
|
||||
|
||||
fmt, parsed = parse_config(toml_path)
|
||||
assert fmt == "toml"
|
||||
|
||||
flat_items = flatten_config(fmt, parsed)
|
||||
assert flat_items
|
||||
|
||||
defaults_yaml = generate_defaults_yaml("jinjaturtle", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
|
||||
# defaults should be a non-empty dict
|
||||
assert isinstance(defaults, dict)
|
||||
assert defaults, "Expected non-empty defaults for TOML sample"
|
||||
|
||||
# all keys should be lowercase, start with prefix, and have no spaces
|
||||
for key in defaults:
|
||||
assert key.startswith("jinjaturtle_")
|
||||
assert key == key.lower()
|
||||
assert " " not in key
|
||||
|
||||
# template generation – **now with original_text**
|
||||
original_text = toml_path.read_text(encoding="utf-8")
|
||||
template = generate_template(
|
||||
fmt, parsed, "jinjaturtle", original_text=original_text
|
||||
)
|
||||
assert isinstance(template, str)
|
||||
assert template.strip()
|
||||
|
||||
# comments from the original file should now be preserved
|
||||
assert "# This is a TOML document" in template
|
||||
|
||||
# each default variable name should appear in the template as a Jinja placeholder
|
||||
for var_name in defaults:
|
||||
assert (
|
||||
var_name in template
|
||||
), f"Variable {var_name} not referenced in TOML template"
|
||||
|
||||
|
||||
def test_parse_config_toml_missing_tomllib(monkeypatch):
|
||||
"""
|
||||
Force tomllib to None to hit the RuntimeError branch when parsing TOML.
|
||||
"""
|
||||
toml_path = SAMPLES_DIR / "tom.toml"
|
||||
|
||||
# Simulate an environment without tomllib/tomli
|
||||
monkeypatch.setattr(toml_module, "tomllib", None)
|
||||
|
||||
with pytest.raises(RuntimeError) as exc:
|
||||
parse_config(toml_path, fmt="toml")
|
||||
assert "tomllib/tomli is required" in str(exc.value)
|
||||
|
||||
|
||||
def test_generate_template_fallback_toml():
|
||||
"""
|
||||
When original_text is not provided, generate_template should use the
|
||||
structural fallback path for TOML configs.
|
||||
"""
|
||||
parsed_toml = {
|
||||
"title": "Example",
|
||||
"server": {"port": 8080, "host": "127.0.0.1"},
|
||||
"logging": {
|
||||
"file": {"path": "/tmp/app.log"}
|
||||
}, # nested table to hit recursive walk
|
||||
}
|
||||
tmpl_toml = generate_template("toml", parsed=parsed_toml, role_prefix="role")
|
||||
assert "[server]" in tmpl_toml
|
||||
assert "role_server_port" in tmpl_toml
|
||||
assert "[logging]" in tmpl_toml or "[logging.file]" in tmpl_toml
|
||||
|
||||
|
||||
def test_generate_toml_template_from_text_edge_cases():
|
||||
# Cover CRLF newlines, lines without '=', empty keys, and inline tables
|
||||
# that both parse successfully and fail parsing.
|
||||
text = (
|
||||
"# comment\r\n"
|
||||
"[table]\r\n"
|
||||
"noequals\r\n"
|
||||
" = 42\r\n"
|
||||
'inline_good = { name = "abc", value = 1 }\r\n'
|
||||
"inline_bad = { invalid = }\r\n"
|
||||
)
|
||||
handler = TomlHandler()
|
||||
tmpl = handler._generate_toml_template_from_text("role", text)
|
||||
|
||||
# The good inline table should expand into two separate variables.
|
||||
assert "role_table_inline_good_name" in tmpl
|
||||
assert "role_table_inline_good_value" in tmpl
|
||||
# The bad inline table should fall back to scalar handling.
|
||||
assert "role_table_inline_bad" in tmpl
|
||||
# Ensure the lines without '=' / empty key were handled without exploding.
|
||||
assert "[table]" in tmpl
|
||||
assert "noequals" in tmpl
|
||||
Loading…
Add table
Add a link
Reference in a new issue