OLD | NEW |
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # | 2 # |
3 # Protocol Buffers - Google's data interchange format | 3 # Protocol Buffers - Google's data interchange format |
4 # Copyright 2008 Google Inc. All rights reserved. | 4 # Copyright 2008 Google Inc. All rights reserved. |
5 # https://developers.google.com/protocol-buffers/ | 5 # https://developers.google.com/protocol-buffers/ |
6 # | 6 # |
7 # Redistribution and use in source and binary forms, with or without | 7 # Redistribution and use in source and binary forms, with or without |
8 # modification, are permitted provided that the following conditions are | 8 # modification, are permitted provided that the following conditions are |
9 # met: | 9 # met: |
10 # | 10 # |
(...skipping 22 matching lines...) Expand all Loading... |
33 """Test for google.protobuf.text_format.""" | 33 """Test for google.protobuf.text_format.""" |
34 | 34 |
35 __author__ = 'kenton@google.com (Kenton Varda)' | 35 __author__ = 'kenton@google.com (Kenton Varda)' |
36 | 36 |
37 | 37 |
38 import re | 38 import re |
39 import six | 39 import six |
40 import string | 40 import string |
41 | 41 |
42 try: | 42 try: |
43 import unittest2 as unittest #PY26 | 43 import unittest2 as unittest # PY26, pylint: disable=g-import-not-at-top |
44 except ImportError: | 44 except ImportError: |
45 import unittest | 45 import unittest # pylint: disable=g-import-not-at-top |
46 | 46 |
47 from google.protobuf.internal import _parameterized | 47 from google.protobuf.internal import _parameterized |
48 | 48 |
| 49 from google.protobuf import any_test_pb2 |
49 from google.protobuf import map_unittest_pb2 | 50 from google.protobuf import map_unittest_pb2 |
50 from google.protobuf import unittest_mset_pb2 | 51 from google.protobuf import unittest_mset_pb2 |
51 from google.protobuf import unittest_pb2 | 52 from google.protobuf import unittest_pb2 |
52 from google.protobuf import unittest_proto3_arena_pb2 | 53 from google.protobuf import unittest_proto3_arena_pb2 |
53 from google.protobuf.internal import api_implementation | 54 from google.protobuf.internal import api_implementation |
| 55 from google.protobuf.internal import any_test_pb2 as test_extend_any |
54 from google.protobuf.internal import test_util | 56 from google.protobuf.internal import test_util |
55 from google.protobuf.internal import message_set_extensions_pb2 | 57 from google.protobuf.internal import message_set_extensions_pb2 |
| 58 from google.protobuf import descriptor_pool |
56 from google.protobuf import text_format | 59 from google.protobuf import text_format |
57 | 60 |
58 | 61 |
59 # Low-level nuts-n-bolts tests. | 62 # Low-level nuts-n-bolts tests. |
60 class SimpleTextFormatTests(unittest.TestCase): | 63 class SimpleTextFormatTests(unittest.TestCase): |
61 | 64 |
62 # The members of _QUOTES are formatted into a regexp template that | 65 # The members of _QUOTES are formatted into a regexp template that |
63 # expects single characters. Therefore it's an error (in addition to being | 66 # expects single characters. Therefore it's an error (in addition to being |
64 # non-sensical in the first place) to try to specify a "quote mark" that is | 67 # non-sensical in the first place) to try to specify a "quote mark" that is |
65 # more than one character. | 68 # more than one character. |
(...skipping 17 matching lines...) Expand all Loading... |
83 def CompareToGoldenText(self, text, golden_text): | 86 def CompareToGoldenText(self, text, golden_text): |
84 self.assertEqual(text, golden_text) | 87 self.assertEqual(text, golden_text) |
85 | 88 |
86 def RemoveRedundantZeros(self, text): | 89 def RemoveRedundantZeros(self, text): |
87 # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove | 90 # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove |
88 # these zeros in order to match the golden file. | 91 # these zeros in order to match the golden file. |
89 text = text.replace('e+0','e+').replace('e+0','e+') \ | 92 text = text.replace('e+0','e+').replace('e+0','e+') \ |
90 .replace('e-0','e-').replace('e-0','e-') | 93 .replace('e-0','e-').replace('e-0','e-') |
91 # Floating point fields are printed with .0 suffix even if they are | 94 # Floating point fields are printed with .0 suffix even if they are |
92 # actualy integer numbers. | 95 # actualy integer numbers. |
93 text = re.compile('\.0$', re.MULTILINE).sub('', text) | 96 text = re.compile(r'\.0$', re.MULTILINE).sub('', text) |
94 return text | 97 return text |
95 | 98 |
96 | 99 |
97 @_parameterized.Parameters( | 100 @_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2)) |
98 (unittest_pb2), | |
99 (unittest_proto3_arena_pb2)) | |
100 class TextFormatTest(TextFormatBase): | 101 class TextFormatTest(TextFormatBase): |
101 | 102 |
102 def testPrintExotic(self, message_module): | 103 def testPrintExotic(self, message_module): |
103 message = message_module.TestAllTypes() | 104 message = message_module.TestAllTypes() |
104 message.repeated_int64.append(-9223372036854775808) | 105 message.repeated_int64.append(-9223372036854775808) |
105 message.repeated_uint64.append(18446744073709551615) | 106 message.repeated_uint64.append(18446744073709551615) |
106 message.repeated_double.append(123.456) | 107 message.repeated_double.append(123.456) |
107 message.repeated_double.append(1.23e22) | 108 message.repeated_double.append(1.23e22) |
108 message.repeated_double.append(1.23e-18) | 109 message.repeated_double.append(1.23e-18) |
109 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') | 110 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') |
110 message.repeated_string.append(u'\u00fc\ua71f') | 111 message.repeated_string.append(u'\u00fc\ua71f') |
111 self.CompareToGoldenText( | 112 self.CompareToGoldenText( |
112 self.RemoveRedundantZeros(text_format.MessageToString(message)), | 113 self.RemoveRedundantZeros(text_format.MessageToString(message)), |
113 'repeated_int64: -9223372036854775808\n' | 114 'repeated_int64: -9223372036854775808\n' |
114 'repeated_uint64: 18446744073709551615\n' | 115 'repeated_uint64: 18446744073709551615\n' |
115 'repeated_double: 123.456\n' | 116 'repeated_double: 123.456\n' |
116 'repeated_double: 1.23e+22\n' | 117 'repeated_double: 1.23e+22\n' |
117 'repeated_double: 1.23e-18\n' | 118 'repeated_double: 1.23e-18\n' |
118 'repeated_string:' | 119 'repeated_string:' |
119 ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' | 120 ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' |
120 'repeated_string: "\\303\\274\\352\\234\\237"\n') | 121 'repeated_string: "\\303\\274\\352\\234\\237"\n') |
121 | 122 |
122 def testPrintExoticUnicodeSubclass(self, message_module): | 123 def testPrintExoticUnicodeSubclass(self, message_module): |
| 124 |
123 class UnicodeSub(six.text_type): | 125 class UnicodeSub(six.text_type): |
124 pass | 126 pass |
| 127 |
125 message = message_module.TestAllTypes() | 128 message = message_module.TestAllTypes() |
126 message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f')) | 129 message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f')) |
127 self.CompareToGoldenText( | 130 self.CompareToGoldenText( |
128 text_format.MessageToString(message), | 131 text_format.MessageToString(message), |
129 'repeated_string: "\\303\\274\\352\\234\\237"\n') | 132 'repeated_string: "\\303\\274\\352\\234\\237"\n') |
130 | 133 |
131 def testPrintNestedMessageAsOneLine(self, message_module): | 134 def testPrintNestedMessageAsOneLine(self, message_module): |
132 message = message_module.TestAllTypes() | 135 message = message_module.TestAllTypes() |
133 msg = message.repeated_nested_message.add() | 136 msg = message.repeated_nested_message.add() |
134 msg.bb = 42 | 137 msg.bb = 42 |
(...skipping 23 matching lines...) Expand all Loading... |
158 def testPrintExoticAsOneLine(self, message_module): | 161 def testPrintExoticAsOneLine(self, message_module): |
159 message = message_module.TestAllTypes() | 162 message = message_module.TestAllTypes() |
160 message.repeated_int64.append(-9223372036854775808) | 163 message.repeated_int64.append(-9223372036854775808) |
161 message.repeated_uint64.append(18446744073709551615) | 164 message.repeated_uint64.append(18446744073709551615) |
162 message.repeated_double.append(123.456) | 165 message.repeated_double.append(123.456) |
163 message.repeated_double.append(1.23e22) | 166 message.repeated_double.append(1.23e22) |
164 message.repeated_double.append(1.23e-18) | 167 message.repeated_double.append(1.23e-18) |
165 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') | 168 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') |
166 message.repeated_string.append(u'\u00fc\ua71f') | 169 message.repeated_string.append(u'\u00fc\ua71f') |
167 self.CompareToGoldenText( | 170 self.CompareToGoldenText( |
168 self.RemoveRedundantZeros( | 171 self.RemoveRedundantZeros(text_format.MessageToString( |
169 text_format.MessageToString(message, as_one_line=True)), | 172 message, as_one_line=True)), |
170 'repeated_int64: -9223372036854775808' | 173 'repeated_int64: -9223372036854775808' |
171 ' repeated_uint64: 18446744073709551615' | 174 ' repeated_uint64: 18446744073709551615' |
172 ' repeated_double: 123.456' | 175 ' repeated_double: 123.456' |
173 ' repeated_double: 1.23e+22' | 176 ' repeated_double: 1.23e+22' |
174 ' repeated_double: 1.23e-18' | 177 ' repeated_double: 1.23e-18' |
175 ' repeated_string: ' | 178 ' repeated_string: ' |
176 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""' | 179 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""' |
177 ' repeated_string: "\\303\\274\\352\\234\\237"') | 180 ' repeated_string: "\\303\\274\\352\\234\\237"') |
178 | 181 |
179 def testRoundTripExoticAsOneLine(self, message_module): | 182 def testRoundTripExoticAsOneLine(self, message_module): |
180 message = message_module.TestAllTypes() | 183 message = message_module.TestAllTypes() |
181 message.repeated_int64.append(-9223372036854775808) | 184 message.repeated_int64.append(-9223372036854775808) |
182 message.repeated_uint64.append(18446744073709551615) | 185 message.repeated_uint64.append(18446744073709551615) |
183 message.repeated_double.append(123.456) | 186 message.repeated_double.append(123.456) |
184 message.repeated_double.append(1.23e22) | 187 message.repeated_double.append(1.23e22) |
185 message.repeated_double.append(1.23e-18) | 188 message.repeated_double.append(1.23e-18) |
186 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') | 189 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') |
187 message.repeated_string.append(u'\u00fc\ua71f') | 190 message.repeated_string.append(u'\u00fc\ua71f') |
188 | 191 |
189 # Test as_utf8 = False. | 192 # Test as_utf8 = False. |
190 wire_text = text_format.MessageToString( | 193 wire_text = text_format.MessageToString(message, |
191 message, as_one_line=True, as_utf8=False) | 194 as_one_line=True, |
| 195 as_utf8=False) |
192 parsed_message = message_module.TestAllTypes() | 196 parsed_message = message_module.TestAllTypes() |
193 r = text_format.Parse(wire_text, parsed_message) | 197 r = text_format.Parse(wire_text, parsed_message) |
194 self.assertIs(r, parsed_message) | 198 self.assertIs(r, parsed_message) |
195 self.assertEqual(message, parsed_message) | 199 self.assertEqual(message, parsed_message) |
196 | 200 |
197 # Test as_utf8 = True. | 201 # Test as_utf8 = True. |
198 wire_text = text_format.MessageToString( | 202 wire_text = text_format.MessageToString(message, |
199 message, as_one_line=True, as_utf8=True) | 203 as_one_line=True, |
| 204 as_utf8=True) |
200 parsed_message = message_module.TestAllTypes() | 205 parsed_message = message_module.TestAllTypes() |
201 r = text_format.Parse(wire_text, parsed_message) | 206 r = text_format.Parse(wire_text, parsed_message) |
202 self.assertIs(r, parsed_message) | 207 self.assertIs(r, parsed_message) |
203 self.assertEqual(message, parsed_message, | 208 self.assertEqual(message, parsed_message, |
204 '\n%s != %s' % (message, parsed_message)) | 209 '\n%s != %s' % (message, parsed_message)) |
205 | 210 |
206 def testPrintRawUtf8String(self, message_module): | 211 def testPrintRawUtf8String(self, message_module): |
207 message = message_module.TestAllTypes() | 212 message = message_module.TestAllTypes() |
208 message.repeated_string.append(u'\u00fc\ua71f') | 213 message.repeated_string.append(u'\u00fc\ua71f') |
209 text = text_format.MessageToString(message, as_utf8=True) | 214 text = text_format.MessageToString(message, as_utf8=True) |
210 self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n') | 215 self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n') |
211 parsed_message = message_module.TestAllTypes() | 216 parsed_message = message_module.TestAllTypes() |
212 text_format.Parse(text, parsed_message) | 217 text_format.Parse(text, parsed_message) |
213 self.assertEqual(message, parsed_message, | 218 self.assertEqual(message, parsed_message, |
214 '\n%s != %s' % (message, parsed_message)) | 219 '\n%s != %s' % (message, parsed_message)) |
215 | 220 |
216 def testPrintFloatFormat(self, message_module): | 221 def testPrintFloatFormat(self, message_module): |
217 # Check that float_format argument is passed to sub-message formatting. | 222 # Check that float_format argument is passed to sub-message formatting. |
218 message = message_module.NestedTestAllTypes() | 223 message = message_module.NestedTestAllTypes() |
219 # We use 1.25 as it is a round number in binary. The proto 32-bit float | 224 # We use 1.25 as it is a round number in binary. The proto 32-bit float |
220 # will not gain additional imprecise digits as a 64-bit Python float and | 225 # will not gain additional imprecise digits as a 64-bit Python float and |
221 # show up in its str. 32-bit 1.2 is noisy when extended to 64-bit: | 226 # show up in its str. 32-bit 1.2 is noisy when extended to 64-bit: |
222 # >>> struct.unpack('f', struct.pack('f', 1.2))[0] | 227 # >>> struct.unpack('f', struct.pack('f', 1.2))[0] |
223 # 1.2000000476837158 | 228 # 1.2000000476837158 |
224 # >>> struct.unpack('f', struct.pack('f', 1.25))[0] | 229 # >>> struct.unpack('f', struct.pack('f', 1.25))[0] |
225 # 1.25 | 230 # 1.25 |
226 message.payload.optional_float = 1.25 | 231 message.payload.optional_float = 1.25 |
227 # Check rounding at 15 significant digits | 232 # Check rounding at 15 significant digits |
228 message.payload.optional_double = -.000003456789012345678 | 233 message.payload.optional_double = -.000003456789012345678 |
229 # Check no decimal point. | 234 # Check no decimal point. |
230 message.payload.repeated_float.append(-5642) | 235 message.payload.repeated_float.append(-5642) |
231 # Check no trailing zeros. | 236 # Check no trailing zeros. |
232 message.payload.repeated_double.append(.000078900) | 237 message.payload.repeated_double.append(.000078900) |
233 formatted_fields = ['optional_float: 1.25', | 238 formatted_fields = ['optional_float: 1.25', |
234 'optional_double: -3.45678901234568e-6', | 239 'optional_double: -3.45678901234568e-6', |
235 'repeated_float: -5642', | 240 'repeated_float: -5642', 'repeated_double: 7.89e-5'] |
236 'repeated_double: 7.89e-5'] | |
237 text_message = text_format.MessageToString(message, float_format='.15g') | 241 text_message = text_format.MessageToString(message, float_format='.15g') |
238 self.CompareToGoldenText( | 242 self.CompareToGoldenText( |
239 self.RemoveRedundantZeros(text_message), | 243 self.RemoveRedundantZeros(text_message), |
240 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format(*formatted_fields)
) | 244 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format( |
| 245 *formatted_fields)) |
241 # as_one_line=True is a separate code branch where float_format is passed. | 246 # as_one_line=True is a separate code branch where float_format is passed. |
242 text_message = text_format.MessageToString(message, as_one_line=True, | 247 text_message = text_format.MessageToString(message, |
| 248 as_one_line=True, |
243 float_format='.15g') | 249 float_format='.15g') |
244 self.CompareToGoldenText( | 250 self.CompareToGoldenText( |
245 self.RemoveRedundantZeros(text_message), | 251 self.RemoveRedundantZeros(text_message), |
246 'payload {{ {0} {1} {2} {3} }}'.format(*formatted_fields)) | 252 'payload {{ {0} {1} {2} {3} }}'.format(*formatted_fields)) |
247 | 253 |
248 def testMessageToString(self, message_module): | 254 def testMessageToString(self, message_module): |
249 message = message_module.ForeignMessage() | 255 message = message_module.ForeignMessage() |
250 message.c = 123 | 256 message.c = 123 |
251 self.assertEqual('c: 123\n', str(message)) | 257 self.assertEqual('c: 123\n', str(message)) |
252 | 258 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 'repeated_string: "\\303\\274\\352\\234\\237"\n' | 310 'repeated_string: "\\303\\274\\352\\234\\237"\n' |
305 'repeated_string: "\\xc3\\xbc"\n' | 311 'repeated_string: "\\xc3\\xbc"\n' |
306 'repeated_string: "\xc3\xbc"\n') | 312 'repeated_string: "\xc3\xbc"\n') |
307 text_format.Parse(text, message) | 313 text_format.Parse(text, message) |
308 | 314 |
309 self.assertEqual(-9223372036854775808, message.repeated_int64[0]) | 315 self.assertEqual(-9223372036854775808, message.repeated_int64[0]) |
310 self.assertEqual(18446744073709551615, message.repeated_uint64[0]) | 316 self.assertEqual(18446744073709551615, message.repeated_uint64[0]) |
311 self.assertEqual(123.456, message.repeated_double[0]) | 317 self.assertEqual(123.456, message.repeated_double[0]) |
312 self.assertEqual(1.23e22, message.repeated_double[1]) | 318 self.assertEqual(1.23e22, message.repeated_double[1]) |
313 self.assertEqual(1.23e-18, message.repeated_double[2]) | 319 self.assertEqual(1.23e-18, message.repeated_double[2]) |
314 self.assertEqual( | 320 self.assertEqual('\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0]) |
315 '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0]) | |
316 self.assertEqual('foocorgegrault', message.repeated_string[1]) | 321 self.assertEqual('foocorgegrault', message.repeated_string[1]) |
317 self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2]) | 322 self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2]) |
318 self.assertEqual(u'\u00fc', message.repeated_string[3]) | 323 self.assertEqual(u'\u00fc', message.repeated_string[3]) |
319 | 324 |
320 def testParseTrailingCommas(self, message_module): | 325 def testParseTrailingCommas(self, message_module): |
321 message = message_module.TestAllTypes() | 326 message = message_module.TestAllTypes() |
322 text = ('repeated_int64: 100;\n' | 327 text = ('repeated_int64: 100;\n' |
323 'repeated_int64: 200;\n' | 328 'repeated_int64: 200;\n' |
324 'repeated_int64: 300,\n' | 329 'repeated_int64: 300,\n' |
325 'repeated_string: "one",\n' | 330 'repeated_string: "one",\n' |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 self.assertEqual(message_module.TestAllTypes(), message) | 369 self.assertEqual(message_module.TestAllTypes(), message) |
365 | 370 |
366 def testParseInvalidUtf8(self, message_module): | 371 def testParseInvalidUtf8(self, message_module): |
367 message = message_module.TestAllTypes() | 372 message = message_module.TestAllTypes() |
368 text = 'repeated_string: "\\xc3\\xc3"' | 373 text = 'repeated_string: "\\xc3\\xc3"' |
369 self.assertRaises(text_format.ParseError, text_format.Parse, text, message) | 374 self.assertRaises(text_format.ParseError, text_format.Parse, text, message) |
370 | 375 |
371 def testParseSingleWord(self, message_module): | 376 def testParseSingleWord(self, message_module): |
372 message = message_module.TestAllTypes() | 377 message = message_module.TestAllTypes() |
373 text = 'foo' | 378 text = 'foo' |
374 six.assertRaisesRegex(self, | 379 six.assertRaisesRegex(self, text_format.ParseError, ( |
375 text_format.ParseError, | 380 r'1:1 : Message type "\w+.TestAllTypes" has no field named ' |
376 (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' | 381 r'"foo".'), text_format.Parse, text, message) |
377 r'"foo".'), | |
378 text_format.Parse, text, message) | |
379 | 382 |
380 def testParseUnknownField(self, message_module): | 383 def testParseUnknownField(self, message_module): |
381 message = message_module.TestAllTypes() | 384 message = message_module.TestAllTypes() |
382 text = 'unknown_field: 8\n' | 385 text = 'unknown_field: 8\n' |
383 six.assertRaisesRegex(self, | 386 six.assertRaisesRegex(self, text_format.ParseError, ( |
384 text_format.ParseError, | 387 r'1:1 : Message type "\w+.TestAllTypes" has no field named ' |
385 (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' | 388 r'"unknown_field".'), text_format.Parse, text, message) |
386 r'"unknown_field".'), | |
387 text_format.Parse, text, message) | |
388 | 389 |
389 def testParseBadEnumValue(self, message_module): | 390 def testParseBadEnumValue(self, message_module): |
390 message = message_module.TestAllTypes() | 391 message = message_module.TestAllTypes() |
391 text = 'optional_nested_enum: BARR' | 392 text = 'optional_nested_enum: BARR' |
392 six.assertRaisesRegex(self, | 393 six.assertRaisesRegex(self, text_format.ParseError, |
393 text_format.ParseError, | 394 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" ' |
394 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" ' | 395 r'has no value named BARR.'), text_format.Parse, |
395 r'has no value named BARR.'), | 396 text, message) |
396 text_format.Parse, text, message) | |
397 | 397 |
398 message = message_module.TestAllTypes() | 398 message = message_module.TestAllTypes() |
399 text = 'optional_nested_enum: 100' | 399 text = 'optional_nested_enum: 100' |
400 six.assertRaisesRegex(self, | 400 six.assertRaisesRegex(self, text_format.ParseError, |
401 text_format.ParseError, | 401 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" ' |
402 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" ' | 402 r'has no value with number 100.'), text_format.Parse, |
403 r'has no value with number 100.'), | 403 text, message) |
404 text_format.Parse, text, message) | |
405 | 404 |
406 def testParseBadIntValue(self, message_module): | 405 def testParseBadIntValue(self, message_module): |
407 message = message_module.TestAllTypes() | 406 message = message_module.TestAllTypes() |
408 text = 'optional_int32: bork' | 407 text = 'optional_int32: bork' |
409 six.assertRaisesRegex(self, | 408 six.assertRaisesRegex(self, text_format.ParseError, |
410 text_format.ParseError, | 409 ('1:17 : Couldn\'t parse integer: bork'), |
411 ('1:17 : Couldn\'t parse integer: bork'), | 410 text_format.Parse, text, message) |
412 text_format.Parse, text, message) | |
413 | 411 |
414 def testParseStringFieldUnescape(self, message_module): | 412 def testParseStringFieldUnescape(self, message_module): |
415 message = message_module.TestAllTypes() | 413 message = message_module.TestAllTypes() |
416 text = r'''repeated_string: "\xf\x62" | 414 text = r'''repeated_string: "\xf\x62" |
417 repeated_string: "\\xf\\x62" | 415 repeated_string: "\\xf\\x62" |
418 repeated_string: "\\\xf\\\x62" | 416 repeated_string: "\\\xf\\\x62" |
419 repeated_string: "\\\\xf\\\\x62" | 417 repeated_string: "\\\\xf\\\\x62" |
420 repeated_string: "\\\\\xf\\\\\x62" | 418 repeated_string: "\\\\\xf\\\\\x62" |
421 repeated_string: "\x5cx20"''' | 419 repeated_string: "\x5cx20"''' |
| 420 |
422 text_format.Parse(text, message) | 421 text_format.Parse(text, message) |
423 | 422 |
424 SLASH = '\\' | 423 SLASH = '\\' |
425 self.assertEqual('\x0fb', message.repeated_string[0]) | 424 self.assertEqual('\x0fb', message.repeated_string[0]) |
426 self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1]) | 425 self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1]) |
427 self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2]) | 426 self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2]) |
428 self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62', | 427 self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62', |
429 message.repeated_string[3]) | 428 message.repeated_string[3]) |
430 self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b', | 429 self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b', |
431 message.repeated_string[4]) | 430 message.repeated_string[4]) |
432 self.assertEqual(SLASH + 'x20', message.repeated_string[5]) | 431 self.assertEqual(SLASH + 'x20', message.repeated_string[5]) |
433 | 432 |
434 def testMergeDuplicateScalars(self, message_module): | 433 def testMergeDuplicateScalars(self, message_module): |
435 message = message_module.TestAllTypes() | 434 message = message_module.TestAllTypes() |
436 text = ('optional_int32: 42 ' | 435 text = ('optional_int32: 42 ' 'optional_int32: 67') |
437 'optional_int32: 67') | |
438 r = text_format.Merge(text, message) | 436 r = text_format.Merge(text, message) |
439 self.assertIs(r, message) | 437 self.assertIs(r, message) |
440 self.assertEqual(67, message.optional_int32) | 438 self.assertEqual(67, message.optional_int32) |
441 | 439 |
442 def testMergeDuplicateNestedMessageScalars(self, message_module): | 440 def testMergeDuplicateNestedMessageScalars(self, message_module): |
443 message = message_module.TestAllTypes() | 441 message = message_module.TestAllTypes() |
444 text = ('optional_nested_message { bb: 1 } ' | 442 text = ('optional_nested_message { bb: 1 } ' |
445 'optional_nested_message { bb: 2 }') | 443 'optional_nested_message { bb: 2 }') |
446 r = text_format.Merge(text, message) | 444 r = text_format.Merge(text, message) |
447 self.assertTrue(r is message) | 445 self.assertTrue(r is message) |
448 self.assertEqual(2, message.optional_nested_message.bb) | 446 self.assertEqual(2, message.optional_nested_message.bb) |
449 | 447 |
450 def testParseOneof(self, message_module): | 448 def testParseOneof(self, message_module): |
451 m = message_module.TestAllTypes() | 449 m = message_module.TestAllTypes() |
452 m.oneof_uint32 = 11 | 450 m.oneof_uint32 = 11 |
453 m2 = message_module.TestAllTypes() | 451 m2 = message_module.TestAllTypes() |
454 text_format.Parse(text_format.MessageToString(m), m2) | 452 text_format.Parse(text_format.MessageToString(m), m2) |
455 self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field')) | 453 self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field')) |
456 | 454 |
457 def testParseMultipleOneof(self, message_module): | 455 def testParseMultipleOneof(self, message_module): |
458 m_string = '\n'.join([ | 456 m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"']) |
459 'oneof_uint32: 11', | |
460 'oneof_string: "foo"']) | |
461 m2 = message_module.TestAllTypes() | 457 m2 = message_module.TestAllTypes() |
462 if message_module is unittest_pb2: | 458 if message_module is unittest_pb2: |
463 with self.assertRaisesRegexp( | 459 with self.assertRaisesRegexp(text_format.ParseError, |
464 text_format.ParseError, ' is specified along with field '): | 460 ' is specified along with field '): |
465 text_format.Parse(m_string, m2) | 461 text_format.Parse(m_string, m2) |
466 else: | 462 else: |
467 text_format.Parse(m_string, m2) | 463 text_format.Parse(m_string, m2) |
468 self.assertEqual('oneof_string', m2.WhichOneof('oneof_field')) | 464 self.assertEqual('oneof_string', m2.WhichOneof('oneof_field')) |
469 | 465 |
470 | 466 |
471 # These are tests that aren't fundamentally specific to proto2, but are at | 467 # These are tests that aren't fundamentally specific to proto2, but are at |
472 # the moment because of differences between the proto2 and proto3 test schemas. | 468 # the moment because of differences between the proto2 and proto3 test schemas. |
473 # Ideally the schemas would be made more similar so these tests could pass. | 469 # Ideally the schemas would be made more similar so these tests could pass. |
474 class OnlyWorksWithProto2RightNowTests(TextFormatBase): | 470 class OnlyWorksWithProto2RightNowTests(TextFormatBase): |
475 | 471 |
476 def testPrintAllFieldsPointy(self): | 472 def testPrintAllFieldsPointy(self): |
477 message = unittest_pb2.TestAllTypes() | 473 message = unittest_pb2.TestAllTypes() |
478 test_util.SetAllFields(message) | 474 test_util.SetAllFields(message) |
479 self.CompareToGoldenFile( | 475 self.CompareToGoldenFile( |
480 self.RemoveRedundantZeros( | 476 self.RemoveRedundantZeros(text_format.MessageToString( |
481 text_format.MessageToString(message, pointy_brackets=True)), | 477 message, pointy_brackets=True)), |
482 'text_format_unittest_data_pointy_oneof.txt') | 478 'text_format_unittest_data_pointy_oneof.txt') |
483 | 479 |
484 def testParseGolden(self): | 480 def testParseGolden(self): |
485 golden_text = '\n'.join(self.ReadGolden( | 481 golden_text = '\n'.join(self.ReadGolden( |
486 'text_format_unittest_data_oneof_implemented.txt')) | 482 'text_format_unittest_data_oneof_implemented.txt')) |
487 parsed_message = unittest_pb2.TestAllTypes() | 483 parsed_message = unittest_pb2.TestAllTypes() |
488 r = text_format.Parse(golden_text, parsed_message) | 484 r = text_format.Parse(golden_text, parsed_message) |
489 self.assertIs(r, parsed_message) | 485 self.assertIs(r, parsed_message) |
490 | 486 |
491 message = unittest_pb2.TestAllTypes() | 487 message = unittest_pb2.TestAllTypes() |
492 test_util.SetAllFields(message) | 488 test_util.SetAllFields(message) |
493 self.assertEqual(message, parsed_message) | 489 self.assertEqual(message, parsed_message) |
494 | 490 |
495 def testPrintAllFields(self): | 491 def testPrintAllFields(self): |
496 message = unittest_pb2.TestAllTypes() | 492 message = unittest_pb2.TestAllTypes() |
497 test_util.SetAllFields(message) | 493 test_util.SetAllFields(message) |
498 self.CompareToGoldenFile( | 494 self.CompareToGoldenFile( |
499 self.RemoveRedundantZeros(text_format.MessageToString(message)), | 495 self.RemoveRedundantZeros(text_format.MessageToString(message)), |
500 'text_format_unittest_data_oneof_implemented.txt') | 496 'text_format_unittest_data_oneof_implemented.txt') |
501 | 497 |
502 def testPrintAllFieldsPointy(self): | |
503 message = unittest_pb2.TestAllTypes() | |
504 test_util.SetAllFields(message) | |
505 self.CompareToGoldenFile( | |
506 self.RemoveRedundantZeros( | |
507 text_format.MessageToString(message, pointy_brackets=True)), | |
508 'text_format_unittest_data_pointy_oneof.txt') | |
509 | |
510 def testPrintInIndexOrder(self): | 498 def testPrintInIndexOrder(self): |
511 message = unittest_pb2.TestFieldOrderings() | 499 message = unittest_pb2.TestFieldOrderings() |
512 message.my_string = '115' | 500 message.my_string = '115' |
513 message.my_int = 101 | 501 message.my_int = 101 |
514 message.my_float = 111 | 502 message.my_float = 111 |
515 message.optional_nested_message.oo = 0 | 503 message.optional_nested_message.oo = 0 |
516 message.optional_nested_message.bb = 1 | 504 message.optional_nested_message.bb = 1 |
517 self.CompareToGoldenText( | 505 self.CompareToGoldenText( |
518 self.RemoveRedundantZeros(text_format.MessageToString( | 506 self.RemoveRedundantZeros(text_format.MessageToString( |
519 message, use_index_order=True)), | 507 message, use_index_order=True)), |
520 'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n' | 508 'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n' |
521 'optional_nested_message {\n oo: 0\n bb: 1\n}\n') | 509 'optional_nested_message {\n oo: 0\n bb: 1\n}\n') |
522 self.CompareToGoldenText( | 510 self.CompareToGoldenText( |
523 self.RemoveRedundantZeros(text_format.MessageToString( | 511 self.RemoveRedundantZeros(text_format.MessageToString(message)), |
524 message)), | |
525 'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n' | 512 'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n' |
526 'optional_nested_message {\n bb: 1\n oo: 0\n}\n') | 513 'optional_nested_message {\n bb: 1\n oo: 0\n}\n') |
527 | 514 |
528 def testMergeLinesGolden(self): | 515 def testMergeLinesGolden(self): |
529 opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt') | 516 opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt') |
530 parsed_message = unittest_pb2.TestAllTypes() | 517 parsed_message = unittest_pb2.TestAllTypes() |
531 r = text_format.MergeLines(opened, parsed_message) | 518 r = text_format.MergeLines(opened, parsed_message) |
532 self.assertIs(r, parsed_message) | 519 self.assertIs(r, parsed_message) |
533 | 520 |
534 message = unittest_pb2.TestAllTypes() | 521 message = unittest_pb2.TestAllTypes() |
(...skipping 10 matching lines...) Expand all Loading... |
545 test_util.SetAllFields(message) | 532 test_util.SetAllFields(message) |
546 self.assertEqual(message, parsed_message) | 533 self.assertEqual(message, parsed_message) |
547 | 534 |
548 def testPrintMap(self): | 535 def testPrintMap(self): |
549 message = map_unittest_pb2.TestMap() | 536 message = map_unittest_pb2.TestMap() |
550 | 537 |
551 message.map_int32_int32[-123] = -456 | 538 message.map_int32_int32[-123] = -456 |
552 message.map_int64_int64[-2**33] = -2**34 | 539 message.map_int64_int64[-2**33] = -2**34 |
553 message.map_uint32_uint32[123] = 456 | 540 message.map_uint32_uint32[123] = 456 |
554 message.map_uint64_uint64[2**33] = 2**34 | 541 message.map_uint64_uint64[2**33] = 2**34 |
555 message.map_string_string["abc"] = "123" | 542 message.map_string_string['abc'] = '123' |
556 message.map_int32_foreign_message[111].c = 5 | 543 message.map_int32_foreign_message[111].c = 5 |
557 | 544 |
558 # Maps are serialized to text format using their underlying repeated | 545 # Maps are serialized to text format using their underlying repeated |
559 # representation. | 546 # representation. |
560 self.CompareToGoldenText( | 547 self.CompareToGoldenText( |
561 text_format.MessageToString(message), | 548 text_format.MessageToString(message), 'map_int32_int32 {\n' |
562 'map_int32_int32 {\n' | |
563 ' key: -123\n' | 549 ' key: -123\n' |
564 ' value: -456\n' | 550 ' value: -456\n' |
565 '}\n' | 551 '}\n' |
566 'map_int64_int64 {\n' | 552 'map_int64_int64 {\n' |
567 ' key: -8589934592\n' | 553 ' key: -8589934592\n' |
568 ' value: -17179869184\n' | 554 ' value: -17179869184\n' |
569 '}\n' | 555 '}\n' |
570 'map_uint32_uint32 {\n' | 556 'map_uint32_uint32 {\n' |
571 ' key: 123\n' | 557 ' key: 123\n' |
572 ' value: 456\n' | 558 ' value: 456\n' |
(...skipping 12 matching lines...) Expand all Loading... |
585 ' c: 5\n' | 571 ' c: 5\n' |
586 ' }\n' | 572 ' }\n' |
587 '}\n') | 573 '}\n') |
588 | 574 |
589 def testMapOrderEnforcement(self): | 575 def testMapOrderEnforcement(self): |
590 message = map_unittest_pb2.TestMap() | 576 message = map_unittest_pb2.TestMap() |
591 for letter in string.ascii_uppercase[13:26]: | 577 for letter in string.ascii_uppercase[13:26]: |
592 message.map_string_string[letter] = 'dummy' | 578 message.map_string_string[letter] = 'dummy' |
593 for letter in reversed(string.ascii_uppercase[0:13]): | 579 for letter in reversed(string.ascii_uppercase[0:13]): |
594 message.map_string_string[letter] = 'dummy' | 580 message.map_string_string[letter] = 'dummy' |
595 golden = ''.join(( | 581 golden = ''.join(('map_string_string {\n key: "%c"\n value: "dummy"\n}\n' |
596 'map_string_string {\n key: "%c"\n value: "dummy"\n}\n' % (letter,) | 582 % (letter,) for letter in string.ascii_uppercase)) |
597 for letter in string.ascii_uppercase)) | |
598 self.CompareToGoldenText(text_format.MessageToString(message), golden) | 583 self.CompareToGoldenText(text_format.MessageToString(message), golden) |
599 | 584 |
600 def testMapOrderSemantics(self): | 585 # TODO(teboring): In c/137553523, not serializing default value for map entry |
601 golden_lines = self.ReadGolden('map_test_data.txt') | 586 # message has been fixed. This test needs to be disabled in order to submit |
602 # The C++ implementation emits defaulted-value fields, while the Python | 587 # that cl. Add this back when c/137553523 has been submitted. |
603 # implementation does not. Adjusting for this is awkward, but it is | 588 # def testMapOrderSemantics(self): |
604 # valuable to test against a common golden file. | 589 # golden_lines = self.ReadGolden('map_test_data.txt') |
605 line_blacklist = (' key: 0\n', | |
606 ' value: 0\n', | |
607 ' key: false\n', | |
608 ' value: false\n') | |
609 golden_lines = [line for line in golden_lines if line not in line_blacklist] | |
610 | 590 |
611 message = map_unittest_pb2.TestMap() | 591 # message = map_unittest_pb2.TestMap() |
612 text_format.ParseLines(golden_lines, message) | 592 # text_format.ParseLines(golden_lines, message) |
613 candidate = text_format.MessageToString(message) | 593 # candidate = text_format.MessageToString(message) |
614 # The Python implementation emits "1.0" for the double value that the C++ | 594 # # The Python implementation emits "1.0" for the double value that the C++ |
615 # implementation emits as "1". | 595 # # implementation emits as "1". |
616 candidate = candidate.replace('1.0', '1', 2) | 596 # candidate = candidate.replace('1.0', '1', 2) |
617 self.assertMultiLineEqual(candidate, ''.join(golden_lines)) | 597 # candidate = candidate.replace('0.0', '0', 2) |
| 598 # self.assertMultiLineEqual(candidate, ''.join(golden_lines)) |
618 | 599 |
619 | 600 |
620 # Tests of proto2-only features (MessageSet, extensions, etc.). | 601 # Tests of proto2-only features (MessageSet, extensions, etc.). |
621 class Proto2Tests(TextFormatBase): | 602 class Proto2Tests(TextFormatBase): |
622 | 603 |
623 def testPrintMessageSet(self): | 604 def testPrintMessageSet(self): |
624 message = unittest_mset_pb2.TestMessageSetContainer() | 605 message = unittest_mset_pb2.TestMessageSetContainer() |
625 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 606 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
626 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 607 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
627 message.message_set.Extensions[ext1].i = 23 | 608 message.message_set.Extensions[ext1].i = 23 |
628 message.message_set.Extensions[ext2].str = 'foo' | 609 message.message_set.Extensions[ext2].str = 'foo' |
629 self.CompareToGoldenText( | 610 self.CompareToGoldenText( |
630 text_format.MessageToString(message), | 611 text_format.MessageToString(message), 'message_set {\n' |
631 'message_set {\n' | |
632 ' [protobuf_unittest.TestMessageSetExtension1] {\n' | 612 ' [protobuf_unittest.TestMessageSetExtension1] {\n' |
633 ' i: 23\n' | 613 ' i: 23\n' |
634 ' }\n' | 614 ' }\n' |
635 ' [protobuf_unittest.TestMessageSetExtension2] {\n' | 615 ' [protobuf_unittest.TestMessageSetExtension2] {\n' |
636 ' str: \"foo\"\n' | 616 ' str: \"foo\"\n' |
637 ' }\n' | 617 ' }\n' |
638 '}\n') | 618 '}\n') |
639 | 619 |
640 message = message_set_extensions_pb2.TestMessageSet() | 620 message = message_set_extensions_pb2.TestMessageSet() |
641 ext = message_set_extensions_pb2.message_set_extension3 | 621 ext = message_set_extensions_pb2.message_set_extension3 |
642 message.Extensions[ext].text = 'bar' | 622 message.Extensions[ext].text = 'bar' |
643 self.CompareToGoldenText( | 623 self.CompareToGoldenText( |
644 text_format.MessageToString(message), | 624 text_format.MessageToString(message), |
645 '[google.protobuf.internal.TestMessageSetExtension3] {\n' | 625 '[google.protobuf.internal.TestMessageSetExtension3] {\n' |
646 ' text: \"bar\"\n' | 626 ' text: \"bar\"\n' |
647 '}\n') | 627 '}\n') |
648 | 628 |
649 def testPrintMessageSetByFieldNumber(self): | 629 def testPrintMessageSetByFieldNumber(self): |
650 out = text_format.TextWriter(False) | 630 out = text_format.TextWriter(False) |
651 message = unittest_mset_pb2.TestMessageSetContainer() | 631 message = unittest_mset_pb2.TestMessageSetContainer() |
652 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 632 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
653 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 633 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
654 message.message_set.Extensions[ext1].i = 23 | 634 message.message_set.Extensions[ext1].i = 23 |
655 message.message_set.Extensions[ext2].str = 'foo' | 635 message.message_set.Extensions[ext2].str = 'foo' |
656 text_format.PrintMessage(message, out, use_field_number=True) | 636 text_format.PrintMessage(message, out, use_field_number=True) |
657 self.CompareToGoldenText( | 637 self.CompareToGoldenText(out.getvalue(), '1 {\n' |
658 out.getvalue(), | 638 ' 1545008 {\n' |
659 '1 {\n' | 639 ' 15: 23\n' |
660 ' 1545008 {\n' | 640 ' }\n' |
661 ' 15: 23\n' | 641 ' 1547769 {\n' |
662 ' }\n' | 642 ' 25: \"foo\"\n' |
663 ' 1547769 {\n' | 643 ' }\n' |
664 ' 25: \"foo\"\n' | 644 '}\n') |
665 ' }\n' | |
666 '}\n') | |
667 out.close() | 645 out.close() |
668 | 646 |
669 def testPrintMessageSetAsOneLine(self): | 647 def testPrintMessageSetAsOneLine(self): |
670 message = unittest_mset_pb2.TestMessageSetContainer() | 648 message = unittest_mset_pb2.TestMessageSetContainer() |
671 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 649 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
672 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 650 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
673 message.message_set.Extensions[ext1].i = 23 | 651 message.message_set.Extensions[ext1].i = 23 |
674 message.message_set.Extensions[ext2].str = 'foo' | 652 message.message_set.Extensions[ext2].str = 'foo' |
675 self.CompareToGoldenText( | 653 self.CompareToGoldenText( |
676 text_format.MessageToString(message, as_one_line=True), | 654 text_format.MessageToString(message, as_one_line=True), |
677 'message_set {' | 655 'message_set {' |
678 ' [protobuf_unittest.TestMessageSetExtension1] {' | 656 ' [protobuf_unittest.TestMessageSetExtension1] {' |
679 ' i: 23' | 657 ' i: 23' |
680 ' }' | 658 ' }' |
681 ' [protobuf_unittest.TestMessageSetExtension2] {' | 659 ' [protobuf_unittest.TestMessageSetExtension2] {' |
682 ' str: \"foo\"' | 660 ' str: \"foo\"' |
683 ' }' | 661 ' }' |
684 ' }') | 662 ' }') |
685 | 663 |
686 def testParseMessageSet(self): | 664 def testParseMessageSet(self): |
687 message = unittest_pb2.TestAllTypes() | 665 message = unittest_pb2.TestAllTypes() |
688 text = ('repeated_uint64: 1\n' | 666 text = ('repeated_uint64: 1\n' 'repeated_uint64: 2\n') |
689 'repeated_uint64: 2\n') | |
690 text_format.Parse(text, message) | 667 text_format.Parse(text, message) |
691 self.assertEqual(1, message.repeated_uint64[0]) | 668 self.assertEqual(1, message.repeated_uint64[0]) |
692 self.assertEqual(2, message.repeated_uint64[1]) | 669 self.assertEqual(2, message.repeated_uint64[1]) |
693 | 670 |
694 message = unittest_mset_pb2.TestMessageSetContainer() | 671 message = unittest_mset_pb2.TestMessageSetContainer() |
695 text = ('message_set {\n' | 672 text = ('message_set {\n' |
696 ' [protobuf_unittest.TestMessageSetExtension1] {\n' | 673 ' [protobuf_unittest.TestMessageSetExtension1] {\n' |
697 ' i: 23\n' | 674 ' i: 23\n' |
698 ' }\n' | 675 ' }\n' |
699 ' [protobuf_unittest.TestMessageSetExtension2] {\n' | 676 ' [protobuf_unittest.TestMessageSetExtension2] {\n' |
700 ' str: \"foo\"\n' | 677 ' str: \"foo\"\n' |
701 ' }\n' | 678 ' }\n' |
702 '}\n') | 679 '}\n') |
703 text_format.Parse(text, message) | 680 text_format.Parse(text, message) |
704 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 681 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
705 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 682 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
706 self.assertEqual(23, message.message_set.Extensions[ext1].i) | 683 self.assertEqual(23, message.message_set.Extensions[ext1].i) |
707 self.assertEqual('foo', message.message_set.Extensions[ext2].str) | 684 self.assertEqual('foo', message.message_set.Extensions[ext2].str) |
708 | 685 |
| 686 def testExtensionInsideAnyMessage(self): |
| 687 message = test_extend_any.TestAny() |
| 688 text = ('value {\n' |
| 689 ' [type.googleapis.com/google.protobuf.internal.TestAny] {\n' |
| 690 ' [google.protobuf.internal.TestAnyExtension1.extension1] {\n' |
| 691 ' i: 10\n' |
| 692 ' }\n' |
| 693 ' }\n' |
| 694 '}\n') |
| 695 text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) |
| 696 self.CompareToGoldenText( |
| 697 text_format.MessageToString( |
| 698 message, descriptor_pool=descriptor_pool.Default()), |
| 699 text) |
| 700 |
709 def testParseMessageByFieldNumber(self): | 701 def testParseMessageByFieldNumber(self): |
710 message = unittest_pb2.TestAllTypes() | 702 message = unittest_pb2.TestAllTypes() |
711 text = ('34: 1\n' | 703 text = ('34: 1\n' 'repeated_uint64: 2\n') |
712 'repeated_uint64: 2\n') | |
713 text_format.Parse(text, message, allow_field_number=True) | 704 text_format.Parse(text, message, allow_field_number=True) |
714 self.assertEqual(1, message.repeated_uint64[0]) | 705 self.assertEqual(1, message.repeated_uint64[0]) |
715 self.assertEqual(2, message.repeated_uint64[1]) | 706 self.assertEqual(2, message.repeated_uint64[1]) |
716 | 707 |
717 message = unittest_mset_pb2.TestMessageSetContainer() | 708 message = unittest_mset_pb2.TestMessageSetContainer() |
718 text = ('1 {\n' | 709 text = ('1 {\n' |
719 ' 1545008 {\n' | 710 ' 1545008 {\n' |
720 ' 15: 23\n' | 711 ' 15: 23\n' |
721 ' }\n' | 712 ' }\n' |
722 ' 1547769 {\n' | 713 ' 1547769 {\n' |
723 ' 25: \"foo\"\n' | 714 ' 25: \"foo\"\n' |
724 ' }\n' | 715 ' }\n' |
725 '}\n') | 716 '}\n') |
726 text_format.Parse(text, message, allow_field_number=True) | 717 text_format.Parse(text, message, allow_field_number=True) |
727 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 718 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
728 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 719 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
729 self.assertEqual(23, message.message_set.Extensions[ext1].i) | 720 self.assertEqual(23, message.message_set.Extensions[ext1].i) |
730 self.assertEqual('foo', message.message_set.Extensions[ext2].str) | 721 self.assertEqual('foo', message.message_set.Extensions[ext2].str) |
731 | 722 |
732 # Can't parse field number without set allow_field_number=True. | 723 # Can't parse field number without set allow_field_number=True. |
733 message = unittest_pb2.TestAllTypes() | 724 message = unittest_pb2.TestAllTypes() |
734 text = '34:1\n' | 725 text = '34:1\n' |
735 six.assertRaisesRegex( | 726 six.assertRaisesRegex(self, text_format.ParseError, ( |
736 self, | 727 r'1:1 : Message type "\w+.TestAllTypes" has no field named ' |
737 text_format.ParseError, | 728 r'"34".'), text_format.Parse, text, message) |
738 (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' | |
739 r'"34".'), | |
740 text_format.Parse, text, message) | |
741 | 729 |
742 # Can't parse if field number is not found. | 730 # Can't parse if field number is not found. |
743 text = '1234:1\n' | 731 text = '1234:1\n' |
744 six.assertRaisesRegex( | 732 six.assertRaisesRegex( |
745 self, | 733 self, |
746 text_format.ParseError, | 734 text_format.ParseError, |
747 (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' | 735 (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' |
748 r'"1234".'), | 736 r'"1234".'), |
749 text_format.Parse, text, message, allow_field_number=True) | 737 text_format.Parse, |
| 738 text, |
| 739 message, |
| 740 allow_field_number=True) |
750 | 741 |
751 def testPrintAllExtensions(self): | 742 def testPrintAllExtensions(self): |
752 message = unittest_pb2.TestAllExtensions() | 743 message = unittest_pb2.TestAllExtensions() |
753 test_util.SetAllExtensions(message) | 744 test_util.SetAllExtensions(message) |
754 self.CompareToGoldenFile( | 745 self.CompareToGoldenFile( |
755 self.RemoveRedundantZeros(text_format.MessageToString(message)), | 746 self.RemoveRedundantZeros(text_format.MessageToString(message)), |
756 'text_format_unittest_extensions_data.txt') | 747 'text_format_unittest_extensions_data.txt') |
757 | 748 |
758 def testPrintAllExtensionsPointy(self): | 749 def testPrintAllExtensionsPointy(self): |
759 message = unittest_pb2.TestAllExtensions() | 750 message = unittest_pb2.TestAllExtensions() |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 # Catch parse errors in unknown extension. | 808 # Catch parse errors in unknown extension. |
818 message = unittest_mset_pb2.TestMessageSetContainer() | 809 message = unittest_mset_pb2.TestMessageSetContainer() |
819 malformed = ('message_set {\n' | 810 malformed = ('message_set {\n' |
820 ' [unknown_extension] {\n' | 811 ' [unknown_extension] {\n' |
821 ' i:\n' # Missing value. | 812 ' i:\n' # Missing value. |
822 ' }\n' | 813 ' }\n' |
823 '}\n') | 814 '}\n') |
824 six.assertRaisesRegex(self, | 815 six.assertRaisesRegex(self, |
825 text_format.ParseError, | 816 text_format.ParseError, |
826 'Invalid field value: }', | 817 'Invalid field value: }', |
827 text_format.Parse, malformed, message, | 818 text_format.Parse, |
| 819 malformed, |
| 820 message, |
828 allow_unknown_extension=True) | 821 allow_unknown_extension=True) |
829 | 822 |
830 message = unittest_mset_pb2.TestMessageSetContainer() | 823 message = unittest_mset_pb2.TestMessageSetContainer() |
831 malformed = ('message_set {\n' | 824 malformed = ('message_set {\n' |
832 ' [unknown_extension] {\n' | 825 ' [unknown_extension] {\n' |
833 ' str: "malformed string\n' # Missing closing quote. | 826 ' str: "malformed string\n' # Missing closing quote. |
834 ' }\n' | 827 ' }\n' |
835 '}\n') | 828 '}\n') |
836 six.assertRaisesRegex(self, | 829 six.assertRaisesRegex(self, |
837 text_format.ParseError, | 830 text_format.ParseError, |
838 'Invalid field value: "', | 831 'Invalid field value: "', |
839 text_format.Parse, malformed, message, | 832 text_format.Parse, |
| 833 malformed, |
| 834 message, |
840 allow_unknown_extension=True) | 835 allow_unknown_extension=True) |
841 | 836 |
842 message = unittest_mset_pb2.TestMessageSetContainer() | 837 message = unittest_mset_pb2.TestMessageSetContainer() |
843 malformed = ('message_set {\n' | 838 malformed = ('message_set {\n' |
844 ' [unknown_extension] {\n' | 839 ' [unknown_extension] {\n' |
845 ' str: "malformed\n multiline\n string\n' | 840 ' str: "malformed\n multiline\n string\n' |
846 ' }\n' | 841 ' }\n' |
847 '}\n') | 842 '}\n') |
848 six.assertRaisesRegex(self, | 843 six.assertRaisesRegex(self, |
849 text_format.ParseError, | 844 text_format.ParseError, |
850 'Invalid field value: "', | 845 'Invalid field value: "', |
851 text_format.Parse, malformed, message, | 846 text_format.Parse, |
| 847 malformed, |
| 848 message, |
852 allow_unknown_extension=True) | 849 allow_unknown_extension=True) |
853 | 850 |
854 message = unittest_mset_pb2.TestMessageSetContainer() | 851 message = unittest_mset_pb2.TestMessageSetContainer() |
855 malformed = ('message_set {\n' | 852 malformed = ('message_set {\n' |
856 ' [malformed_extension] <\n' | 853 ' [malformed_extension] <\n' |
857 ' i: -5\n' | 854 ' i: -5\n' |
858 ' \n' # Missing '>' here. | 855 ' \n' # Missing '>' here. |
859 '}\n') | 856 '}\n') |
860 six.assertRaisesRegex(self, | 857 six.assertRaisesRegex(self, |
861 text_format.ParseError, | 858 text_format.ParseError, |
862 '5:1 : Expected ">".', | 859 '5:1 : Expected ">".', |
863 text_format.Parse, malformed, message, | 860 text_format.Parse, |
| 861 malformed, |
| 862 message, |
864 allow_unknown_extension=True) | 863 allow_unknown_extension=True) |
865 | 864 |
866 # Don't allow unknown fields with allow_unknown_extension=True. | 865 # Don't allow unknown fields with allow_unknown_extension=True. |
867 message = unittest_mset_pb2.TestMessageSetContainer() | 866 message = unittest_mset_pb2.TestMessageSetContainer() |
868 malformed = ('message_set {\n' | 867 malformed = ('message_set {\n' |
869 ' unknown_field: true\n' | 868 ' unknown_field: true\n' |
870 ' \n' # Missing '>' here. | 869 ' \n' # Missing '>' here. |
871 '}\n') | 870 '}\n') |
872 six.assertRaisesRegex(self, | 871 six.assertRaisesRegex(self, |
873 text_format.ParseError, | 872 text_format.ParseError, |
874 ('2:3 : Message type ' | 873 ('2:3 : Message type ' |
875 '"proto2_wireformat_unittest.TestMessageSet" has no' | 874 '"proto2_wireformat_unittest.TestMessageSet" has no' |
876 ' field named "unknown_field".'), | 875 ' field named "unknown_field".'), |
877 text_format.Parse, malformed, message, | 876 text_format.Parse, |
| 877 malformed, |
| 878 message, |
878 allow_unknown_extension=True) | 879 allow_unknown_extension=True) |
879 | 880 |
880 # Parse known extension correcty. | 881 # Parse known extension correcty. |
881 message = unittest_mset_pb2.TestMessageSetContainer() | 882 message = unittest_mset_pb2.TestMessageSetContainer() |
882 text = ('message_set {\n' | 883 text = ('message_set {\n' |
883 ' [protobuf_unittest.TestMessageSetExtension1] {\n' | 884 ' [protobuf_unittest.TestMessageSetExtension1] {\n' |
884 ' i: 23\n' | 885 ' i: 23\n' |
885 ' }\n' | 886 ' }\n' |
886 ' [protobuf_unittest.TestMessageSetExtension2] {\n' | 887 ' [protobuf_unittest.TestMessageSetExtension2] {\n' |
887 ' str: \"foo\"\n' | 888 ' str: \"foo\"\n' |
888 ' }\n' | 889 ' }\n' |
889 '}\n') | 890 '}\n') |
890 text_format.Parse(text, message, allow_unknown_extension=True) | 891 text_format.Parse(text, message, allow_unknown_extension=True) |
891 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension | 892 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension |
892 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension | 893 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension |
893 self.assertEqual(23, message.message_set.Extensions[ext1].i) | 894 self.assertEqual(23, message.message_set.Extensions[ext1].i) |
894 self.assertEqual('foo', message.message_set.Extensions[ext2].str) | 895 self.assertEqual('foo', message.message_set.Extensions[ext2].str) |
895 | 896 |
896 def testParseBadExtension(self): | 897 def testParseBadExtension(self): |
897 message = unittest_pb2.TestAllExtensions() | 898 message = unittest_pb2.TestAllExtensions() |
898 text = '[unknown_extension]: 8\n' | 899 text = '[unknown_extension]: 8\n' |
899 six.assertRaisesRegex(self, | 900 six.assertRaisesRegex(self, text_format.ParseError, |
900 text_format.ParseError, | 901 '1:2 : Extension "unknown_extension" not registered.', |
901 '1:2 : Extension "unknown_extension" not registered.', | 902 text_format.Parse, text, message) |
902 text_format.Parse, text, message) | |
903 message = unittest_pb2.TestAllTypes() | 903 message = unittest_pb2.TestAllTypes() |
904 six.assertRaisesRegex(self, | 904 six.assertRaisesRegex(self, text_format.ParseError, ( |
905 text_format.ParseError, | 905 '1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' |
906 ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' | 906 'extensions.'), text_format.Parse, text, message) |
907 'extensions.'), | |
908 text_format.Parse, text, message) | |
909 | 907 |
910 def testMergeDuplicateExtensionScalars(self): | 908 def testMergeDuplicateExtensionScalars(self): |
911 message = unittest_pb2.TestAllExtensions() | 909 message = unittest_pb2.TestAllExtensions() |
912 text = ('[protobuf_unittest.optional_int32_extension]: 42 ' | 910 text = ('[protobuf_unittest.optional_int32_extension]: 42 ' |
913 '[protobuf_unittest.optional_int32_extension]: 67') | 911 '[protobuf_unittest.optional_int32_extension]: 67') |
914 text_format.Merge(text, message) | 912 text_format.Merge(text, message) |
915 self.assertEqual( | 913 self.assertEqual(67, |
916 67, | 914 message.Extensions[unittest_pb2.optional_int32_extension]) |
917 message.Extensions[unittest_pb2.optional_int32_extension]) | |
918 | 915 |
919 def testParseDuplicateExtensionScalars(self): | 916 def testParseDuplicateExtensionScalars(self): |
920 message = unittest_pb2.TestAllExtensions() | 917 message = unittest_pb2.TestAllExtensions() |
921 text = ('[protobuf_unittest.optional_int32_extension]: 42 ' | 918 text = ('[protobuf_unittest.optional_int32_extension]: 42 ' |
922 '[protobuf_unittest.optional_int32_extension]: 67') | 919 '[protobuf_unittest.optional_int32_extension]: 67') |
923 six.assertRaisesRegex(self, | 920 six.assertRaisesRegex(self, text_format.ParseError, ( |
924 text_format.ParseError, | 921 '1:96 : Message type "protobuf_unittest.TestAllExtensions" ' |
925 ('1:96 : Message type "protobuf_unittest.TestAllExtensions" ' | 922 'should not have multiple ' |
926 'should not have multiple ' | 923 '"protobuf_unittest.optional_int32_extension" extensions.'), |
927 '"protobuf_unittest.optional_int32_extension" extensions.'), | 924 text_format.Parse, text, message) |
928 text_format.Parse, text, message) | |
929 | 925 |
930 def testParseDuplicateNestedMessageScalars(self): | 926 def testParseDuplicateNestedMessageScalars(self): |
931 message = unittest_pb2.TestAllTypes() | 927 message = unittest_pb2.TestAllTypes() |
932 text = ('optional_nested_message { bb: 1 } ' | 928 text = ('optional_nested_message { bb: 1 } ' |
933 'optional_nested_message { bb: 2 }') | 929 'optional_nested_message { bb: 2 }') |
934 six.assertRaisesRegex(self, | 930 six.assertRaisesRegex(self, text_format.ParseError, ( |
935 text_format.ParseError, | 931 '1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" ' |
936 ('1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" ' | 932 'should not have multiple "bb" fields.'), text_format.Parse, text, |
937 'should not have multiple "bb" fields.'), | 933 message) |
938 text_format.Parse, text, message) | |
939 | 934 |
940 def testParseDuplicateScalars(self): | 935 def testParseDuplicateScalars(self): |
941 message = unittest_pb2.TestAllTypes() | 936 message = unittest_pb2.TestAllTypes() |
942 text = ('optional_int32: 42 ' | 937 text = ('optional_int32: 42 ' 'optional_int32: 67') |
943 'optional_int32: 67') | 938 six.assertRaisesRegex(self, text_format.ParseError, ( |
944 six.assertRaisesRegex(self, | 939 '1:36 : Message type "protobuf_unittest.TestAllTypes" should not ' |
945 text_format.ParseError, | 940 'have multiple "optional_int32" fields.'), text_format.Parse, text, |
946 ('1:36 : Message type "protobuf_unittest.TestAllTypes" should not ' | 941 message) |
947 'have multiple "optional_int32" fields.'), | |
948 text_format.Parse, text, message) | |
949 | 942 |
950 def testParseGroupNotClosed(self): | 943 def testParseGroupNotClosed(self): |
951 message = unittest_pb2.TestAllTypes() | 944 message = unittest_pb2.TestAllTypes() |
952 text = 'RepeatedGroup: <' | 945 text = 'RepeatedGroup: <' |
953 six.assertRaisesRegex(self, | 946 six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected ">".', |
954 text_format.ParseError, '1:16 : Expected ">".', | 947 text_format.Parse, text, message) |
955 text_format.Parse, text, message) | |
956 text = 'RepeatedGroup: {' | 948 text = 'RepeatedGroup: {' |
957 six.assertRaisesRegex(self, | 949 six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected "}".', |
958 text_format.ParseError, '1:16 : Expected "}".', | 950 text_format.Parse, text, message) |
959 text_format.Parse, text, message) | |
960 | 951 |
961 def testParseEmptyGroup(self): | 952 def testParseEmptyGroup(self): |
962 message = unittest_pb2.TestAllTypes() | 953 message = unittest_pb2.TestAllTypes() |
963 text = 'OptionalGroup: {}' | 954 text = 'OptionalGroup: {}' |
964 text_format.Parse(text, message) | 955 text_format.Parse(text, message) |
965 self.assertTrue(message.HasField('optionalgroup')) | 956 self.assertTrue(message.HasField('optionalgroup')) |
966 | 957 |
967 message.Clear() | 958 message.Clear() |
968 | 959 |
969 message = unittest_pb2.TestAllTypes() | 960 message = unittest_pb2.TestAllTypes() |
(...skipping 30 matching lines...) Expand all Loading... |
1000 ' c: 5\n' | 991 ' c: 5\n' |
1001 ' }\n' | 992 ' }\n' |
1002 '}\n') | 993 '}\n') |
1003 message = map_unittest_pb2.TestMap() | 994 message = map_unittest_pb2.TestMap() |
1004 text_format.Parse(text, message) | 995 text_format.Parse(text, message) |
1005 | 996 |
1006 self.assertEqual(-456, message.map_int32_int32[-123]) | 997 self.assertEqual(-456, message.map_int32_int32[-123]) |
1007 self.assertEqual(-2**34, message.map_int64_int64[-2**33]) | 998 self.assertEqual(-2**34, message.map_int64_int64[-2**33]) |
1008 self.assertEqual(456, message.map_uint32_uint32[123]) | 999 self.assertEqual(456, message.map_uint32_uint32[123]) |
1009 self.assertEqual(2**34, message.map_uint64_uint64[2**33]) | 1000 self.assertEqual(2**34, message.map_uint64_uint64[2**33]) |
1010 self.assertEqual("123", message.map_string_string["abc"]) | 1001 self.assertEqual('123', message.map_string_string['abc']) |
1011 self.assertEqual(5, message.map_int32_foreign_message[111].c) | 1002 self.assertEqual(5, message.map_int32_foreign_message[111].c) |
1012 | 1003 |
1013 | 1004 |
| 1005 class Proto3Tests(unittest.TestCase): |
| 1006 |
| 1007 def testPrintMessageExpandAny(self): |
| 1008 packed_message = unittest_pb2.OneString() |
| 1009 packed_message.data = 'string' |
| 1010 message = any_test_pb2.TestAny() |
| 1011 message.any_value.Pack(packed_message) |
| 1012 self.assertEqual( |
| 1013 text_format.MessageToString(message, |
| 1014 descriptor_pool=descriptor_pool.Default()), |
| 1015 'any_value {\n' |
| 1016 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1017 ' data: "string"\n' |
| 1018 ' }\n' |
| 1019 '}\n') |
| 1020 |
| 1021 def testPrintMessageExpandAnyRepeated(self): |
| 1022 packed_message = unittest_pb2.OneString() |
| 1023 message = any_test_pb2.TestAny() |
| 1024 packed_message.data = 'string0' |
| 1025 message.repeated_any_value.add().Pack(packed_message) |
| 1026 packed_message.data = 'string1' |
| 1027 message.repeated_any_value.add().Pack(packed_message) |
| 1028 self.assertEqual( |
| 1029 text_format.MessageToString(message, |
| 1030 descriptor_pool=descriptor_pool.Default()), |
| 1031 'repeated_any_value {\n' |
| 1032 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1033 ' data: "string0"\n' |
| 1034 ' }\n' |
| 1035 '}\n' |
| 1036 'repeated_any_value {\n' |
| 1037 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1038 ' data: "string1"\n' |
| 1039 ' }\n' |
| 1040 '}\n') |
| 1041 |
| 1042 def testPrintMessageExpandAnyNoDescriptorPool(self): |
| 1043 packed_message = unittest_pb2.OneString() |
| 1044 packed_message.data = 'string' |
| 1045 message = any_test_pb2.TestAny() |
| 1046 message.any_value.Pack(packed_message) |
| 1047 self.assertEqual( |
| 1048 text_format.MessageToString(message, descriptor_pool=None), |
| 1049 'any_value {\n' |
| 1050 ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n' |
| 1051 ' value: "\\n\\006string"\n' |
| 1052 '}\n') |
| 1053 |
| 1054 def testPrintMessageExpandAnyDescriptorPoolMissingType(self): |
| 1055 packed_message = unittest_pb2.OneString() |
| 1056 packed_message.data = 'string' |
| 1057 message = any_test_pb2.TestAny() |
| 1058 message.any_value.Pack(packed_message) |
| 1059 empty_pool = descriptor_pool.DescriptorPool() |
| 1060 self.assertEqual( |
| 1061 text_format.MessageToString(message, descriptor_pool=empty_pool), |
| 1062 'any_value {\n' |
| 1063 ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n' |
| 1064 ' value: "\\n\\006string"\n' |
| 1065 '}\n') |
| 1066 |
| 1067 def testPrintMessageExpandAnyPointyBrackets(self): |
| 1068 packed_message = unittest_pb2.OneString() |
| 1069 packed_message.data = 'string' |
| 1070 message = any_test_pb2.TestAny() |
| 1071 message.any_value.Pack(packed_message) |
| 1072 self.assertEqual( |
| 1073 text_format.MessageToString(message, |
| 1074 pointy_brackets=True, |
| 1075 descriptor_pool=descriptor_pool.Default()), |
| 1076 'any_value <\n' |
| 1077 ' [type.googleapis.com/protobuf_unittest.OneString] <\n' |
| 1078 ' data: "string"\n' |
| 1079 ' >\n' |
| 1080 '>\n') |
| 1081 |
| 1082 def testPrintMessageExpandAnyAsOneLine(self): |
| 1083 packed_message = unittest_pb2.OneString() |
| 1084 packed_message.data = 'string' |
| 1085 message = any_test_pb2.TestAny() |
| 1086 message.any_value.Pack(packed_message) |
| 1087 self.assertEqual( |
| 1088 text_format.MessageToString(message, |
| 1089 as_one_line=True, |
| 1090 descriptor_pool=descriptor_pool.Default()), |
| 1091 'any_value {' |
| 1092 ' [type.googleapis.com/protobuf_unittest.OneString]' |
| 1093 ' { data: "string" } ' |
| 1094 '}') |
| 1095 |
| 1096 def testPrintMessageExpandAnyAsOneLinePointyBrackets(self): |
| 1097 packed_message = unittest_pb2.OneString() |
| 1098 packed_message.data = 'string' |
| 1099 message = any_test_pb2.TestAny() |
| 1100 message.any_value.Pack(packed_message) |
| 1101 self.assertEqual( |
| 1102 text_format.MessageToString(message, |
| 1103 as_one_line=True, |
| 1104 pointy_brackets=True, |
| 1105 descriptor_pool=descriptor_pool.Default()), |
| 1106 'any_value <' |
| 1107 ' [type.googleapis.com/protobuf_unittest.OneString]' |
| 1108 ' < data: "string" > ' |
| 1109 '>') |
| 1110 |
| 1111 def testMergeExpandedAny(self): |
| 1112 message = any_test_pb2.TestAny() |
| 1113 text = ('any_value {\n' |
| 1114 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1115 ' data: "string"\n' |
| 1116 ' }\n' |
| 1117 '}\n') |
| 1118 text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) |
| 1119 packed_message = unittest_pb2.OneString() |
| 1120 message.any_value.Unpack(packed_message) |
| 1121 self.assertEqual('string', packed_message.data) |
| 1122 |
| 1123 def testMergeExpandedAnyRepeated(self): |
| 1124 message = any_test_pb2.TestAny() |
| 1125 text = ('repeated_any_value {\n' |
| 1126 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1127 ' data: "string0"\n' |
| 1128 ' }\n' |
| 1129 '}\n' |
| 1130 'repeated_any_value {\n' |
| 1131 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1132 ' data: "string1"\n' |
| 1133 ' }\n' |
| 1134 '}\n') |
| 1135 text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) |
| 1136 packed_message = unittest_pb2.OneString() |
| 1137 message.repeated_any_value[0].Unpack(packed_message) |
| 1138 self.assertEqual('string0', packed_message.data) |
| 1139 message.repeated_any_value[1].Unpack(packed_message) |
| 1140 self.assertEqual('string1', packed_message.data) |
| 1141 |
| 1142 def testMergeExpandedAnyPointyBrackets(self): |
| 1143 message = any_test_pb2.TestAny() |
| 1144 text = ('any_value {\n' |
| 1145 ' [type.googleapis.com/protobuf_unittest.OneString] <\n' |
| 1146 ' data: "string"\n' |
| 1147 ' >\n' |
| 1148 '}\n') |
| 1149 text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) |
| 1150 packed_message = unittest_pb2.OneString() |
| 1151 message.any_value.Unpack(packed_message) |
| 1152 self.assertEqual('string', packed_message.data) |
| 1153 |
| 1154 def testMergeExpandedAnyNoDescriptorPool(self): |
| 1155 message = any_test_pb2.TestAny() |
| 1156 text = ('any_value {\n' |
| 1157 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1158 ' data: "string"\n' |
| 1159 ' }\n' |
| 1160 '}\n') |
| 1161 with self.assertRaises(text_format.ParseError) as e: |
| 1162 text_format.Merge(text, message, descriptor_pool=None) |
| 1163 self.assertEqual(str(e.exception), |
| 1164 'Descriptor pool required to parse expanded Any field') |
| 1165 |
| 1166 def testMergeExpandedAnyDescriptorPoolMissingType(self): |
| 1167 message = any_test_pb2.TestAny() |
| 1168 text = ('any_value {\n' |
| 1169 ' [type.googleapis.com/protobuf_unittest.OneString] {\n' |
| 1170 ' data: "string"\n' |
| 1171 ' }\n' |
| 1172 '}\n') |
| 1173 with self.assertRaises(text_format.ParseError) as e: |
| 1174 empty_pool = descriptor_pool.DescriptorPool() |
| 1175 text_format.Merge(text, message, descriptor_pool=empty_pool) |
| 1176 self.assertEqual( |
| 1177 str(e.exception), |
| 1178 'Type protobuf_unittest.OneString not found in descriptor pool') |
| 1179 |
| 1180 def testMergeUnexpandedAny(self): |
| 1181 text = ('any_value {\n' |
| 1182 ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n' |
| 1183 ' value: "\\n\\006string"\n' |
| 1184 '}\n') |
| 1185 message = any_test_pb2.TestAny() |
| 1186 text_format.Merge(text, message) |
| 1187 packed_message = unittest_pb2.OneString() |
| 1188 message.any_value.Unpack(packed_message) |
| 1189 self.assertEqual('string', packed_message.data) |
| 1190 |
| 1191 |
1014 class TokenizerTest(unittest.TestCase): | 1192 class TokenizerTest(unittest.TestCase): |
1015 | 1193 |
1016 def testSimpleTokenCases(self): | 1194 def testSimpleTokenCases(self): |
1017 text = ('identifier1:"string1"\n \n\n' | 1195 text = ('identifier1:"string1"\n \n\n' |
1018 'identifier2 : \n \n123 \n identifier3 :\'string\'\n' | 1196 'identifier2 : \n \n123 \n identifier3 :\'string\'\n' |
1019 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n' | 1197 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n' |
1020 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n' | 1198 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n' |
1021 'ID9: 22 ID10: -111111111111111111 ID11: -22\n' | 1199 'ID9: 22 ID10: -111111111111111111 ID11: -22\n' |
1022 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f ' | 1200 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f ' |
1023 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ') | 1201 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' |
1024 tokenizer = text_format._Tokenizer(text.splitlines()) | 1202 'False_bool: False True_bool: True') |
1025 methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), | 1203 tokenizer = text_format.Tokenizer(text.splitlines()) |
1026 ':', | 1204 methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), ':', |
1027 (tokenizer.ConsumeString, 'string1'), | 1205 (tokenizer.ConsumeString, 'string1'), |
1028 (tokenizer.ConsumeIdentifier, 'identifier2'), | 1206 (tokenizer.ConsumeIdentifier, 'identifier2'), ':', |
1029 ':', | 1207 (tokenizer.ConsumeInteger, 123), |
1030 (tokenizer.ConsumeInt32, 123), | 1208 (tokenizer.ConsumeIdentifier, 'identifier3'), ':', |
1031 (tokenizer.ConsumeIdentifier, 'identifier3'), | |
1032 ':', | |
1033 (tokenizer.ConsumeString, 'string'), | 1209 (tokenizer.ConsumeString, 'string'), |
1034 (tokenizer.ConsumeIdentifier, 'identifiER_4'), | 1210 (tokenizer.ConsumeIdentifier, 'identifiER_4'), ':', |
1035 ':', | |
1036 (tokenizer.ConsumeFloat, 1.1e+2), | 1211 (tokenizer.ConsumeFloat, 1.1e+2), |
1037 (tokenizer.ConsumeIdentifier, 'ID5'), | 1212 (tokenizer.ConsumeIdentifier, 'ID5'), ':', |
1038 ':', | |
1039 (tokenizer.ConsumeFloat, -0.23), | 1213 (tokenizer.ConsumeFloat, -0.23), |
1040 (tokenizer.ConsumeIdentifier, 'ID6'), | 1214 (tokenizer.ConsumeIdentifier, 'ID6'), ':', |
1041 ':', | |
1042 (tokenizer.ConsumeString, 'aaaa\'bbbb'), | 1215 (tokenizer.ConsumeString, 'aaaa\'bbbb'), |
1043 (tokenizer.ConsumeIdentifier, 'ID7'), | 1216 (tokenizer.ConsumeIdentifier, 'ID7'), ':', |
1044 ':', | |
1045 (tokenizer.ConsumeString, 'aa\"bb'), | 1217 (tokenizer.ConsumeString, 'aa\"bb'), |
1046 (tokenizer.ConsumeIdentifier, 'ID8'), | 1218 (tokenizer.ConsumeIdentifier, 'ID8'), ':', '{', |
1047 ':', | 1219 (tokenizer.ConsumeIdentifier, 'A'), ':', |
1048 '{', | |
1049 (tokenizer.ConsumeIdentifier, 'A'), | |
1050 ':', | |
1051 (tokenizer.ConsumeFloat, float('inf')), | 1220 (tokenizer.ConsumeFloat, float('inf')), |
1052 (tokenizer.ConsumeIdentifier, 'B'), | 1221 (tokenizer.ConsumeIdentifier, 'B'), ':', |
1053 ':', | |
1054 (tokenizer.ConsumeFloat, -float('inf')), | 1222 (tokenizer.ConsumeFloat, -float('inf')), |
1055 (tokenizer.ConsumeIdentifier, 'C'), | 1223 (tokenizer.ConsumeIdentifier, 'C'), ':', |
1056 ':', | |
1057 (tokenizer.ConsumeBool, True), | 1224 (tokenizer.ConsumeBool, True), |
1058 (tokenizer.ConsumeIdentifier, 'D'), | 1225 (tokenizer.ConsumeIdentifier, 'D'), ':', |
1059 ':', | 1226 (tokenizer.ConsumeBool, False), '}', |
| 1227 (tokenizer.ConsumeIdentifier, 'ID9'), ':', |
| 1228 (tokenizer.ConsumeInteger, 22), |
| 1229 (tokenizer.ConsumeIdentifier, 'ID10'), ':', |
| 1230 (tokenizer.ConsumeInteger, -111111111111111111), |
| 1231 (tokenizer.ConsumeIdentifier, 'ID11'), ':', |
| 1232 (tokenizer.ConsumeInteger, -22), |
| 1233 (tokenizer.ConsumeIdentifier, 'ID12'), ':', |
| 1234 (tokenizer.ConsumeInteger, 2222222222222222222), |
| 1235 (tokenizer.ConsumeIdentifier, 'ID13'), ':', |
| 1236 (tokenizer.ConsumeFloat, 1.23456), |
| 1237 (tokenizer.ConsumeIdentifier, 'ID14'), ':', |
| 1238 (tokenizer.ConsumeFloat, 1.2e+2), |
| 1239 (tokenizer.ConsumeIdentifier, 'false_bool'), ':', |
1060 (tokenizer.ConsumeBool, False), | 1240 (tokenizer.ConsumeBool, False), |
1061 '}', | 1241 (tokenizer.ConsumeIdentifier, 'true_BOOL'), ':', |
1062 (tokenizer.ConsumeIdentifier, 'ID9'), | 1242 (tokenizer.ConsumeBool, True), |
1063 ':', | 1243 (tokenizer.ConsumeIdentifier, 'true_bool1'), ':', |
1064 (tokenizer.ConsumeUint32, 22), | 1244 (tokenizer.ConsumeBool, True), |
1065 (tokenizer.ConsumeIdentifier, 'ID10'), | 1245 (tokenizer.ConsumeIdentifier, 'false_BOOL1'), ':', |
1066 ':', | |
1067 (tokenizer.ConsumeInt64, -111111111111111111), | |
1068 (tokenizer.ConsumeIdentifier, 'ID11'), | |
1069 ':', | |
1070 (tokenizer.ConsumeInt32, -22), | |
1071 (tokenizer.ConsumeIdentifier, 'ID12'), | |
1072 ':', | |
1073 (tokenizer.ConsumeUint64, 2222222222222222222), | |
1074 (tokenizer.ConsumeIdentifier, 'ID13'), | |
1075 ':', | |
1076 (tokenizer.ConsumeFloat, 1.23456), | |
1077 (tokenizer.ConsumeIdentifier, 'ID14'), | |
1078 ':', | |
1079 (tokenizer.ConsumeFloat, 1.2e+2), | |
1080 (tokenizer.ConsumeIdentifier, 'false_bool'), | |
1081 ':', | |
1082 (tokenizer.ConsumeBool, False), | 1246 (tokenizer.ConsumeBool, False), |
1083 (tokenizer.ConsumeIdentifier, 'true_BOOL'), | 1247 (tokenizer.ConsumeIdentifier, 'False_bool'), ':', |
1084 ':', | 1248 (tokenizer.ConsumeBool, False), |
1085 (tokenizer.ConsumeBool, True), | 1249 (tokenizer.ConsumeIdentifier, 'True_bool'), ':', |
1086 (tokenizer.ConsumeIdentifier, 'true_bool1'), | 1250 (tokenizer.ConsumeBool, True)] |
1087 ':', | |
1088 (tokenizer.ConsumeBool, True), | |
1089 (tokenizer.ConsumeIdentifier, 'false_BOOL1'), | |
1090 ':', | |
1091 (tokenizer.ConsumeBool, False)] | |
1092 | 1251 |
1093 i = 0 | 1252 i = 0 |
1094 while not tokenizer.AtEnd(): | 1253 while not tokenizer.AtEnd(): |
1095 m = methods[i] | 1254 m = methods[i] |
1096 if type(m) == str: | 1255 if isinstance(m, str): |
1097 token = tokenizer.token | 1256 token = tokenizer.token |
1098 self.assertEqual(token, m) | 1257 self.assertEqual(token, m) |
1099 tokenizer.NextToken() | 1258 tokenizer.NextToken() |
1100 else: | 1259 else: |
1101 self.assertEqual(m[1], m[0]()) | 1260 self.assertEqual(m[1], m[0]()) |
1102 i += 1 | 1261 i += 1 |
1103 | 1262 |
| 1263 def testConsumeAbstractIntegers(self): |
| 1264 # This test only tests the failures in the integer parsing methods as well |
| 1265 # as the '0' special cases. |
| 1266 int64_max = (1 << 63) - 1 |
| 1267 uint32_max = (1 << 32) - 1 |
| 1268 text = '-1 %d %d' % (uint32_max + 1, int64_max + 1) |
| 1269 tokenizer = text_format.Tokenizer(text.splitlines()) |
| 1270 self.assertEqual(-1, tokenizer.ConsumeInteger()) |
| 1271 |
| 1272 self.assertEqual(uint32_max + 1, tokenizer.ConsumeInteger()) |
| 1273 |
| 1274 self.assertEqual(int64_max + 1, tokenizer.ConsumeInteger()) |
| 1275 self.assertTrue(tokenizer.AtEnd()) |
| 1276 |
| 1277 text = '-0 0' |
| 1278 tokenizer = text_format.Tokenizer(text.splitlines()) |
| 1279 self.assertEqual(0, tokenizer.ConsumeInteger()) |
| 1280 self.assertEqual(0, tokenizer.ConsumeInteger()) |
| 1281 self.assertTrue(tokenizer.AtEnd()) |
| 1282 |
1104 def testConsumeIntegers(self): | 1283 def testConsumeIntegers(self): |
1105 # This test only tests the failures in the integer parsing methods as well | 1284 # This test only tests the failures in the integer parsing methods as well |
1106 # as the '0' special cases. | 1285 # as the '0' special cases. |
1107 int64_max = (1 << 63) - 1 | 1286 int64_max = (1 << 63) - 1 |
1108 uint32_max = (1 << 32) - 1 | 1287 uint32_max = (1 << 32) - 1 |
1109 text = '-1 %d %d' % (uint32_max + 1, int64_max + 1) | 1288 text = '-1 %d %d' % (uint32_max + 1, int64_max + 1) |
1110 tokenizer = text_format._Tokenizer(text.splitlines()) | 1289 tokenizer = text_format.Tokenizer(text.splitlines()) |
1111 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) | 1290 self.assertRaises(text_format.ParseError, |
1112 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64) | 1291 text_format._ConsumeUint32, tokenizer) |
1113 self.assertEqual(-1, tokenizer.ConsumeInt32()) | 1292 self.assertRaises(text_format.ParseError, |
| 1293 text_format._ConsumeUint64, tokenizer) |
| 1294 self.assertEqual(-1, text_format._ConsumeInt32(tokenizer)) |
1114 | 1295 |
1115 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) | 1296 self.assertRaises(text_format.ParseError, |
1116 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32) | 1297 text_format._ConsumeUint32, tokenizer) |
1117 self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64()) | 1298 self.assertRaises(text_format.ParseError, |
| 1299 text_format._ConsumeInt32, tokenizer) |
| 1300 self.assertEqual(uint32_max + 1, text_format._ConsumeInt64(tokenizer)) |
1118 | 1301 |
1119 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64) | 1302 self.assertRaises(text_format.ParseError, |
1120 self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64()) | 1303 text_format._ConsumeInt64, tokenizer) |
| 1304 self.assertEqual(int64_max + 1, text_format._ConsumeUint64(tokenizer)) |
1121 self.assertTrue(tokenizer.AtEnd()) | 1305 self.assertTrue(tokenizer.AtEnd()) |
1122 | 1306 |
1123 text = '-0 -0 0 0' | 1307 text = '-0 -0 0 0' |
1124 tokenizer = text_format._Tokenizer(text.splitlines()) | 1308 tokenizer = text_format.Tokenizer(text.splitlines()) |
1125 self.assertEqual(0, tokenizer.ConsumeUint32()) | 1309 self.assertEqual(0, text_format._ConsumeUint32(tokenizer)) |
1126 self.assertEqual(0, tokenizer.ConsumeUint64()) | 1310 self.assertEqual(0, text_format._ConsumeUint64(tokenizer)) |
1127 self.assertEqual(0, tokenizer.ConsumeUint32()) | 1311 self.assertEqual(0, text_format._ConsumeUint32(tokenizer)) |
1128 self.assertEqual(0, tokenizer.ConsumeUint64()) | 1312 self.assertEqual(0, text_format._ConsumeUint64(tokenizer)) |
1129 self.assertTrue(tokenizer.AtEnd()) | 1313 self.assertTrue(tokenizer.AtEnd()) |
1130 | 1314 |
1131 def testConsumeByteString(self): | 1315 def testConsumeByteString(self): |
1132 text = '"string1\'' | 1316 text = '"string1\'' |
1133 tokenizer = text_format._Tokenizer(text.splitlines()) | 1317 tokenizer = text_format.Tokenizer(text.splitlines()) |
1134 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) | 1318 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) |
1135 | 1319 |
1136 text = 'string1"' | 1320 text = 'string1"' |
1137 tokenizer = text_format._Tokenizer(text.splitlines()) | 1321 tokenizer = text_format.Tokenizer(text.splitlines()) |
1138 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) | 1322 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) |
1139 | 1323 |
1140 text = '\n"\\xt"' | 1324 text = '\n"\\xt"' |
1141 tokenizer = text_format._Tokenizer(text.splitlines()) | 1325 tokenizer = text_format.Tokenizer(text.splitlines()) |
1142 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) | 1326 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) |
1143 | 1327 |
1144 text = '\n"\\"' | 1328 text = '\n"\\"' |
1145 tokenizer = text_format._Tokenizer(text.splitlines()) | 1329 tokenizer = text_format.Tokenizer(text.splitlines()) |
1146 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) | 1330 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) |
1147 | 1331 |
1148 text = '\n"\\x"' | 1332 text = '\n"\\x"' |
1149 tokenizer = text_format._Tokenizer(text.splitlines()) | 1333 tokenizer = text_format.Tokenizer(text.splitlines()) |
1150 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) | 1334 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) |
1151 | 1335 |
1152 def testConsumeBool(self): | 1336 def testConsumeBool(self): |
1153 text = 'not-a-bool' | 1337 text = 'not-a-bool' |
1154 tokenizer = text_format._Tokenizer(text.splitlines()) | 1338 tokenizer = text_format.Tokenizer(text.splitlines()) |
1155 self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) | 1339 self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) |
1156 | 1340 |
| 1341 def testSkipComment(self): |
| 1342 tokenizer = text_format.Tokenizer('# some comment'.splitlines()) |
| 1343 self.assertTrue(tokenizer.AtEnd()) |
| 1344 self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment) |
| 1345 |
| 1346 def testConsumeComment(self): |
| 1347 tokenizer = text_format.Tokenizer('# some comment'.splitlines(), |
| 1348 skip_comments=False) |
| 1349 self.assertFalse(tokenizer.AtEnd()) |
| 1350 self.assertEqual('# some comment', tokenizer.ConsumeComment()) |
| 1351 self.assertTrue(tokenizer.AtEnd()) |
| 1352 |
| 1353 def testConsumeTwoComments(self): |
| 1354 text = '# some comment\n# another comment' |
| 1355 tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False) |
| 1356 self.assertEqual('# some comment', tokenizer.ConsumeComment()) |
| 1357 self.assertFalse(tokenizer.AtEnd()) |
| 1358 self.assertEqual('# another comment', tokenizer.ConsumeComment()) |
| 1359 self.assertTrue(tokenizer.AtEnd()) |
| 1360 |
| 1361 def testConsumeTrailingComment(self): |
| 1362 text = 'some_number: 4\n# some comment' |
| 1363 tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False) |
| 1364 self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment) |
| 1365 |
| 1366 self.assertEqual('some_number', tokenizer.ConsumeIdentifier()) |
| 1367 self.assertEqual(tokenizer.token, ':') |
| 1368 tokenizer.NextToken() |
| 1369 self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment) |
| 1370 self.assertEqual(4, tokenizer.ConsumeInteger()) |
| 1371 self.assertFalse(tokenizer.AtEnd()) |
| 1372 |
| 1373 self.assertEqual('# some comment', tokenizer.ConsumeComment()) |
| 1374 self.assertTrue(tokenizer.AtEnd()) |
| 1375 |
1157 | 1376 |
1158 if __name__ == '__main__': | 1377 if __name__ == '__main__': |
1159 unittest.main() | 1378 unittest.main() |
OLD | NEW |