Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: third_party/protobuf/python/google/protobuf/internal/text_format_test.py

Issue 1291903002: Pull new version of protobuf sources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #! /usr/bin/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 # http://code.google.com/p/protobuf/ 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 #
11 # * Redistributions of source code must retain the above copyright 11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer. 12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above 13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following disclaimer 14 # copyright notice, this list of conditions and the following disclaimer
15 # in the documentation and/or other materials provided with the 15 # in the documentation and/or other materials provided with the
(...skipping 11 matching lines...) Expand all
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 32
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 import difflib
38 import re 37 import re
38 import unittest
39 39
40 import unittest 40 import unittest
41 from google.protobuf.internal import _parameterized
42
43 from google.protobuf import map_unittest_pb2
44 from google.protobuf import unittest_mset_pb2
45 from google.protobuf import unittest_pb2
46 from google.protobuf import unittest_proto3_arena_pb2
47 from google.protobuf.internal import api_implementation
48 from google.protobuf.internal import test_util
41 from google.protobuf import text_format 49 from google.protobuf import text_format
42 from google.protobuf.internal import test_util
43 from google.protobuf import unittest_pb2
44 from google.protobuf import unittest_mset_pb2
45 50
51 # Base class with some common functionality.
52 class TextFormatBase(unittest.TestCase):
46 53
47 class TextFormatTest(unittest.TestCase):
48 def ReadGolden(self, golden_filename): 54 def ReadGolden(self, golden_filename):
49 f = test_util.GoldenFile(golden_filename) 55 with test_util.GoldenFile(golden_filename) as f:
50 golden_lines = f.readlines() 56 return (f.readlines() if str is bytes else # PY3
51 f.close() 57 [golden_line.decode('utf-8') for golden_line in f])
52 return golden_lines
53 58
54 def CompareToGoldenFile(self, text, golden_filename): 59 def CompareToGoldenFile(self, text, golden_filename):
55 golden_lines = self.ReadGolden(golden_filename) 60 golden_lines = self.ReadGolden(golden_filename)
56 self.CompareToGoldenLines(text, golden_lines) 61 self.assertMultiLineEqual(text, ''.join(golden_lines))
57 62
58 def CompareToGoldenText(self, text, golden_text): 63 def CompareToGoldenText(self, text, golden_text):
59 self.CompareToGoldenLines(text, golden_text.splitlines(1)) 64 self.assertMultiLineEqual(text, golden_text)
60 65
61 def CompareToGoldenLines(self, text, golden_lines): 66 def RemoveRedundantZeros(self, text):
62 actual_lines = text.splitlines(1) 67 # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove
63 self.assertEqual(golden_lines, actual_lines, 68 # these zeros in order to match the golden file.
64 "Text doesn't match golden. Diff:\n" + 69 text = text.replace('e+0','e+').replace('e+0','e+') \
65 ''.join(difflib.ndiff(golden_lines, actual_lines))) 70 .replace('e-0','e-').replace('e-0','e-')
71 # Floating point fields are printed with .0 suffix even if they are
72 # actualy integer numbers.
73 text = re.compile('\.0$', re.MULTILINE).sub('', text)
74 return text
66 75
67 def testPrintAllFields(self):
68 message = unittest_pb2.TestAllTypes()
69 test_util.SetAllFields(message)
70 self.CompareToGoldenFile(
71 self.RemoveRedundantZeros(text_format.MessageToString(message)),
72 'text_format_unittest_data.txt')
73 76
74 def testPrintAllExtensions(self): 77 @_parameterized.Parameters(
75 message = unittest_pb2.TestAllExtensions() 78 (unittest_pb2),
76 test_util.SetAllExtensions(message) 79 (unittest_proto3_arena_pb2))
77 self.CompareToGoldenFile( 80 class TextFormatTest(TextFormatBase):
78 self.RemoveRedundantZeros(text_format.MessageToString(message)),
79 'text_format_unittest_extensions_data.txt')
80 81
81 def testPrintMessageSet(self): 82 def testPrintExotic(self, message_module):
82 message = unittest_mset_pb2.TestMessageSetContainer() 83 message = message_module.TestAllTypes()
83 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
84 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
85 message.message_set.Extensions[ext1].i = 23
86 message.message_set.Extensions[ext2].str = 'foo'
87 self.CompareToGoldenText(text_format.MessageToString(message),
88 'message_set {\n'
89 ' [protobuf_unittest.TestMessageSetExtension1] {\n'
90 ' i: 23\n'
91 ' }\n'
92 ' [protobuf_unittest.TestMessageSetExtension2] {\n'
93 ' str: \"foo\"\n'
94 ' }\n'
95 '}\n')
96
97 def testPrintBadEnumValue(self):
98 message = unittest_pb2.TestAllTypes()
99 message.optional_nested_enum = 100
100 message.optional_foreign_enum = 101
101 message.optional_import_enum = 102
102 self.CompareToGoldenText(
103 text_format.MessageToString(message),
104 'optional_nested_enum: 100\n'
105 'optional_foreign_enum: 101\n'
106 'optional_import_enum: 102\n')
107
108 def testPrintBadEnumValueExtensions(self):
109 message = unittest_pb2.TestAllExtensions()
110 message.Extensions[unittest_pb2.optional_nested_enum_extension] = 100
111 message.Extensions[unittest_pb2.optional_foreign_enum_extension] = 101
112 message.Extensions[unittest_pb2.optional_import_enum_extension] = 102
113 self.CompareToGoldenText(
114 text_format.MessageToString(message),
115 '[protobuf_unittest.optional_nested_enum_extension]: 100\n'
116 '[protobuf_unittest.optional_foreign_enum_extension]: 101\n'
117 '[protobuf_unittest.optional_import_enum_extension]: 102\n')
118
119 def testPrintExotic(self):
120 message = unittest_pb2.TestAllTypes()
121 message.repeated_int64.append(-9223372036854775808) 84 message.repeated_int64.append(-9223372036854775808)
122 message.repeated_uint64.append(18446744073709551615) 85 message.repeated_uint64.append(18446744073709551615)
123 message.repeated_double.append(123.456) 86 message.repeated_double.append(123.456)
124 message.repeated_double.append(1.23e22) 87 message.repeated_double.append(1.23e22)
125 message.repeated_double.append(1.23e-18) 88 message.repeated_double.append(1.23e-18)
126 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') 89 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
127 message.repeated_string.append(u'\u00fc\ua71f') 90 message.repeated_string.append(u'\u00fc\ua71f')
128 self.CompareToGoldenText( 91 self.CompareToGoldenText(
129 self.RemoveRedundantZeros(text_format.MessageToString(message)), 92 self.RemoveRedundantZeros(text_format.MessageToString(message)),
130 'repeated_int64: -9223372036854775808\n' 93 'repeated_int64: -9223372036854775808\n'
131 'repeated_uint64: 18446744073709551615\n' 94 'repeated_uint64: 18446744073709551615\n'
132 'repeated_double: 123.456\n' 95 'repeated_double: 123.456\n'
133 'repeated_double: 1.23e+22\n' 96 'repeated_double: 1.23e+22\n'
134 'repeated_double: 1.23e-18\n' 97 'repeated_double: 1.23e-18\n'
135 'repeated_string: ' 98 'repeated_string:'
136 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' 99 ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
137 'repeated_string: "\\303\\274\\352\\234\\237"\n') 100 'repeated_string: "\\303\\274\\352\\234\\237"\n')
138 101
139 def testPrintNestedMessageAsOneLine(self): 102 def testPrintExoticUnicodeSubclass(self, message_module):
140 message = unittest_pb2.TestAllTypes() 103 class UnicodeSub(unicode):
104 pass
105 message = message_module.TestAllTypes()
106 message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f'))
107 self.CompareToGoldenText(
108 text_format.MessageToString(message),
109 'repeated_string: "\\303\\274\\352\\234\\237"\n')
110
111 def testPrintNestedMessageAsOneLine(self, message_module):
112 message = message_module.TestAllTypes()
141 msg = message.repeated_nested_message.add() 113 msg = message.repeated_nested_message.add()
142 msg.bb = 42; 114 msg.bb = 42
143 self.CompareToGoldenText( 115 self.CompareToGoldenText(
144 text_format.MessageToString(message, as_one_line=True), 116 text_format.MessageToString(message, as_one_line=True),
145 'repeated_nested_message { bb: 42 }') 117 'repeated_nested_message { bb: 42 }')
146 118
147 def testPrintRepeatedFieldsAsOneLine(self): 119 def testPrintRepeatedFieldsAsOneLine(self, message_module):
148 message = unittest_pb2.TestAllTypes() 120 message = message_module.TestAllTypes()
149 message.repeated_int32.append(1) 121 message.repeated_int32.append(1)
150 message.repeated_int32.append(1) 122 message.repeated_int32.append(1)
151 message.repeated_int32.append(3) 123 message.repeated_int32.append(3)
152 message.repeated_string.append("Google") 124 message.repeated_string.append('Google')
153 message.repeated_string.append("Zurich") 125 message.repeated_string.append('Zurich')
154 self.CompareToGoldenText( 126 self.CompareToGoldenText(
155 text_format.MessageToString(message, as_one_line=True), 127 text_format.MessageToString(message, as_one_line=True),
156 'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 ' 128 'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
157 'repeated_string: "Google" repeated_string: "Zurich"') 129 'repeated_string: "Google" repeated_string: "Zurich"')
158 130
159 def testPrintNestedNewLineInStringAsOneLine(self): 131 def testPrintNestedNewLineInStringAsOneLine(self, message_module):
160 message = unittest_pb2.TestAllTypes() 132 message = message_module.TestAllTypes()
161 message.optional_string = "a\nnew\nline" 133 message.optional_string = 'a\nnew\nline'
162 self.CompareToGoldenText( 134 self.CompareToGoldenText(
163 text_format.MessageToString(message, as_one_line=True), 135 text_format.MessageToString(message, as_one_line=True),
164 'optional_string: "a\\nnew\\nline"') 136 'optional_string: "a\\nnew\\nline"')
165 137
166 def testPrintMessageSetAsOneLine(self): 138 def testPrintExoticAsOneLine(self, message_module):
167 message = unittest_mset_pb2.TestMessageSetContainer() 139 message = message_module.TestAllTypes()
168 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
169 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
170 message.message_set.Extensions[ext1].i = 23
171 message.message_set.Extensions[ext2].str = 'foo'
172 self.CompareToGoldenText(
173 text_format.MessageToString(message, as_one_line=True),
174 'message_set {'
175 ' [protobuf_unittest.TestMessageSetExtension1] {'
176 ' i: 23'
177 ' }'
178 ' [protobuf_unittest.TestMessageSetExtension2] {'
179 ' str: \"foo\"'
180 ' }'
181 ' }')
182
183 def testPrintExoticAsOneLine(self):
184 message = unittest_pb2.TestAllTypes()
185 message.repeated_int64.append(-9223372036854775808) 140 message.repeated_int64.append(-9223372036854775808)
186 message.repeated_uint64.append(18446744073709551615) 141 message.repeated_uint64.append(18446744073709551615)
187 message.repeated_double.append(123.456) 142 message.repeated_double.append(123.456)
188 message.repeated_double.append(1.23e22) 143 message.repeated_double.append(1.23e22)
189 message.repeated_double.append(1.23e-18) 144 message.repeated_double.append(1.23e-18)
190 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') 145 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
191 message.repeated_string.append(u'\u00fc\ua71f') 146 message.repeated_string.append(u'\u00fc\ua71f')
192 self.CompareToGoldenText( 147 self.CompareToGoldenText(
193 self.RemoveRedundantZeros( 148 self.RemoveRedundantZeros(
194 text_format.MessageToString(message, as_one_line=True)), 149 text_format.MessageToString(message, as_one_line=True)),
195 'repeated_int64: -9223372036854775808' 150 'repeated_int64: -9223372036854775808'
196 ' repeated_uint64: 18446744073709551615' 151 ' repeated_uint64: 18446744073709551615'
197 ' repeated_double: 123.456' 152 ' repeated_double: 123.456'
198 ' repeated_double: 1.23e+22' 153 ' repeated_double: 1.23e+22'
199 ' repeated_double: 1.23e-18' 154 ' repeated_double: 1.23e-18'
200 ' repeated_string: ' 155 ' repeated_string: '
201 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""' 156 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""'
202 ' repeated_string: "\\303\\274\\352\\234\\237"') 157 ' repeated_string: "\\303\\274\\352\\234\\237"')
203 158
204 def testRoundTripExoticAsOneLine(self): 159 def testRoundTripExoticAsOneLine(self, message_module):
205 message = unittest_pb2.TestAllTypes() 160 message = message_module.TestAllTypes()
206 message.repeated_int64.append(-9223372036854775808) 161 message.repeated_int64.append(-9223372036854775808)
207 message.repeated_uint64.append(18446744073709551615) 162 message.repeated_uint64.append(18446744073709551615)
208 message.repeated_double.append(123.456) 163 message.repeated_double.append(123.456)
209 message.repeated_double.append(1.23e22) 164 message.repeated_double.append(1.23e22)
210 message.repeated_double.append(1.23e-18) 165 message.repeated_double.append(1.23e-18)
211 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') 166 message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
212 message.repeated_string.append(u'\u00fc\ua71f') 167 message.repeated_string.append(u'\u00fc\ua71f')
213 168
214 # Test as_utf8 = False. 169 # Test as_utf8 = False.
215 wire_text = text_format.MessageToString( 170 wire_text = text_format.MessageToString(
216 message, as_one_line=True, as_utf8=False) 171 message, as_one_line=True, as_utf8=False)
217 parsed_message = unittest_pb2.TestAllTypes() 172 parsed_message = message_module.TestAllTypes()
218 text_format.Merge(wire_text, parsed_message) 173 r = text_format.Parse(wire_text, parsed_message)
174 self.assertIs(r, parsed_message)
219 self.assertEquals(message, parsed_message) 175 self.assertEquals(message, parsed_message)
220 176
221 # Test as_utf8 = True. 177 # Test as_utf8 = True.
222 wire_text = text_format.MessageToString( 178 wire_text = text_format.MessageToString(
223 message, as_one_line=True, as_utf8=True) 179 message, as_one_line=True, as_utf8=True)
224 parsed_message = unittest_pb2.TestAllTypes() 180 parsed_message = message_module.TestAllTypes()
225 text_format.Merge(wire_text, parsed_message) 181 r = text_format.Parse(wire_text, parsed_message)
226 self.assertEquals(message, parsed_message) 182 self.assertIs(r, parsed_message)
227 183 self.assertEquals(message, parsed_message,
228 def testPrintRawUtf8String(self): 184 '\n%s != %s' % (message, parsed_message))
229 message = unittest_pb2.TestAllTypes() 185
186 def testPrintRawUtf8String(self, message_module):
187 message = message_module.TestAllTypes()
230 message.repeated_string.append(u'\u00fc\ua71f') 188 message.repeated_string.append(u'\u00fc\ua71f')
231 text = text_format.MessageToString(message, as_utf8 = True) 189 text = text_format.MessageToString(message, as_utf8=True)
232 self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n') 190 self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
233 parsed_message = unittest_pb2.TestAllTypes() 191 parsed_message = message_module.TestAllTypes()
234 text_format.Merge(text, parsed_message) 192 text_format.Parse(text, parsed_message)
235 self.assertEquals(message, parsed_message) 193 self.assertEquals(message, parsed_message,
236 194 '\n%s != %s' % (message, parsed_message))
237 def testMessageToString(self): 195
238 message = unittest_pb2.ForeignMessage() 196 def testPrintFloatFormat(self, message_module):
197 # Check that float_format argument is passed to sub-message formatting.
198 message = message_module.NestedTestAllTypes()
199 # We use 1.25 as it is a round number in binary. The proto 32-bit float
200 # will not gain additional imprecise digits as a 64-bit Python float and
201 # show up in its str. 32-bit 1.2 is noisy when extended to 64-bit:
202 # >>> struct.unpack('f', struct.pack('f', 1.2))[0]
203 # 1.2000000476837158
204 # >>> struct.unpack('f', struct.pack('f', 1.25))[0]
205 # 1.25
206 message.payload.optional_float = 1.25
207 # Check rounding at 15 significant digits
208 message.payload.optional_double = -.000003456789012345678
209 # Check no decimal point.
210 message.payload.repeated_float.append(-5642)
211 # Check no trailing zeros.
212 message.payload.repeated_double.append(.000078900)
213 formatted_fields = ['optional_float: 1.25',
214 'optional_double: -3.45678901234568e-6',
215 'repeated_float: -5642',
216 'repeated_double: 7.89e-5']
217 text_message = text_format.MessageToString(message, float_format='.15g')
218 self.CompareToGoldenText(
219 self.RemoveRedundantZeros(text_message),
220 'payload {{\n {}\n {}\n {}\n {}\n}}\n'.format(*formatted_fields))
221 # as_one_line=True is a separate code branch where float_format is passed.
222 text_message = text_format.MessageToString(message, as_one_line=True,
223 float_format='.15g')
224 self.CompareToGoldenText(
225 self.RemoveRedundantZeros(text_message),
226 'payload {{ {} {} {} {} }}'.format(*formatted_fields))
227
228 def testMessageToString(self, message_module):
229 message = message_module.ForeignMessage()
239 message.c = 123 230 message.c = 123
240 self.assertEqual('c: 123\n', str(message)) 231 self.assertEqual('c: 123\n', str(message))
241 232
242 def RemoveRedundantZeros(self, text): 233 def testParseAllFields(self, message_module):
243 # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove 234 message = message_module.TestAllTypes()
244 # these zeros in order to match the golden file. 235 test_util.SetAllFields(message)
245 text = text.replace('e+0','e+').replace('e+0','e+') \ 236 ascii_text = text_format.MessageToString(message)
246 .replace('e-0','e-').replace('e-0','e-') 237
247 # Floating point fields are printed with .0 suffix even if they are 238 parsed_message = message_module.TestAllTypes()
248 # actualy integer numbers. 239 text_format.Parse(ascii_text, parsed_message)
249 text = re.compile('\.0$', re.MULTILINE).sub('', text) 240 self.assertEqual(message, parsed_message)
250 return text 241 if message_module is unittest_pb2:
251 242 test_util.ExpectAllFieldsSet(self, message)
252 def testMergeGolden(self): 243
244 def testParseExotic(self, message_module):
245 message = message_module.TestAllTypes()
246 text = ('repeated_int64: -9223372036854775808\n'
247 'repeated_uint64: 18446744073709551615\n'
248 'repeated_double: 123.456\n'
249 'repeated_double: 1.23e+22\n'
250 'repeated_double: 1.23e-18\n'
251 'repeated_string: \n'
252 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
253 'repeated_string: "foo" \'corge\' "grault"\n'
254 'repeated_string: "\\303\\274\\352\\234\\237"\n'
255 'repeated_string: "\\xc3\\xbc"\n'
256 'repeated_string: "\xc3\xbc"\n')
257 text_format.Parse(text, message)
258
259 self.assertEqual(-9223372036854775808, message.repeated_int64[0])
260 self.assertEqual(18446744073709551615, message.repeated_uint64[0])
261 self.assertEqual(123.456, message.repeated_double[0])
262 self.assertEqual(1.23e22, message.repeated_double[1])
263 self.assertEqual(1.23e-18, message.repeated_double[2])
264 self.assertEqual(
265 '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
266 self.assertEqual('foocorgegrault', message.repeated_string[1])
267 self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
268 self.assertEqual(u'\u00fc', message.repeated_string[3])
269
270 def testParseTrailingCommas(self, message_module):
271 message = message_module.TestAllTypes()
272 text = ('repeated_int64: 100;\n'
273 'repeated_int64: 200;\n'
274 'repeated_int64: 300,\n'
275 'repeated_string: "one",\n'
276 'repeated_string: "two";\n')
277 text_format.Parse(text, message)
278
279 self.assertEqual(100, message.repeated_int64[0])
280 self.assertEqual(200, message.repeated_int64[1])
281 self.assertEqual(300, message.repeated_int64[2])
282 self.assertEqual(u'one', message.repeated_string[0])
283 self.assertEqual(u'two', message.repeated_string[1])
284
285 def testParseEmptyText(self, message_module):
286 message = message_module.TestAllTypes()
287 text = ''
288 text_format.Parse(text, message)
289 self.assertEquals(message_module.TestAllTypes(), message)
290
291 def testParseInvalidUtf8(self, message_module):
292 message = message_module.TestAllTypes()
293 text = 'repeated_string: "\\xc3\\xc3"'
294 self.assertRaises(text_format.ParseError, text_format.Parse, text, message)
295
296 def testParseSingleWord(self, message_module):
297 message = message_module.TestAllTypes()
298 text = 'foo'
299 self.assertRaisesRegexp(
300 text_format.ParseError,
301 (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
302 r'"foo".'),
303 text_format.Parse, text, message)
304
305 def testParseUnknownField(self, message_module):
306 message = message_module.TestAllTypes()
307 text = 'unknown_field: 8\n'
308 self.assertRaisesRegexp(
309 text_format.ParseError,
310 (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
311 r'"unknown_field".'),
312 text_format.Parse, text, message)
313
314 def testParseBadEnumValue(self, message_module):
315 message = message_module.TestAllTypes()
316 text = 'optional_nested_enum: BARR'
317 self.assertRaisesRegexp(
318 text_format.ParseError,
319 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
320 r'has no value named BARR.'),
321 text_format.Parse, text, message)
322
323 message = message_module.TestAllTypes()
324 text = 'optional_nested_enum: 100'
325 self.assertRaisesRegexp(
326 text_format.ParseError,
327 (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
328 r'has no value with number 100.'),
329 text_format.Parse, text, message)
330
331 def testParseBadIntValue(self, message_module):
332 message = message_module.TestAllTypes()
333 text = 'optional_int32: bork'
334 self.assertRaisesRegexp(
335 text_format.ParseError,
336 ('1:17 : Couldn\'t parse integer: bork'),
337 text_format.Parse, text, message)
338
339 def testParseStringFieldUnescape(self, message_module):
340 message = message_module.TestAllTypes()
341 text = r'''repeated_string: "\xf\x62"
342 repeated_string: "\\xf\\x62"
343 repeated_string: "\\\xf\\\x62"
344 repeated_string: "\\\\xf\\\\x62"
345 repeated_string: "\\\\\xf\\\\\x62"
346 repeated_string: "\x5cx20"'''
347 text_format.Parse(text, message)
348
349 SLASH = '\\'
350 self.assertEqual('\x0fb', message.repeated_string[0])
351 self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1])
352 self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2])
353 self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62',
354 message.repeated_string[3])
355 self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b',
356 message.repeated_string[4])
357 self.assertEqual(SLASH + 'x20', message.repeated_string[5])
358
359 def testMergeDuplicateScalars(self, message_module):
360 message = message_module.TestAllTypes()
361 text = ('optional_int32: 42 '
362 'optional_int32: 67')
363 r = text_format.Merge(text, message)
364 self.assertIs(r, message)
365 self.assertEqual(67, message.optional_int32)
366
367 def testMergeDuplicateNestedMessageScalars(self, message_module):
368 message = message_module.TestAllTypes()
369 text = ('optional_nested_message { bb: 1 } '
370 'optional_nested_message { bb: 2 }')
371 r = text_format.Merge(text, message)
372 self.assertTrue(r is message)
373 self.assertEqual(2, message.optional_nested_message.bb)
374
375 def testParseOneof(self, message_module):
376 m = message_module.TestAllTypes()
377 m.oneof_uint32 = 11
378 m2 = message_module.TestAllTypes()
379 text_format.Parse(text_format.MessageToString(m), m2)
380 self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
381
382
383 # These are tests that aren't fundamentally specific to proto2, but are at
384 # the moment because of differences between the proto2 and proto3 test schemas.
385 # Ideally the schemas would be made more similar so these tests could pass.
386 class OnlyWorksWithProto2RightNowTests(TextFormatBase):
387
388 def testPrintAllFieldsPointy(self, message_module):
389 message = unittest_pb2.TestAllTypes()
390 test_util.SetAllFields(message)
391 self.CompareToGoldenFile(
392 self.RemoveRedundantZeros(
393 text_format.MessageToString(message, pointy_brackets=True)),
394 'text_format_unittest_data_pointy_oneof.txt')
395
396 def testParseGolden(self):
253 golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt')) 397 golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
254 parsed_message = unittest_pb2.TestAllTypes() 398 parsed_message = unittest_pb2.TestAllTypes()
255 text_format.Merge(golden_text, parsed_message) 399 r = text_format.Parse(golden_text, parsed_message)
400 self.assertIs(r, parsed_message)
256 401
257 message = unittest_pb2.TestAllTypes() 402 message = unittest_pb2.TestAllTypes()
258 test_util.SetAllFields(message) 403 test_util.SetAllFields(message)
259 self.assertEquals(message, parsed_message) 404 self.assertEquals(message, parsed_message)
260 405
261 def testMergeGoldenExtensions(self): 406 def testPrintAllFields(self):
262 golden_text = '\n'.join(self.ReadGolden( 407 message = unittest_pb2.TestAllTypes()
263 'text_format_unittest_extensions_data.txt')) 408 test_util.SetAllFields(message)
264 parsed_message = unittest_pb2.TestAllExtensions() 409 self.CompareToGoldenFile(
265 text_format.Merge(golden_text, parsed_message) 410 self.RemoveRedundantZeros(text_format.MessageToString(message)),
266 411 'text_format_unittest_data_oneof_implemented.txt')
267 message = unittest_pb2.TestAllExtensions() 412
268 test_util.SetAllExtensions(message) 413 def testPrintAllFieldsPointy(self):
414 message = unittest_pb2.TestAllTypes()
415 test_util.SetAllFields(message)
416 self.CompareToGoldenFile(
417 self.RemoveRedundantZeros(
418 text_format.MessageToString(message, pointy_brackets=True)),
419 'text_format_unittest_data_pointy_oneof.txt')
420
421 def testPrintInIndexOrder(self):
422 message = unittest_pb2.TestFieldOrderings()
423 message.my_string = '115'
424 message.my_int = 101
425 message.my_float = 111
426 message.optional_nested_message.oo = 0
427 message.optional_nested_message.bb = 1
428 self.CompareToGoldenText(
429 self.RemoveRedundantZeros(text_format.MessageToString(
430 message, use_index_order=True)),
431 'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n'
432 'optional_nested_message {\n oo: 0\n bb: 1\n}\n')
433 self.CompareToGoldenText(
434 self.RemoveRedundantZeros(text_format.MessageToString(
435 message)),
436 'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n'
437 'optional_nested_message {\n bb: 1\n oo: 0\n}\n')
438
439 def testMergeLinesGolden(self):
440 opened = self.ReadGolden('text_format_unittest_data.txt')
441 parsed_message = unittest_pb2.TestAllTypes()
442 r = text_format.MergeLines(opened, parsed_message)
443 self.assertIs(r, parsed_message)
444
445 message = unittest_pb2.TestAllTypes()
446 test_util.SetAllFields(message)
447 self.assertEqual(message, parsed_message)
448
449 def testParseLinesGolden(self):
450 opened = self.ReadGolden('text_format_unittest_data.txt')
451 parsed_message = unittest_pb2.TestAllTypes()
452 r = text_format.ParseLines(opened, parsed_message)
453 self.assertIs(r, parsed_message)
454
455 message = unittest_pb2.TestAllTypes()
456 test_util.SetAllFields(message)
269 self.assertEquals(message, parsed_message) 457 self.assertEquals(message, parsed_message)
270 458
271 def testMergeAllFields(self): 459 def testPrintMap(self):
272 message = unittest_pb2.TestAllTypes() 460 message = map_unittest_pb2.TestMap()
273 test_util.SetAllFields(message) 461
274 ascii_text = text_format.MessageToString(message) 462 message.map_int32_int32[-123] = -456
275 463 message.map_int64_int64[-2**33] = -2**34
276 parsed_message = unittest_pb2.TestAllTypes() 464 message.map_uint32_uint32[123] = 456
277 text_format.Merge(ascii_text, parsed_message) 465 message.map_uint64_uint64[2**33] = 2**34
278 self.assertEqual(message, parsed_message) 466 message.map_string_string["abc"] = "123"
279 test_util.ExpectAllFieldsSet(self, message) 467 message.map_int32_foreign_message[111].c = 5
280 468
281 def testMergeAllExtensions(self): 469 # Maps are serialized to text format using their underlying repeated
282 message = unittest_pb2.TestAllExtensions() 470 # representation.
283 test_util.SetAllExtensions(message) 471 self.CompareToGoldenText(
284 ascii_text = text_format.MessageToString(message) 472 text_format.MessageToString(message),
285 473 'map_int32_int32 {\n'
286 parsed_message = unittest_pb2.TestAllExtensions() 474 ' key: -123\n'
287 text_format.Merge(ascii_text, parsed_message) 475 ' value: -456\n'
288 self.assertEqual(message, parsed_message) 476 '}\n'
289 477 'map_int64_int64 {\n'
290 def testMergeMessageSet(self): 478 ' key: -8589934592\n'
479 ' value: -17179869184\n'
480 '}\n'
481 'map_uint32_uint32 {\n'
482 ' key: 123\n'
483 ' value: 456\n'
484 '}\n'
485 'map_uint64_uint64 {\n'
486 ' key: 8589934592\n'
487 ' value: 17179869184\n'
488 '}\n'
489 'map_string_string {\n'
490 ' key: "abc"\n'
491 ' value: "123"\n'
492 '}\n'
493 'map_int32_foreign_message {\n'
494 ' key: 111\n'
495 ' value {\n'
496 ' c: 5\n'
497 ' }\n'
498 '}\n')
499
500
501 # Tests of proto2-only features (MessageSet, extensions, etc.).
502 class Proto2Tests(TextFormatBase):
503
504 def testPrintMessageSet(self):
505 message = unittest_mset_pb2.TestMessageSetContainer()
506 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
507 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
508 message.message_set.Extensions[ext1].i = 23
509 message.message_set.Extensions[ext2].str = 'foo'
510 self.CompareToGoldenText(
511 text_format.MessageToString(message),
512 'message_set {\n'
513 ' [protobuf_unittest.TestMessageSetExtension1] {\n'
514 ' i: 23\n'
515 ' }\n'
516 ' [protobuf_unittest.TestMessageSetExtension2] {\n'
517 ' str: \"foo\"\n'
518 ' }\n'
519 '}\n')
520
521 def testPrintMessageSetAsOneLine(self):
522 message = unittest_mset_pb2.TestMessageSetContainer()
523 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
524 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
525 message.message_set.Extensions[ext1].i = 23
526 message.message_set.Extensions[ext2].str = 'foo'
527 self.CompareToGoldenText(
528 text_format.MessageToString(message, as_one_line=True),
529 'message_set {'
530 ' [protobuf_unittest.TestMessageSetExtension1] {'
531 ' i: 23'
532 ' }'
533 ' [protobuf_unittest.TestMessageSetExtension2] {'
534 ' str: \"foo\"'
535 ' }'
536 ' }')
537
538 def testParseMessageSet(self):
291 message = unittest_pb2.TestAllTypes() 539 message = unittest_pb2.TestAllTypes()
292 text = ('repeated_uint64: 1\n' 540 text = ('repeated_uint64: 1\n'
293 'repeated_uint64: 2\n') 541 'repeated_uint64: 2\n')
294 text_format.Merge(text, message) 542 text_format.Parse(text, message)
295 self.assertEqual(1, message.repeated_uint64[0]) 543 self.assertEqual(1, message.repeated_uint64[0])
296 self.assertEqual(2, message.repeated_uint64[1]) 544 self.assertEqual(2, message.repeated_uint64[1])
297 545
298 message = unittest_mset_pb2.TestMessageSetContainer() 546 message = unittest_mset_pb2.TestMessageSetContainer()
299 text = ('message_set {\n' 547 text = ('message_set {\n'
300 ' [protobuf_unittest.TestMessageSetExtension1] {\n' 548 ' [protobuf_unittest.TestMessageSetExtension1] {\n'
301 ' i: 23\n' 549 ' i: 23\n'
302 ' }\n' 550 ' }\n'
303 ' [protobuf_unittest.TestMessageSetExtension2] {\n' 551 ' [protobuf_unittest.TestMessageSetExtension2] {\n'
304 ' str: \"foo\"\n' 552 ' str: \"foo\"\n'
305 ' }\n' 553 ' }\n'
306 '}\n') 554 '}\n')
307 text_format.Merge(text, message) 555 text_format.Parse(text, message)
308 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension 556 ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
309 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension 557 ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
310 self.assertEquals(23, message.message_set.Extensions[ext1].i) 558 self.assertEquals(23, message.message_set.Extensions[ext1].i)
311 self.assertEquals('foo', message.message_set.Extensions[ext2].str) 559 self.assertEquals('foo', message.message_set.Extensions[ext2].str)
312 560
313 def testMergeExotic(self): 561 def testPrintAllExtensions(self):
314 message = unittest_pb2.TestAllTypes() 562 message = unittest_pb2.TestAllExtensions()
315 text = ('repeated_int64: -9223372036854775808\n' 563 test_util.SetAllExtensions(message)
316 'repeated_uint64: 18446744073709551615\n' 564 self.CompareToGoldenFile(
317 'repeated_double: 123.456\n' 565 self.RemoveRedundantZeros(text_format.MessageToString(message)),
318 'repeated_double: 1.23e+22\n' 566 'text_format_unittest_extensions_data.txt')
319 'repeated_double: 1.23e-18\n'
320 'repeated_string: \n'
321 '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
322 'repeated_string: "foo" \'corge\' "grault"\n'
323 'repeated_string: "\\303\\274\\352\\234\\237"\n'
324 'repeated_string: "\\xc3\\xbc"\n'
325 'repeated_string: "\xc3\xbc"\n')
326 text_format.Merge(text, message)
327 567
328 self.assertEqual(-9223372036854775808, message.repeated_int64[0]) 568 def testPrintAllExtensionsPointy(self):
329 self.assertEqual(18446744073709551615, message.repeated_uint64[0]) 569 message = unittest_pb2.TestAllExtensions()
330 self.assertEqual(123.456, message.repeated_double[0]) 570 test_util.SetAllExtensions(message)
331 self.assertEqual(1.23e22, message.repeated_double[1]) 571 self.CompareToGoldenFile(
332 self.assertEqual(1.23e-18, message.repeated_double[2]) 572 self.RemoveRedundantZeros(text_format.MessageToString(
333 self.assertEqual( 573 message, pointy_brackets=True)),
334 '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0]) 574 'text_format_unittest_extensions_data_pointy.txt')
335 self.assertEqual('foocorgegrault', message.repeated_string[1])
336 self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
337 self.assertEqual(u'\u00fc', message.repeated_string[3])
338 575
339 def testMergeEmptyText(self): 576 def testParseGoldenExtensions(self):
340 message = unittest_pb2.TestAllTypes() 577 golden_text = '\n'.join(self.ReadGolden(
341 text = '' 578 'text_format_unittest_extensions_data.txt'))
342 text_format.Merge(text, message) 579 parsed_message = unittest_pb2.TestAllExtensions()
343 self.assertEquals(unittest_pb2.TestAllTypes(), message) 580 text_format.Parse(golden_text, parsed_message)
344 581
345 def testMergeInvalidUtf8(self): 582 message = unittest_pb2.TestAllExtensions()
346 message = unittest_pb2.TestAllTypes() 583 test_util.SetAllExtensions(message)
347 text = 'repeated_string: "\\xc3\\xc3"' 584 self.assertEquals(message, parsed_message)
348 self.assertRaises(text_format.ParseError, text_format.Merge, text, message)
349 585
350 def testMergeSingleWord(self): 586 def testParseAllExtensions(self):
351 message = unittest_pb2.TestAllTypes() 587 message = unittest_pb2.TestAllExtensions()
352 text = 'foo' 588 test_util.SetAllExtensions(message)
353 self.assertRaisesWithMessage( 589 ascii_text = text_format.MessageToString(message)
354 text_format.ParseError,
355 ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
356 '"foo".'),
357 text_format.Merge, text, message)
358 590
359 def testMergeUnknownField(self): 591 parsed_message = unittest_pb2.TestAllExtensions()
360 message = unittest_pb2.TestAllTypes() 592 text_format.Parse(ascii_text, parsed_message)
361 text = 'unknown_field: 8\n' 593 self.assertEqual(message, parsed_message)
362 self.assertRaisesWithMessage(
363 text_format.ParseError,
364 ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
365 '"unknown_field".'),
366 text_format.Merge, text, message)
367 594
368 def testMergeBadExtension(self): 595 def testParseBadExtension(self):
369 message = unittest_pb2.TestAllExtensions() 596 message = unittest_pb2.TestAllExtensions()
370 text = '[unknown_extension]: 8\n' 597 text = '[unknown_extension]: 8\n'
371 self.assertRaisesWithMessage( 598 self.assertRaisesRegexp(
372 text_format.ParseError, 599 text_format.ParseError,
373 '1:2 : Extension "unknown_extension" not registered.', 600 '1:2 : Extension "unknown_extension" not registered.',
374 text_format.Merge, text, message) 601 text_format.Parse, text, message)
375 message = unittest_pb2.TestAllTypes() 602 message = unittest_pb2.TestAllTypes()
376 self.assertRaisesWithMessage( 603 self.assertRaisesRegexp(
377 text_format.ParseError, 604 text_format.ParseError,
378 ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' 605 ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
379 'extensions.'), 606 'extensions.'),
380 text_format.Merge, text, message) 607 text_format.Parse, text, message)
381 608
382 def testMergeGroupNotClosed(self): 609 def testMergeDuplicateExtensionScalars(self):
610 message = unittest_pb2.TestAllExtensions()
611 text = ('[protobuf_unittest.optional_int32_extension]: 42 '
612 '[protobuf_unittest.optional_int32_extension]: 67')
613 text_format.Merge(text, message)
614 self.assertEqual(
615 67,
616 message.Extensions[unittest_pb2.optional_int32_extension])
617
618 def testParseDuplicateExtensionScalars(self):
619 message = unittest_pb2.TestAllExtensions()
620 text = ('[protobuf_unittest.optional_int32_extension]: 42 '
621 '[protobuf_unittest.optional_int32_extension]: 67')
622 self.assertRaisesRegexp(
623 text_format.ParseError,
624 ('1:96 : Message type "protobuf_unittest.TestAllExtensions" '
625 'should not have multiple '
626 '"protobuf_unittest.optional_int32_extension" extensions.'),
627 text_format.Parse, text, message)
628
629 def testParseDuplicateNestedMessageScalars(self):
630 message = unittest_pb2.TestAllTypes()
631 text = ('optional_nested_message { bb: 1 } '
632 'optional_nested_message { bb: 2 }')
633 self.assertRaisesRegexp(
634 text_format.ParseError,
635 ('1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
636 'should not have multiple "bb" fields.'),
637 text_format.Parse, text, message)
638
639 def testParseDuplicateScalars(self):
640 message = unittest_pb2.TestAllTypes()
641 text = ('optional_int32: 42 '
642 'optional_int32: 67')
643 self.assertRaisesRegexp(
644 text_format.ParseError,
645 ('1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
646 'have multiple "optional_int32" fields.'),
647 text_format.Parse, text, message)
648
649 def testParseGroupNotClosed(self):
383 message = unittest_pb2.TestAllTypes() 650 message = unittest_pb2.TestAllTypes()
384 text = 'RepeatedGroup: <' 651 text = 'RepeatedGroup: <'
385 self.assertRaisesWithMessage( 652 self.assertRaisesRegexp(
386 text_format.ParseError, '1:16 : Expected ">".', 653 text_format.ParseError, '1:16 : Expected ">".',
387 text_format.Merge, text, message) 654 text_format.Parse, text, message)
655 text = 'RepeatedGroup: {'
656 self.assertRaisesRegexp(
657 text_format.ParseError, '1:16 : Expected "}".',
658 text_format.Parse, text, message)
388 659
389 text = 'RepeatedGroup: {' 660 def testParseEmptyGroup(self):
390 self.assertRaisesWithMessage(
391 text_format.ParseError, '1:16 : Expected "}".',
392 text_format.Merge, text, message)
393
394 def testMergeEmptyGroup(self):
395 message = unittest_pb2.TestAllTypes() 661 message = unittest_pb2.TestAllTypes()
396 text = 'OptionalGroup: {}' 662 text = 'OptionalGroup: {}'
397 text_format.Merge(text, message) 663 text_format.Parse(text, message)
398 self.assertTrue(message.HasField('optionalgroup')) 664 self.assertTrue(message.HasField('optionalgroup'))
399 665
400 message.Clear() 666 message.Clear()
401 667
402 message = unittest_pb2.TestAllTypes() 668 message = unittest_pb2.TestAllTypes()
403 text = 'OptionalGroup: <>' 669 text = 'OptionalGroup: <>'
404 text_format.Merge(text, message) 670 text_format.Parse(text, message)
405 self.assertTrue(message.HasField('optionalgroup')) 671 self.assertTrue(message.HasField('optionalgroup'))
406 672
407 def testMergeBadEnumValue(self): 673 # Maps aren't really proto2-only, but our test schema only has maps for
408 message = unittest_pb2.TestAllTypes() 674 # proto2.
409 text = 'optional_nested_enum: BARR' 675 def testParseMap(self):
410 self.assertRaisesWithMessage( 676 text = ('map_int32_int32 {\n'
411 text_format.ParseError, 677 ' key: -123\n'
412 ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" ' 678 ' value: -456\n'
413 'has no value named BARR.'), 679 '}\n'
414 text_format.Merge, text, message) 680 'map_int64_int64 {\n'
681 ' key: -8589934592\n'
682 ' value: -17179869184\n'
683 '}\n'
684 'map_uint32_uint32 {\n'
685 ' key: 123\n'
686 ' value: 456\n'
687 '}\n'
688 'map_uint64_uint64 {\n'
689 ' key: 8589934592\n'
690 ' value: 17179869184\n'
691 '}\n'
692 'map_string_string {\n'
693 ' key: "abc"\n'
694 ' value: "123"\n'
695 '}\n'
696 'map_int32_foreign_message {\n'
697 ' key: 111\n'
698 ' value {\n'
699 ' c: 5\n'
700 ' }\n'
701 '}\n')
702 message = map_unittest_pb2.TestMap()
703 text_format.Parse(text, message)
415 704
416 message = unittest_pb2.TestAllTypes() 705 self.assertEqual(-456, message.map_int32_int32[-123])
417 text = 'optional_nested_enum: 100' 706 self.assertEqual(-2**34, message.map_int64_int64[-2**33])
418 self.assertRaisesWithMessage( 707 self.assertEqual(456, message.map_uint32_uint32[123])
419 text_format.ParseError, 708 self.assertEqual(2**34, message.map_uint64_uint64[2**33])
420 ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" ' 709 self.assertEqual("123", message.map_string_string["abc"])
421 'has no value with number 100.'), 710 self.assertEqual(5, message.map_int32_foreign_message[111].c)
422 text_format.Merge, text, message)
423
424 def testMergeBadIntValue(self):
425 message = unittest_pb2.TestAllTypes()
426 text = 'optional_int32: bork'
427 self.assertRaisesWithMessage(
428 text_format.ParseError,
429 ('1:17 : Couldn\'t parse integer: bork'),
430 text_format.Merge, text, message)
431
432 def assertRaisesWithMessage(self, e_class, e, func, *args, **kwargs):
433 """Same as assertRaises, but also compares the exception message."""
434 if hasattr(e_class, '__name__'):
435 exc_name = e_class.__name__
436 else:
437 exc_name = str(e_class)
438
439 try:
440 func(*args, **kwargs)
441 except e_class as expr:
442 if str(expr) != e:
443 msg = '%s raised, but with wrong message: "%s" instead of "%s"'
444 raise self.failureException(msg % (exc_name,
445 str(expr).encode('string_escape'),
446 e.encode('string_escape')))
447 return
448 else:
449 raise self.failureException('%s not raised' % exc_name)
450 711
451 712
452 class TokenizerTest(unittest.TestCase): 713 class TokenizerTest(unittest.TestCase):
453 714
454 def testSimpleTokenCases(self): 715 def testSimpleTokenCases(self):
455 text = ('identifier1:"string1"\n \n\n' 716 text = ('identifier1:"string1"\n \n\n'
456 'identifier2 : \n \n123 \n identifier3 :\'string\'\n' 717 'identifier2 : \n \n123 \n identifier3 :\'string\'\n'
457 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n' 718 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
458 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n' 719 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
459 'ID9: 22 ID10: -111111111111111111 ID11: -22\n' 720 'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
460 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f ' 721 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f '
461 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' ) 722 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ')
462 tokenizer = text_format._Tokenizer(text) 723 tokenizer = text_format._Tokenizer(text.splitlines())
463 methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), 724 methods = [(tokenizer.ConsumeIdentifier, 'identifier1'),
464 ':', 725 ':',
465 (tokenizer.ConsumeString, 'string1'), 726 (tokenizer.ConsumeString, 'string1'),
466 (tokenizer.ConsumeIdentifier, 'identifier2'), 727 (tokenizer.ConsumeIdentifier, 'identifier2'),
467 ':', 728 ':',
468 (tokenizer.ConsumeInt32, 123), 729 (tokenizer.ConsumeInt32, 123),
469 (tokenizer.ConsumeIdentifier, 'identifier3'), 730 (tokenizer.ConsumeIdentifier, 'identifier3'),
470 ':', 731 ':',
471 (tokenizer.ConsumeString, 'string'), 732 (tokenizer.ConsumeString, 'string'),
472 (tokenizer.ConsumeIdentifier, 'identifiER_4'), 733 (tokenizer.ConsumeIdentifier, 'identifiER_4'),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 else: 799 else:
539 self.assertEqual(m[1], m[0]()) 800 self.assertEqual(m[1], m[0]())
540 i += 1 801 i += 1
541 802
542 def testConsumeIntegers(self): 803 def testConsumeIntegers(self):
543 # This test only tests the failures in the integer parsing methods as well 804 # This test only tests the failures in the integer parsing methods as well
544 # as the '0' special cases. 805 # as the '0' special cases.
545 int64_max = (1 << 63) - 1 806 int64_max = (1 << 63) - 1
546 uint32_max = (1 << 32) - 1 807 uint32_max = (1 << 32) - 1
547 text = '-1 %d %d' % (uint32_max + 1, int64_max + 1) 808 text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
548 tokenizer = text_format._Tokenizer(text) 809 tokenizer = text_format._Tokenizer(text.splitlines())
549 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) 810 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
550 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64) 811 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64)
551 self.assertEqual(-1, tokenizer.ConsumeInt32()) 812 self.assertEqual(-1, tokenizer.ConsumeInt32())
552 813
553 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32) 814 self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
554 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32) 815 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32)
555 self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64()) 816 self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64())
556 817
557 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64) 818 self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64)
558 self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64()) 819 self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64())
559 self.assertTrue(tokenizer.AtEnd()) 820 self.assertTrue(tokenizer.AtEnd())
560 821
561 text = '-0 -0 0 0' 822 text = '-0 -0 0 0'
562 tokenizer = text_format._Tokenizer(text) 823 tokenizer = text_format._Tokenizer(text.splitlines())
563 self.assertEqual(0, tokenizer.ConsumeUint32()) 824 self.assertEqual(0, tokenizer.ConsumeUint32())
564 self.assertEqual(0, tokenizer.ConsumeUint64()) 825 self.assertEqual(0, tokenizer.ConsumeUint64())
565 self.assertEqual(0, tokenizer.ConsumeUint32()) 826 self.assertEqual(0, tokenizer.ConsumeUint32())
566 self.assertEqual(0, tokenizer.ConsumeUint64()) 827 self.assertEqual(0, tokenizer.ConsumeUint64())
567 self.assertTrue(tokenizer.AtEnd()) 828 self.assertTrue(tokenizer.AtEnd())
568 829
569 def testConsumeByteString(self): 830 def testConsumeByteString(self):
570 text = '"string1\'' 831 text = '"string1\''
571 tokenizer = text_format._Tokenizer(text) 832 tokenizer = text_format._Tokenizer(text.splitlines())
572 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) 833 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
573 834
574 text = 'string1"' 835 text = 'string1"'
575 tokenizer = text_format._Tokenizer(text) 836 tokenizer = text_format._Tokenizer(text.splitlines())
576 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) 837 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
577 838
578 text = '\n"\\xt"' 839 text = '\n"\\xt"'
579 tokenizer = text_format._Tokenizer(text) 840 tokenizer = text_format._Tokenizer(text.splitlines())
580 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) 841 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
581 842
582 text = '\n"\\"' 843 text = '\n"\\"'
583 tokenizer = text_format._Tokenizer(text) 844 tokenizer = text_format._Tokenizer(text.splitlines())
584 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) 845 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
585 846
586 text = '\n"\\x"' 847 text = '\n"\\x"'
587 tokenizer = text_format._Tokenizer(text) 848 tokenizer = text_format._Tokenizer(text.splitlines())
588 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString) 849 self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
589 850
590 def testConsumeBool(self): 851 def testConsumeBool(self):
591 text = 'not-a-bool' 852 text = 'not-a-bool'
592 tokenizer = text_format._Tokenizer(text) 853 tokenizer = text_format._Tokenizer(text.splitlines())
593 self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) 854 self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
594 855
595 856
596 if __name__ == '__main__': 857 if __name__ == '__main__':
597 unittest.main() 858 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698