pyrtan / sourcev0.14.0 · main

pyrtan / tests / test_template.py

2,282 bytes · last changed 2026-10-25 in Initial public release

1import pytest
2
3from pyrtan.template import MISSING, TemplateError, placeholders, render, resolve
4
5SCOPE = {"inputs": {"city": "New York", "n": 3}, "state": {"resp": {"json": {"items": [{"title": "a"}, {"title": "b"}]}, "status": 200}, "ids": [1, 2, 3]}}
6
7
8def test_resolve_paths():
9 assert resolve("inputs.city", SCOPE) == "New York"
10 assert resolve("state.resp.json.items[1].title", SCOPE) == "b"
11 assert resolve("state.resp.json.items[-1].title", SCOPE) == "b"
12 assert resolve("state.ids[5]", SCOPE) is MISSING
13 assert resolve("state.nope.deeper", SCOPE) is MISSING
14 assert resolve('state.resp["status"]', SCOPE) == 200
15
16
17def test_whole_placeholder_keeps_type():
18 assert render("{{ state.ids }}", SCOPE) == [1, 2, 3]
19 assert render("{{ state.resp.status }}", SCOPE) == 200
20
21
22def test_interpolation_and_filters():
23 assert render("city={{ inputs.city | url }}", SCOPE) == "city=New%20York"
24 assert render("{{ inputs.city | lower }} x{{ inputs.n }}", SCOPE) == "new york x3"
25 assert render("{{ state.ids | length }}", SCOPE) == 3
26 assert render("{{ state.ids | first }}", SCOPE) == 1
27 assert render("{{ state.resp.json.items | json }}", SCOPE) == '[{"title": "a"}, {"title": "b"}]'
28
29
30def test_nested_structures_render():
31 out = render({"url": "https://x/{{ inputs.n }}", "list": ["{{ inputs.city }}", 1]}, SCOPE)
32 assert out == {"url": "https://x/3", "list": ["New York", 1]}
33
34
35def test_missing_is_an_error_unless_lenient():
36 with pytest.raises(TemplateError):
37 render("{{ state.nothing }}", SCOPE)
38 with pytest.raises(TemplateError):
39 render("x {{ state.nothing }} y", SCOPE)
40 assert render("x {{ state.nothing }} y", SCOPE, strict=False) == "x y"
41 assert render("{{ state.nothing }}", SCOPE, strict=False) is None
42
43
44def test_unknown_filter():
45 with pytest.raises(TemplateError):
46 render("{{ inputs.city | shout }}", SCOPE)
47
48
49def test_multiple_placeholders_are_not_one():
50 # A regression: a greedy placeholder regex once swallowed the text between two.
51 assert render("{{ inputs.city }} ({{ inputs.n }})", SCOPE) == "New York (3)"
52
53
54def test_placeholders_listing():
55 assert placeholders({"a": "{{ inputs.x | url }}", "b": ["{{ state.y }}", "{{ item }}"]}) == ["inputs.x", "state.y", "item"]