Rename some methods, merge the loopable classes and just always try it
This commit is contained in:
parent
2db80cc6e1
commit
f66f58a7bb
20 changed files with 702 additions and 1051 deletions
|
|
@ -31,4 +31,4 @@ def test_base_handler_abstract_methods_raise_not_implemented(tmp_path: Path):
|
|||
handler.flatten(object())
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
handler.generate_template(parsed=object(), role_prefix="role")
|
||||
handler.generate_jinja2_template(parsed=object(), role_prefix="role")
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ from jinjaturtle.core import (
|
|||
detect_format,
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
generate_ansible_yaml,
|
||||
generate_jinja2_template,
|
||||
make_var_name,
|
||||
)
|
||||
|
||||
|
|
@ -90,9 +90,9 @@ def test_parse_config_unsupported_format(tmp_path: Path):
|
|||
parse_config(cfg_path, fmt="bogus")
|
||||
|
||||
|
||||
def test_generate_template_type_and_format_errors():
|
||||
def test_generate_jinja2_template_type_and_format_errors():
|
||||
"""
|
||||
Exercise the error branches in generate_template:
|
||||
Exercise the error branches in generate_jinja2_template:
|
||||
- toml with non-dict parsed
|
||||
- ini with non-ConfigParser parsed
|
||||
- yaml with wrong parsed type
|
||||
|
|
@ -101,27 +101,29 @@ def test_generate_template_type_and_format_errors():
|
|||
"""
|
||||
# wrong type for TOML
|
||||
with pytest.raises(TypeError):
|
||||
generate_template("toml", parsed="not a dict", role_prefix="role")
|
||||
generate_jinja2_template("toml", parsed="not a dict", role_prefix="role")
|
||||
|
||||
# wrong type for INI
|
||||
with pytest.raises(TypeError):
|
||||
generate_template("ini", parsed={"not": "a configparser"}, role_prefix="role")
|
||||
generate_jinja2_template(
|
||||
"ini", parsed={"not": "a configparser"}, role_prefix="role"
|
||||
)
|
||||
|
||||
# wrong type for YAML
|
||||
with pytest.raises(TypeError):
|
||||
generate_template("yaml", parsed=None, role_prefix="role")
|
||||
generate_jinja2_template("yaml", parsed=None, role_prefix="role")
|
||||
|
||||
# wrong type for JSON
|
||||
with pytest.raises(TypeError):
|
||||
generate_template("json", parsed=None, role_prefix="role")
|
||||
generate_jinja2_template("json", parsed=None, role_prefix="role")
|
||||
|
||||
# unsupported format, no original_text
|
||||
with pytest.raises(ValueError):
|
||||
generate_template("bogusfmt", parsed=None, role_prefix="role")
|
||||
generate_jinja2_template("bogusfmt", parsed=None, role_prefix="role")
|
||||
|
||||
# unsupported format, with original_text
|
||||
with pytest.raises(ValueError):
|
||||
generate_template(
|
||||
generate_jinja2_template(
|
||||
"bogusfmt",
|
||||
parsed=None,
|
||||
role_prefix="role",
|
||||
|
|
@ -135,8 +137,8 @@ def test_normalize_default_value_true_false_strings():
|
|||
(("section", "foo"), "true"),
|
||||
(("section", "bar"), "FALSE"),
|
||||
]
|
||||
defaults_yaml = generate_defaults_yaml("role", flat_items)
|
||||
data = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("role", flat_items)
|
||||
data = yaml.safe_load(ansible_yaml)
|
||||
assert data["role_section_foo"] == "true"
|
||||
assert data["role_section_bar"] == "FALSE"
|
||||
|
||||
|
|
@ -167,14 +169,14 @@ def test_fallback_str_representer_for_unknown_type():
|
|||
def test_normalize_default_value_bool_inputs_are_stringified():
|
||||
"""
|
||||
Real boolean values should be turned into quoted 'true'/'false' strings
|
||||
by _normalize_default_value via generate_defaults_yaml.
|
||||
by _normalize_default_value via generate_ansible_yaml.
|
||||
"""
|
||||
flat_items = [
|
||||
(("section", "flag_true"), True),
|
||||
(("section", "flag_false"), False),
|
||||
]
|
||||
defaults_yaml = generate_defaults_yaml("role", flat_items)
|
||||
data = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("role", flat_items)
|
||||
data = yaml.safe_load(ansible_yaml)
|
||||
|
||||
assert data["role_section_flag_true"] == "true"
|
||||
assert data["role_section_flag_false"] == "false"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import yaml
|
|||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
generate_ansible_yaml,
|
||||
generate_jinja2_template,
|
||||
)
|
||||
from jinjaturtle.handlers.ini import IniHandler
|
||||
|
||||
|
|
@ -26,8 +26,8 @@ def test_ini_php_sample_roundtrip():
|
|||
flat_items = flatten_config(fmt, parsed)
|
||||
assert flat_items, "Expected at least one flattened item from php.ini sample"
|
||||
|
||||
defaults_yaml = generate_defaults_yaml("php", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("php", flat_items)
|
||||
defaults = yaml.safe_load(ansible_yaml)
|
||||
|
||||
# defaults should be a non-empty dict
|
||||
assert isinstance(defaults, dict)
|
||||
|
|
@ -41,7 +41,7 @@ def test_ini_php_sample_roundtrip():
|
|||
|
||||
# template generation
|
||||
original_text = ini_path.read_text(encoding="utf-8")
|
||||
template = generate_template(fmt, parsed, "php", original_text=original_text)
|
||||
template = generate_jinja2_template(fmt, parsed, "php", original_text=original_text)
|
||||
assert "; About this file" in template
|
||||
assert isinstance(template, str)
|
||||
assert template.strip(), "Template for php.ini sample should not be empty"
|
||||
|
|
@ -53,16 +53,16 @@ def test_ini_php_sample_roundtrip():
|
|||
), f"Variable {var_name} not referenced in INI template"
|
||||
|
||||
|
||||
def test_generate_template_fallback_ini():
|
||||
def test_generate_jinja2_template_fallback_ini():
|
||||
"""
|
||||
When original_text is not provided, generate_template should use the
|
||||
When original_text is not provided, generate_jinja2_template should use the
|
||||
structural fallback path for INI configs.
|
||||
"""
|
||||
parser = configparser.ConfigParser()
|
||||
# foo is quoted in the INI text to hit the "preserve quotes" branch
|
||||
parser["section"] = {"foo": '"bar"', "num": "42"}
|
||||
|
||||
tmpl_ini = generate_template("ini", parsed=parser, role_prefix="role")
|
||||
tmpl_ini = generate_jinja2_template("ini", parsed=parser, role_prefix="role")
|
||||
assert "[section]" in tmpl_ini
|
||||
assert "role_section_foo" in tmpl_ini
|
||||
assert '"{{ role_section_foo }}"' in tmpl_ini # came from quoted INI value
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import yaml
|
|||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_ansible_yaml,
|
||||
)
|
||||
from jinjaturtle.handlers.json import JsonHandler
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ def test_json_roundtrip():
|
|||
assert fmt == "json"
|
||||
|
||||
flat_items = flatten_config(fmt, parsed)
|
||||
defaults_yaml = generate_defaults_yaml("foobar", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("foobar", flat_items)
|
||||
defaults = yaml.safe_load(ansible_yaml)
|
||||
|
||||
# Defaults: nested keys and list indices
|
||||
assert defaults["foobar_foo"] == "bar"
|
||||
|
|
@ -35,10 +35,12 @@ def test_json_roundtrip():
|
|||
assert defaults["foobar_list_0"] == 10
|
||||
assert defaults["foobar_list_1"] == 20
|
||||
|
||||
# Template generation is done via JsonHandler.generate_template; we just
|
||||
# Template generation is done via JsonHandler.generate_jinja2_template; we just
|
||||
# make sure it produces a structure with the expected placeholders.
|
||||
handler = JsonHandler()
|
||||
templated = json.loads(handler.generate_template(parsed, role_prefix="foobar"))
|
||||
templated = json.loads(
|
||||
handler.generate_jinja2_template(parsed, role_prefix="foobar")
|
||||
)
|
||||
|
||||
assert templated["foo"] == "{{ foobar_foo }}"
|
||||
assert "foobar_nested_a" in str(templated)
|
||||
|
|
@ -47,10 +49,10 @@ def test_json_roundtrip():
|
|||
assert "foobar_list_1" in str(templated)
|
||||
|
||||
|
||||
def test_generate_template_json_type_error():
|
||||
def test_generate_jinja2_template_json_type_error():
|
||||
"""
|
||||
Wrong type for JSON in JsonHandler.generate_template should raise TypeError.
|
||||
Wrong type for JSON in JsonHandler.generate_jinja2_template should raise TypeError.
|
||||
"""
|
||||
handler = JsonHandler()
|
||||
with pytest.raises(TypeError):
|
||||
handler.generate_template(parsed="not a dict", role_prefix="role")
|
||||
handler.generate_jinja2_template(parsed="not a dict", role_prefix="role")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import yaml
|
|||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
generate_ansible_yaml,
|
||||
generate_jinja2_template,
|
||||
)
|
||||
from jinjaturtle.handlers.toml import TomlHandler
|
||||
import jinjaturtle.handlers.toml as toml_module
|
||||
|
|
@ -27,8 +27,8 @@ def test_toml_sample_roundtrip():
|
|||
flat_items = flatten_config(fmt, parsed)
|
||||
assert flat_items
|
||||
|
||||
defaults_yaml = generate_defaults_yaml("jinjaturtle", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("jinjaturtle", flat_items)
|
||||
defaults = yaml.safe_load(ansible_yaml)
|
||||
|
||||
# defaults should be a non-empty dict
|
||||
assert isinstance(defaults, dict)
|
||||
|
|
@ -42,7 +42,7 @@ def test_toml_sample_roundtrip():
|
|||
|
||||
# template generation – **now with original_text**
|
||||
original_text = toml_path.read_text(encoding="utf-8")
|
||||
template = generate_template(
|
||||
template = generate_jinja2_template(
|
||||
fmt, parsed, "jinjaturtle", original_text=original_text
|
||||
)
|
||||
assert isinstance(template, str)
|
||||
|
|
@ -72,9 +72,9 @@ def test_parse_config_toml_missing_tomllib(monkeypatch):
|
|||
assert "tomllib/tomli is required" in str(exc.value)
|
||||
|
||||
|
||||
def test_generate_template_fallback_toml():
|
||||
def test_generate_jinja2_template_fallback_toml():
|
||||
"""
|
||||
When original_text is not provided, generate_template should use the
|
||||
When original_text is not provided, generate_jinja2_template should use the
|
||||
structural fallback path for TOML configs.
|
||||
"""
|
||||
parsed_toml = {
|
||||
|
|
@ -84,7 +84,7 @@ def test_generate_template_fallback_toml():
|
|||
"file": {"path": "/tmp/app.log"}
|
||||
}, # nested table to hit recursive walk
|
||||
}
|
||||
tmpl_toml = generate_template("toml", parsed=parsed_toml, role_prefix="role")
|
||||
tmpl_toml = generate_jinja2_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
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import yaml
|
|||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
generate_ansible_yaml,
|
||||
generate_jinja2_template,
|
||||
)
|
||||
from jinjaturtle.handlers.xml import XmlHandler
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ def test_xml_roundtrip_ossec_web_rules():
|
|||
flat_items = flatten_config(fmt, parsed)
|
||||
assert flat_items, "Expected at least one flattened item from XML sample"
|
||||
|
||||
defaults_yaml = generate_defaults_yaml("ossec", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("ossec", flat_items)
|
||||
defaults = yaml.safe_load(ansible_yaml)
|
||||
|
||||
# defaults should be a non-empty dict
|
||||
assert isinstance(defaults, dict)
|
||||
|
|
@ -55,7 +55,9 @@ def test_xml_roundtrip_ossec_web_rules():
|
|||
|
||||
# Template generation (preserving comments)
|
||||
original_text = xml_path.read_text(encoding="utf-8")
|
||||
template = generate_template(fmt, parsed, "ossec", original_text=original_text)
|
||||
template = generate_jinja2_template(
|
||||
fmt, parsed, "ossec", original_text=original_text
|
||||
)
|
||||
assert isinstance(template, str)
|
||||
assert template.strip(), "Template for XML sample should not be empty"
|
||||
|
||||
|
|
@ -108,13 +110,13 @@ def test_generate_xml_template_from_text_edge_cases():
|
|||
assert "role_child_1" in tmpl
|
||||
|
||||
|
||||
def test_generate_template_xml_type_error():
|
||||
def test_generate_jinja2_template_xml_type_error():
|
||||
"""
|
||||
Wrong type for XML in XmlHandler.generate_template should raise TypeError.
|
||||
Wrong type for XML in XmlHandler.generate_jinja2_template should raise TypeError.
|
||||
"""
|
||||
handler = XmlHandler()
|
||||
with pytest.raises(TypeError):
|
||||
handler.generate_template(parsed="not an element", role_prefix="role")
|
||||
handler.generate_jinja2_template(parsed="not an element", role_prefix="role")
|
||||
|
||||
|
||||
def test_flatten_config_xml_type_error():
|
||||
|
|
@ -125,9 +127,9 @@ def test_flatten_config_xml_type_error():
|
|||
flatten_config("xml", parsed="not-an-element")
|
||||
|
||||
|
||||
def test_generate_template_xml_structural_fallback():
|
||||
def test_generate_jinja2_template_xml_structural_fallback():
|
||||
"""
|
||||
When original_text is not provided for XML, generate_template should use
|
||||
When original_text is not provided for XML, generate_jinja2_template should use
|
||||
the structural fallback path (ET.tostring + handler processing).
|
||||
"""
|
||||
xml_text = textwrap.dedent(
|
||||
|
|
@ -140,7 +142,7 @@ def test_generate_template_xml_structural_fallback():
|
|||
)
|
||||
root = ET.fromstring(xml_text)
|
||||
|
||||
tmpl = generate_template("xml", parsed=root, role_prefix="role")
|
||||
tmpl = generate_jinja2_template("xml", parsed=root, role_prefix="role")
|
||||
|
||||
# Root attribute path ("@attr",) -> role_attr
|
||||
assert "role_attr" in tmpl
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import yaml
|
|||
from jinjaturtle.core import (
|
||||
parse_config,
|
||||
flatten_config,
|
||||
generate_defaults_yaml,
|
||||
generate_template,
|
||||
generate_ansible_yaml,
|
||||
generate_jinja2_template,
|
||||
)
|
||||
from jinjaturtle.handlers.yaml import YamlHandler
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ def test_yaml_roundtrip_with_list_and_comment():
|
|||
assert fmt == "yaml"
|
||||
|
||||
flat_items = flatten_config(fmt, parsed)
|
||||
defaults_yaml = generate_defaults_yaml("foobar", flat_items)
|
||||
defaults = yaml.safe_load(defaults_yaml)
|
||||
ansible_yaml = generate_ansible_yaml("foobar", flat_items)
|
||||
defaults = yaml.safe_load(ansible_yaml)
|
||||
|
||||
# Defaults: keys are flattened with indices
|
||||
assert defaults["foobar_foo"] == "bar"
|
||||
|
|
@ -34,7 +34,9 @@ def test_yaml_roundtrip_with_list_and_comment():
|
|||
|
||||
# Template generation (preserving comments)
|
||||
original_text = yaml_path.read_text(encoding="utf-8")
|
||||
template = generate_template(fmt, parsed, "foobar", original_text=original_text)
|
||||
template = generate_jinja2_template(
|
||||
fmt, parsed, "foobar", original_text=original_text
|
||||
)
|
||||
|
||||
# Comment preserved
|
||||
assert "# Top comment" in template
|
||||
|
|
@ -86,14 +88,14 @@ def test_generate_yaml_template_from_text_edge_cases():
|
|||
assert "role_list_1" in tmpl
|
||||
|
||||
|
||||
def test_generate_template_yaml_structural_fallback():
|
||||
def test_generate_jinja2_template_yaml_structural_fallback():
|
||||
"""
|
||||
When original_text is not provided for YAML, generate_template should use
|
||||
When original_text is not provided for YAML, generate_jinja2_template should use
|
||||
the structural fallback path (yaml.safe_dump + handler processing).
|
||||
"""
|
||||
parsed = {"outer": {"inner": "val"}}
|
||||
|
||||
tmpl = generate_template("yaml", parsed=parsed, role_prefix="role")
|
||||
tmpl = generate_jinja2_template("yaml", parsed=parsed, role_prefix="role")
|
||||
|
||||
# We don't care about exact formatting, just that the expected variable
|
||||
# name shows up, proving we went through the structural path.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue