Public Access
DEVX-153: feat: sync missing features from v0.49.x line to master
Co-authored-by: emil User <emil.simeonov@tutanota.com>
This commit was merged in pull request #267.
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
"""Unit tests for devx.utils.jinja."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import jinja2
|
||||
|
||||
from devx.utils.jinja import (
|
||||
make_env,
|
||||
make_value_env,
|
||||
regex_escape,
|
||||
regex_replace,
|
||||
regex_search,
|
||||
render_manifest_values,
|
||||
render_template,
|
||||
render_value,
|
||||
to_bool,
|
||||
to_json,
|
||||
)
|
||||
|
||||
|
||||
class TestFilters:
|
||||
def test_to_json(self):
|
||||
assert to_json({"a": 1}) == '{"a": 1}'
|
||||
|
||||
def test_to_json_list(self):
|
||||
assert to_json([1, 2]) == "[1, 2]"
|
||||
|
||||
def test_to_bool_true(self):
|
||||
assert to_bool(True) is True
|
||||
|
||||
def test_to_bool_false(self):
|
||||
assert to_bool(False) is False
|
||||
|
||||
def test_to_bool_string_true(self):
|
||||
assert to_bool("yes") is True
|
||||
|
||||
def test_to_bool_string_false(self):
|
||||
assert to_bool("false") is False
|
||||
|
||||
def test_to_bool_empty_string(self):
|
||||
assert to_bool("") is False
|
||||
|
||||
def test_to_bool_none(self):
|
||||
assert to_bool(None) is False
|
||||
|
||||
def test_to_bool_int(self):
|
||||
assert to_bool(1) is True
|
||||
assert to_bool(0) is False
|
||||
|
||||
def test_regex_replace(self):
|
||||
assert regex_replace("hello world", "world", "there") == "hello there"
|
||||
|
||||
def test_regex_replace_with_pattern(self):
|
||||
assert regex_replace("abc123", r"\d+", "X") == "abcX"
|
||||
|
||||
def test_regex_escape(self):
|
||||
assert regex_escape("a.b*c") == "a\\.b\\*c"
|
||||
|
||||
def test_regex_search_found(self):
|
||||
assert regex_search("hello world", r"world") == "world"
|
||||
|
||||
def test_regex_search_not_found(self):
|
||||
assert regex_search("hello", r"world") is None
|
||||
|
||||
def test_regex_search_group(self):
|
||||
assert regex_search("abc123", r"\d+") == "123"
|
||||
|
||||
|
||||
class TestMakeEnv:
|
||||
def test_returns_environment(self, tmp_path):
|
||||
(tmp_path / "test.j2").write_text("hello {{ name }}")
|
||||
env = make_env(str(tmp_path))
|
||||
assert isinstance(env, jinja2.Environment)
|
||||
|
||||
def test_has_filters(self, tmp_path):
|
||||
env = make_env(str(tmp_path))
|
||||
assert "to_json" in env.filters
|
||||
assert "bool" in env.filters
|
||||
assert "regex_replace" in env.filters
|
||||
assert "regex_escape" in env.filters
|
||||
assert "regex_search" in env.filters
|
||||
|
||||
def test_cached(self, tmp_path):
|
||||
env1 = make_env(str(tmp_path))
|
||||
env2 = make_env(str(tmp_path))
|
||||
assert env1 is env2
|
||||
|
||||
def test_auto_reload_disabled(self, tmp_path):
|
||||
env = make_env(str(tmp_path))
|
||||
assert env.auto_reload is False
|
||||
|
||||
def test_strict_undefined(self, tmp_path):
|
||||
env = make_env(str(tmp_path))
|
||||
assert env.undefined is jinja2.StrictUndefined
|
||||
|
||||
|
||||
class TestMakeValueEnv:
|
||||
def test_returns_environment(self):
|
||||
env = make_value_env()
|
||||
assert isinstance(env, jinja2.Environment)
|
||||
|
||||
def test_chainable_undefined(self):
|
||||
env = make_value_env()
|
||||
assert env.undefined is jinja2.ChainableUndefined
|
||||
|
||||
def test_cached(self):
|
||||
assert make_value_env() is make_value_env()
|
||||
|
||||
def test_has_filters(self):
|
||||
env = make_value_env()
|
||||
assert "to_json" in env.filters
|
||||
|
||||
|
||||
class TestRenderTemplate:
|
||||
def test_renders_named_template(self, tmp_path):
|
||||
(tmp_path / "test.j2").write_text("hello {{ name }}")
|
||||
env = make_env(str(tmp_path))
|
||||
assert render_template(env, "test.j2", name="world") == "hello world"
|
||||
|
||||
def test_renders_with_filters(self, tmp_path):
|
||||
(tmp_path / "test.j2").write_text("{{ data | to_json }}")
|
||||
env = make_env(str(tmp_path))
|
||||
assert render_template(env, "test.j2", data={"a": 1}) == '{"a": 1}'
|
||||
|
||||
|
||||
class TestRenderValue:
|
||||
def test_renders_string_with_expressions(self):
|
||||
assert render_value("hello {{ name }}", {"name": "world"}) == "hello world"
|
||||
|
||||
def test_passes_through_non_string(self):
|
||||
assert render_value(42, {}) == 42
|
||||
|
||||
def test_passes_through_string_without_expressions(self):
|
||||
assert render_value("plain text", {}) == "plain text"
|
||||
|
||||
def test_passes_through_none(self):
|
||||
assert render_value(None, {}) is None
|
||||
|
||||
|
||||
class TestRenderManifestValues:
|
||||
def test_renders_dict_values(self):
|
||||
result = render_manifest_values({"key": "{{ value }}"}, {"value": "rendered"})
|
||||
assert result == {"key": "rendered"}
|
||||
|
||||
def test_renders_list_values(self):
|
||||
result = render_manifest_values(["{{ a }}", "{{ b }}"], {"a": "1", "b": "2"})
|
||||
assert result == ["1", "2"]
|
||||
|
||||
def test_renders_nested(self):
|
||||
result = render_manifest_values({"outer": {"inner": "{{ x }}"}}, {"x": "yes"})
|
||||
assert result == {"outer": {"inner": "yes"}}
|
||||
|
||||
def test_passes_through_non_string(self):
|
||||
result = render_manifest_values({"n": 42, "b": True, "l": [1, 2]}, {})
|
||||
assert result == {"n": 42, "b": True, "l": [1, 2]}
|
||||
|
||||
def test_empty_dict(self):
|
||||
assert render_manifest_values({}, {}) == {}
|
||||
|
||||
def test_empty_list(self):
|
||||
assert render_manifest_values([], {}) == []
|
||||
Reference in New Issue
Block a user