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

1from string.templatelib import Template 

2 

3import pytest 

4 

5from .source import LinePosition, SourceReader, template_repr 

6from .template_utils import PartPosition, TemplateRef 

7 

8 

9class TestSourceReader: 

10 """ 

11 Top-level tests for SourceReader class. 

12 

13 More in depth tests are handled in more specialized test. 

14 """ 

15 

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 ) 

21 

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" 

26 

27 def test_make_interpolation_repr(self): 

28 reader = SourceReader(template=t"<div>{'content'}</div>") 

29 assert reader.make_interpolation_repr(0) == "{'content'}" 

30 

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>")) 

36 

37 

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 

61 

62 

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) 

69 

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 ) 

77 

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 ) 

85 

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 ) 

97 

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 )