Coverage for tdom/source_test.py: 100%
48 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-19 21:37 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-19 21:37 +0000
1from string.templatelib import Template
3import pytest
5from .source import LinePosition, SourceReader, template_repr
6from .template_utils import PartPosition, TemplateRef
9class TestSourceReader:
10 """
11 Top-level tests for SourceReader class.
13 More in depth tests are handled in more specialized test.
14 """
16 def test_ref_to_repr(self):
17 reader = SourceReader(template=t"a{'b'!s}c")
18 assert (
19 reader.ref_to_repr(TemplateRef(strings=("A", ""), i_start=0)) == "A{'b'!s}"
20 )
22 def test_make_template_pos_msg(self):
23 reader = SourceReader(template=t"<div>{'content'}</div>")
24 msg = reader.make_template_pos_msg(source_pos=PartPosition(s_index=0, offset=1))
25 assert msg == "line 1 offset 1"
27 def test_make_interpolation_repr(self):
28 reader = SourceReader(template=t"<div>{'content'}</div>")
29 assert reader.make_interpolation_repr(0) == "{'content'}"
31 def test_to_template_pos(self):
32 reader = SourceReader(template=t"<div>{'content'}</div>")
33 assert reader.to_template_pos(
34 PartPosition(s_index=0, offset=len("<div>"))
35 ) == LinePosition(line=1, offset=len("<div>"))
38class TestTemplateRepresentation:
39 # whitespace is part of test
40 # fmt: off
41 @pytest.mark.parametrize(
42 ("t", "result"),
43 (
44 (t"<div>{15!s:formatspec}</div>", "<div>{15!s:formatspec}</div>"),
45 (t"<div>{15:formatspec}</div>", "<div>{15:formatspec}</div>"),
46 (t"<div>{15!s}</div>", "<div>{15!s}</div>"),
47 (t"<div>{15}</div>", "<div>{15}</div>"),
48 (t"{15}", "{15}"),
49 (t"", ""),
50 (t"A{0}B{1}{2}C", "A{0}B{1}{2}C"),
51 (t"ABC", "ABC"),
52 (t"""<div>
53</div>""", """<div>\n</div>"""),
54 (t"""{'''
55'''}""", """{'''\n'''}"""),
56 )
57 )
58 def test_repr(self, t: Template, result: str):
59 assert template_repr(t) == result
60 # fmt: on
63class TestToTemplatePosition:
64 def test_origin(self):
65 t = t"<div>{'content'}</div>"
66 reader = SourceReader(template=t)
67 source_pos = PartPosition(s_index=0, offset=0)
68 assert reader.to_template_pos(source_pos) == LinePosition(line=1, offset=0)
70 def test_offset_no_lines(self):
71 t = t"<div>{'content'}</div>"
72 reader = SourceReader(template=t)
73 source_pos = PartPosition(s_index=0, offset=len(t.strings[0]))
74 assert reader.to_template_pos(source_pos) == LinePosition(
75 line=1, offset=len(t.strings[0])
76 )
78 def test_offset_full_interpolation(self):
79 t = t"<div>{''!s:lower}</div>" # conversion and formatspec
80 reader = SourceReader(template=t)
81 source_pos = PartPosition(s_index=1, offset=0)
82 assert reader.to_template_pos(source_pos) == LinePosition(
83 line=1, offset=len('<div>{""!s:lower}')
84 )
86 def test_line(self):
87 # whitespace is part of test
88 # fmt: off
89 t = t"""<div>
90{"content"}</div>"""
91 # fmt: on
92 reader = SourceReader(template=t)
93 source_pos = PartPosition(s_index=1, offset=0)
94 assert reader.to_template_pos(source_pos) == LinePosition(
95 line=2, offset=len('{"content"}')
96 )
98 def test_line_in_interpolation(self):
99 # whitespace is part of test
100 # fmt: off
101 t = t"""<div>
102{'''
103content
104'''}</div>"""
105 # fmt: on
106 reader = SourceReader(template=t)
107 source_pos = PartPosition(s_index=1, offset=0)
108 assert reader.to_template_pos(source_pos) == LinePosition(
109 line=4, offset=len("'''}")
110 )