67
67
self.assertEqual(export_pot._normalize(s), e)
70
class TestParseSource(tests.TestCase):
71
"""Check mappings to line numbers generated from python source"""
73
def test_classes(self):
81
cls_lines, _ = export_pot._parse_source(src)
82
self.assertEqual(cls_lines,
83
{"Ancient": 2, "Modern": 5})
85
def test_classes_nested(self):
87
class Matroska(object):
88
class Smaller(object):
89
class Smallest(object):
92
cls_lines, _ = export_pot._parse_source(src)
93
self.assertEqual(cls_lines,
94
{"Matroska": 2, "Smaller": 3, "Smallest":4})
96
def test_strings_docstrings(self):
109
_, str_lines = export_pot._parse_source(src)
110
self.assertEqual(str_lines,
111
{"Module": 1, "Function": 4, "Class": 7, "Method": 10})
113
def test_strings_literals(self):
117
f = dict(key="Three")
119
_, str_lines = export_pot._parse_source(src)
120
self.assertEqual(str_lines,
121
{"One": 1, "Two": 2, "Three": 3})
123
def test_strings_multiline(self):
135
_, str_lines = export_pot._parse_source(src)
136
self.assertEqual(str_lines,
137
{"Start\n\nEnd\n": 1, "ABC": 6})
139
def test_strings_multiline_escapes(self):
149
_, str_lines = export_pot._parse_source(src)
150
self.expectFailure("Escaped newlines confuses the multiline handling",
151
self.assertNotEqual, str_lines,
152
{"Escaped\n": 0, "Raw\\n": 2, "A\n\nB\n\nC\n\n": -2})
153
self.assertEqual(str_lines,
154
{"Escaped\n": 1, "Raw\\n": 2, "A\n\nB\n\nC\n\n": 4})
157
class TestModuleContext(tests.TestCase):
158
"""Checks for source context tracking objects"""
160
def check_context(self, context, path, lineno):
161
self.assertEquals((context.path, context.lineno), (path, lineno))
163
def test___init__(self):
164
context = export_pot._ModuleContext("one.py")
165
self.check_context(context, "one.py", 1)
166
context = export_pot._ModuleContext("two.py", 5)
167
self.check_context(context, "two.py", 5)
169
def test_from_class(self):
170
"""New context returned with lineno updated from class"""
172
class A(object): pass
173
class B(object): pass
174
cls_lines = {"A": 5, "B": 7}
175
context = export_pot._ModuleContext(path, _source_info=(cls_lines, {}))
176
contextA = context.from_class(A)
177
self.check_context(contextA, path, 5)
178
contextB1 = context.from_class(B)
179
self.check_context(contextB1, path, 7)
180
contextB2 = contextA.from_class(B)
181
self.check_context(contextB2, path, 7)
182
self.check_context(context, path, 1)
183
self.assertEquals("", self.get_log())
185
def test_from_class_missing(self):
186
"""When class has no lineno the old context details are returned"""
187
path = "cls_missing.py"
188
class A(object): pass
189
class M(object): pass
190
context = export_pot._ModuleContext(path, 3, ({"A": 15}, {}))
191
contextA = context.from_class(A)
192
contextM1 = context.from_class(M)
193
self.check_context(contextM1, path, 3)
194
contextM2 = contextA.from_class(M)
195
self.check_context(contextM2, path, 15)
196
self.assertContainsRe(self.get_log(), "Definition of <.*M'> not found")
198
def test_from_string(self):
199
"""New context returned with lineno updated from string"""
201
str_lines = {"one": 14, "two": 42}
202
context = export_pot._ModuleContext(path, _source_info=({}, str_lines))
203
context1 = context.from_string("one")
204
self.check_context(context1, path, 14)
205
context2A = context.from_string("two")
206
self.check_context(context2A, path, 42)
207
context2B = context1.from_string("two")
208
self.check_context(context2B, path, 42)
209
self.check_context(context, path, 1)
210
self.assertEquals("", self.get_log())
212
def test_from_string_missing(self):
213
"""When string has no lineno the old context details are returned"""
214
path = "str_missing.py"
215
context = export_pot._ModuleContext(path, 4, ({}, {"line\n": 21}))
216
context1 = context.from_string("line\n")
217
context2A = context.from_string("not there")
218
self.check_context(context2A, path, 4)
219
context2B = context1.from_string("not there")
220
self.check_context(context2B, path, 21)
221
self.assertContainsRe(self.get_log(), "String 'not there' not found")
70
224
class PoEntryTestCase(tests.TestCase):