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