blob: 76b8920376229e3a209cac2598825ca8927c2f1b [file] [log] [blame]
csharptest71f662c2011-05-20 15:15:34 -05001#region Copyright notice and license
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc. All rights reserved.
5// http://github.com/jskeet/dotnet-protobufs/
6// Original C++/Java/Python code:
7// http://code.google.com/p/protobuf/
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15// * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19// * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35#endregion
36
37using System;
38using System.IO;
39using System.Text;
40using Google.ProtocolBuffers.TestProtos;
41using NUnit.Framework;
42using System.Globalization;
43using System.Threading;
44
45namespace Google.ProtocolBuffers
46{
47 [TestFixture]
48 public class TextFormatTest
49 {
50 private static readonly string AllFieldsSetText = TestUtil.ReadTextFromFile("text_format_unittest_data.txt");
51
52 private static readonly string AllExtensionsSetText =
53 TestUtil.ReadTextFromFile("text_format_unittest_extensions_data.txt");
54
55 /// <summary>
56 /// Note that this is slightly different to the Java - 123.0 becomes 123, and 1.23E17 becomes 1.23E+17.
57 /// Both of these differences can be parsed by the Java and the C++, and we can parse their output too.
58 /// </summary>
59 private const string ExoticText =
60 "repeated_int32: -1\n" +
61 "repeated_int32: -2147483648\n" +
62 "repeated_int64: -1\n" +
63 "repeated_int64: -9223372036854775808\n" +
64 "repeated_uint32: 4294967295\n" +
65 "repeated_uint32: 2147483648\n" +
66 "repeated_uint64: 18446744073709551615\n" +
67 "repeated_uint64: 9223372036854775808\n" +
68 "repeated_double: 123\n" +
69 "repeated_double: 123.5\n" +
70 "repeated_double: 0.125\n" +
71 "repeated_double: 1.23E+17\n" +
72 "repeated_double: 1.235E+22\n" +
73 "repeated_double: 1.235E-18\n" +
74 "repeated_double: 123.456789\n" +
75 "repeated_double: Infinity\n" +
76 "repeated_double: -Infinity\n" +
77 "repeated_double: NaN\n" +
78 "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
79 "\\341\\210\\264\"\n" +
80 "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
81
82 private const string MessageSetText =
83 "[protobuf_unittest.TestMessageSetExtension1] {\n" +
84 " i: 123\n" +
85 "}\n" +
86 "[protobuf_unittest.TestMessageSetExtension2] {\n" +
87 " str: \"foo\"\n" +
88 "}\n";
89
90 /// <summary>
91 /// Print TestAllTypes and compare with golden file.
92 /// </summary>
93 [Test]
94 public void PrintMessage()
95 {
96 TestUtil.TestInMultipleCultures(() =>
97 {
98 string text = TextFormat.PrintToString(TestUtil.GetAllSet());
99 Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"),
100 text.Replace("\r\n", "\n"));
101 });
102 }
103
104 /// <summary>
105 /// Print TestAllExtensions and compare with golden file.
106 /// </summary>
107 [Test]
108 public void PrintExtensions()
109 {
110 string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet());
111
112 Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
113 }
114
115 /// <summary>
116 /// Test printing of unknown fields in a message.
117 /// </summary>
118 [Test]
119 public void PrintUnknownFields()
120 {
121 TestEmptyMessage message =
122 TestEmptyMessage.CreateBuilder()
123 .SetUnknownFields(
124 UnknownFieldSet.CreateBuilder()
125 .AddField(5,
126 UnknownField.CreateBuilder()
127 .AddVarint(1)
128 .AddFixed32(2)
129 .AddFixed64(3)
130 .AddLengthDelimited(ByteString.CopyFromUtf8("4"))
131 .AddGroup(
132 UnknownFieldSet.CreateBuilder()
133 .AddField(10,
134 UnknownField.CreateBuilder()
135 .AddVarint(5)
136 .Build())
137 .Build())
138 .Build())
139 .AddField(8,
140 UnknownField.CreateBuilder()
141 .AddVarint(1)
142 .AddVarint(2)
143 .AddVarint(3)
144 .Build())
145 .AddField(15,
146 UnknownField.CreateBuilder()
147 .AddVarint(0xABCDEF1234567890L)
148 .AddFixed32(0xABCD1234)
149 .AddFixed64(0xABCDEF1234567890L)
150 .Build())
151 .Build())
152 .Build();
153
154 Assert.AreEqual(
155 "5: 1\n" +
156 "5: 0x00000002\n" +
157 "5: 0x0000000000000003\n" +
158 "5: \"4\"\n" +
159 "5 {\n" +
160 " 10: 5\n" +
161 "}\n" +
162 "8: 1\n" +
163 "8: 2\n" +
164 "8: 3\n" +
165 "15: 12379813812177893520\n" +
166 "15: 0xabcd1234\n" +
167 "15: 0xabcdef1234567890\n",
168 TextFormat.PrintToString(message));
169 }
170
171 /// <summary>
172 /// Helper to construct a ByteString from a string containing only 8-bit
173 /// characters. The characters are converted directly to bytes, *not*
174 /// encoded using UTF-8.
175 /// </summary>
176 private static ByteString Bytes(string str)
177 {
178 return ByteString.CopyFrom(Encoding.GetEncoding(28591).GetBytes(str));
179 }
180
181 [Test]
182 public void PrintExotic()
183 {
184 IMessage message = TestAllTypes.CreateBuilder()
185 // Signed vs. unsigned numbers.
186 .AddRepeatedInt32(-1)
187 .AddRepeatedUint32(uint.MaxValue)
188 .AddRepeatedInt64(-1)
189 .AddRepeatedUint64(ulong.MaxValue)
190 .AddRepeatedInt32(1 << 31)
191 .AddRepeatedUint32(1U << 31)
192 .AddRepeatedInt64(1L << 63)
193 .AddRepeatedUint64(1UL << 63)
194
195 // Floats of various precisions and exponents.
196 .AddRepeatedDouble(123)
197 .AddRepeatedDouble(123.5)
198 .AddRepeatedDouble(0.125)
199 .AddRepeatedDouble(123e15)
200 .AddRepeatedDouble(123.5e20)
201 .AddRepeatedDouble(123.5e-20)
202 .AddRepeatedDouble(123.456789)
203 .AddRepeatedDouble(Double.PositiveInfinity)
204 .AddRepeatedDouble(Double.NegativeInfinity)
205 .AddRepeatedDouble(Double.NaN)
206
207 // Strings and bytes that needing escaping.
208 .AddRepeatedString("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u1234")
209 .AddRepeatedBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u00fe"))
210 .Build();
211
212 Assert.AreEqual(ExoticText, message.ToString());
213 }
214
215 [Test]
216 public void PrintMessageSet()
217 {
218 TestMessageSet messageSet =
219 TestMessageSet.CreateBuilder()
220 .SetExtension(
221 TestMessageSetExtension1.MessageSetExtension,
222 TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
223 .SetExtension(
224 TestMessageSetExtension2.MessageSetExtension,
225 TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
226 .Build();
227
228 Assert.AreEqual(MessageSetText, messageSet.ToString());
229 }
230
231 // =================================================================
232
233 [Test]
234 public void Parse()
235 {
236 TestUtil.TestInMultipleCultures(() =>
237 {
238 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
239 TextFormat.Merge(AllFieldsSetText, builder);
240 TestUtil.AssertAllFieldsSet(builder.Build());
241 });
242 }
243
244 [Test]
245 public void ParseReader()
246 {
247 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
248 TextFormat.Merge(new StringReader(AllFieldsSetText), builder);
249 TestUtil.AssertAllFieldsSet(builder.Build());
250 }
251
252 [Test]
253 public void ParseExtensions()
254 {
255 TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
256 TextFormat.Merge(AllExtensionsSetText,
257 TestUtil.CreateExtensionRegistry(),
258 builder);
259 TestUtil.AssertAllExtensionsSet(builder.Build());
260 }
261
262 [Test]
263 public void ParseCompatibility()
264 {
265 string original = "repeated_float: inf\n" +
266 "repeated_float: -inf\n" +
267 "repeated_float: nan\n" +
268 "repeated_float: inff\n" +
269 "repeated_float: -inff\n" +
270 "repeated_float: nanf\n" +
271 "repeated_float: 1.0f\n" +
272 "repeated_float: infinityf\n" +
273 "repeated_float: -Infinityf\n" +
274 "repeated_double: infinity\n" +
275 "repeated_double: -infinity\n" +
276 "repeated_double: nan\n";
277 string canonical = "repeated_float: Infinity\n" +
278 "repeated_float: -Infinity\n" +
279 "repeated_float: NaN\n" +
280 "repeated_float: Infinity\n" +
281 "repeated_float: -Infinity\n" +
282 "repeated_float: NaN\n" +
283 "repeated_float: 1\n" + // Java has 1.0; this is fine
284 "repeated_float: Infinity\n" +
285 "repeated_float: -Infinity\n" +
286 "repeated_double: Infinity\n" +
287 "repeated_double: -Infinity\n" +
288 "repeated_double: NaN\n";
289 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
290 TextFormat.Merge(original, builder);
291 Assert.AreEqual(canonical, builder.Build().ToString());
292 }
293
294 [Test]
295 public void ParseExotic()
296 {
297 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
298 TextFormat.Merge(ExoticText, builder);
299
300 // Too lazy to check things individually. Don't try to debug this
301 // if testPrintExotic() is Assert.Failing.
302 Assert.AreEqual(ExoticText, builder.Build().ToString());
303 }
304
305 [Test]
306 public void ParseMessageSet()
307 {
308 ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
309 extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
310 extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
311
312 TestMessageSet.Builder builder = TestMessageSet.CreateBuilder();
313 TextFormat.Merge(MessageSetText, extensionRegistry, builder);
314 TestMessageSet messageSet = builder.Build();
315
316 Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension1.MessageSetExtension));
317 Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
318 Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension2.MessageSetExtension));
319 Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
320 }
321
322 [Test]
323 public void ParseNumericEnum()
324 {
325 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
326 TextFormat.Merge("optional_nested_enum: 2", builder);
327 Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, builder.OptionalNestedEnum);
328 }
329
330 [Test]
331 public void ParseAngleBrackets()
332 {
333 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
334 TextFormat.Merge("OptionalGroup: < a: 1 >", builder);
335 Assert.IsTrue(builder.HasOptionalGroup);
336 Assert.AreEqual(1, builder.OptionalGroup.A);
337 }
338
339 [Test]
340 public void ParseComment()
341 {
342 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
343 TextFormat.Merge(
344 "# this is a comment\n" +
345 "optional_int32: 1 # another comment\n" +
346 "optional_int64: 2\n" +
347 "# EOF comment", builder);
348 Assert.AreEqual(1, builder.OptionalInt32);
349 Assert.AreEqual(2, builder.OptionalInt64);
350 }
351
352
353 private static void AssertParseError(string error, string text)
354 {
355 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
356 try
357 {
358 TextFormat.Merge(text, TestUtil.CreateExtensionRegistry(), builder);
359 Assert.Fail("Expected parse exception.");
360 }
361 catch (FormatException e)
362 {
363 Assert.AreEqual(error, e.Message);
364 }
365 }
366
367 [Test]
368 public void ParseErrors()
369 {
370 AssertParseError(
371 "1:16: Expected \":\".",
372 "optional_int32 123");
373 AssertParseError(
374 "1:23: Expected identifier.",
375 "optional_nested_enum: ?");
376 AssertParseError(
377 "1:18: Couldn't parse integer: Number must be positive: -1",
378 "optional_uint32: -1");
379 AssertParseError(
380 "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
381 "integer: 82301481290849012385230157",
382 "optional_int32: 82301481290849012385230157");
383 AssertParseError(
384 "1:16: Expected \"true\" or \"false\".",
385 "optional_bool: maybe");
386 AssertParseError(
387 "1:18: Expected string.",
388 "optional_string: 123");
389 AssertParseError(
390 "1:18: String missing ending quote.",
391 "optional_string: \"ueoauaoe");
392 AssertParseError(
393 "1:18: String missing ending quote.",
394 "optional_string: \"ueoauaoe\n" +
395 "optional_int32: 123");
396 AssertParseError(
397 "1:18: Invalid escape sequence: '\\z'",
398 "optional_string: \"\\z\"");
399 AssertParseError(
400 "1:18: String missing ending quote.",
401 "optional_string: \"ueoauaoe\n" +
402 "optional_int32: 123");
403 AssertParseError(
404 "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
405 "[nosuchext]: 123");
406 AssertParseError(
407 "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
408 "not extend message type \"protobuf_unittest.TestAllTypes\".",
409 "[protobuf_unittest.optional_int32_extension]: 123");
410 AssertParseError(
411 "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
412 "named \"nosuchfield\".",
413 "nosuchfield: 123");
414 AssertParseError(
415 "1:21: Expected \">\".",
416 "OptionalGroup < a: 1");
417 AssertParseError(
418 "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
419 "value named \"NO_SUCH_VALUE\".",
420 "optional_nested_enum: NO_SUCH_VALUE");
421 AssertParseError(
422 "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
423 "value with number 123.",
424 "optional_nested_enum: 123");
425
426 // Delimiters must match.
427 AssertParseError(
428 "1:22: Expected identifier.",
429 "OptionalGroup < a: 1 }");
430 AssertParseError(
431 "1:22: Expected identifier.",
432 "OptionalGroup { a: 1 >");
433 }
434
435 // =================================================================
436
437 private static ByteString Bytes(params byte[] bytes)
438 {
439 return ByteString.CopyFrom(bytes);
440 }
441
442 private delegate void FormattingAction();
443
444 private static void AssertFormatException(FormattingAction action)
445 {
446 try
447 {
448 action();
449 Assert.Fail("Should have thrown an exception.");
450 }
451 catch (FormatException)
452 {
453 // success
454 }
455 }
456
457 [Test]
458 public void Escape()
459 {
460 // Escape sequences.
461 Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
462 TextFormat.EscapeBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"")));
463 Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
464 TextFormat.EscapeText("\0\u0001\u0007\b\f\n\r\t\v\\\'\""));
465 Assert.AreEqual(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\""),
466 TextFormat.UnescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
467 Assert.AreEqual("\0\u0001\u0007\b\f\n\r\t\v\\\'\"",
468 TextFormat.UnescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
469
470 // Unicode handling.
471 Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeText("\u1234"));
472 Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeBytes(Bytes(0xe1, 0x88, 0xb4)));
473 Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\341\\210\\264"));
474 Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\341\\210\\264"));
475 Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\xe1\\x88\\xb4"));
476 Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\xe1\\x88\\xb4"));
477
478 // Errors.
479 AssertFormatException(() => TextFormat.UnescapeText("\\x"));
480 AssertFormatException(() => TextFormat.UnescapeText("\\z"));
481 AssertFormatException(() => TextFormat.UnescapeText("\\"));
482 }
483
484 [Test]
485 public void ParseInteger()
486 {
487 Assert.AreEqual(0, TextFormat.ParseInt32("0"));
488 Assert.AreEqual(1, TextFormat.ParseInt32("1"));
489 Assert.AreEqual(-1, TextFormat.ParseInt32("-1"));
490 Assert.AreEqual(12345, TextFormat.ParseInt32("12345"));
491 Assert.AreEqual(-12345, TextFormat.ParseInt32("-12345"));
492 Assert.AreEqual(2147483647, TextFormat.ParseInt32("2147483647"));
493 Assert.AreEqual(-2147483648, TextFormat.ParseInt32("-2147483648"));
494
495 Assert.AreEqual(0, TextFormat.ParseUInt32("0"));
496 Assert.AreEqual(1, TextFormat.ParseUInt32("1"));
497 Assert.AreEqual(12345, TextFormat.ParseUInt32("12345"));
498 Assert.AreEqual(2147483647, TextFormat.ParseUInt32("2147483647"));
499 Assert.AreEqual(2147483648U, TextFormat.ParseUInt32("2147483648"));
500 Assert.AreEqual(4294967295U, TextFormat.ParseUInt32("4294967295"));
501
502 Assert.AreEqual(0L, TextFormat.ParseInt64("0"));
503 Assert.AreEqual(1L, TextFormat.ParseInt64("1"));
504 Assert.AreEqual(-1L, TextFormat.ParseInt64("-1"));
505 Assert.AreEqual(12345L, TextFormat.ParseInt64("12345"));
506 Assert.AreEqual(-12345L, TextFormat.ParseInt64("-12345"));
507 Assert.AreEqual(2147483647L, TextFormat.ParseInt64("2147483647"));
508 Assert.AreEqual(-2147483648L, TextFormat.ParseInt64("-2147483648"));
509 Assert.AreEqual(4294967295L, TextFormat.ParseInt64("4294967295"));
510 Assert.AreEqual(4294967296L, TextFormat.ParseInt64("4294967296"));
511 Assert.AreEqual(9223372036854775807L, TextFormat.ParseInt64("9223372036854775807"));
512 Assert.AreEqual(-9223372036854775808L, TextFormat.ParseInt64("-9223372036854775808"));
513
514 Assert.AreEqual(0L, TextFormat.ParseUInt64("0"));
515 Assert.AreEqual(1L, TextFormat.ParseUInt64("1"));
516 Assert.AreEqual(12345L, TextFormat.ParseUInt64("12345"));
517 Assert.AreEqual(2147483647L, TextFormat.ParseUInt64("2147483647"));
518 Assert.AreEqual(4294967295L, TextFormat.ParseUInt64("4294967295"));
519 Assert.AreEqual(4294967296L, TextFormat.ParseUInt64("4294967296"));
520 Assert.AreEqual(9223372036854775807UL, TextFormat.ParseUInt64("9223372036854775807"));
521 Assert.AreEqual(9223372036854775808UL, TextFormat.ParseUInt64("9223372036854775808"));
522 Assert.AreEqual(18446744073709551615UL, TextFormat.ParseUInt64("18446744073709551615"));
523
524 // Hex
525 Assert.AreEqual(0x1234abcd, TextFormat.ParseInt32("0x1234abcd"));
526 Assert.AreEqual(-0x1234abcd, TextFormat.ParseInt32("-0x1234abcd"));
527 Assert.AreEqual(0xffffffffffffffffUL, TextFormat.ParseUInt64("0xffffffffffffffff"));
528 Assert.AreEqual(0x7fffffffffffffffL,
529 TextFormat.ParseInt64("0x7fffffffffffffff"));
530
531 // Octal
532 Assert.AreEqual(342391, TextFormat.ParseInt32("01234567"));
533
534 // Out-of-range
535 AssertFormatException(() => TextFormat.ParseInt32("2147483648"));
536 AssertFormatException(() => TextFormat.ParseInt32("-2147483649"));
537 AssertFormatException(() => TextFormat.ParseUInt32("4294967296"));
538 AssertFormatException(() => TextFormat.ParseUInt32("-1"));
539 AssertFormatException(() => TextFormat.ParseInt64("9223372036854775808"));
540 AssertFormatException(() => TextFormat.ParseInt64("-9223372036854775809"));
541 AssertFormatException(() => TextFormat.ParseUInt64("18446744073709551616"));
542 AssertFormatException(() => TextFormat.ParseUInt64("-1"));
543 AssertFormatException(() => TextFormat.ParseInt32("abcd"));
544 }
545
546 [Test]
547 public void ParseLongString()
548 {
549 string longText =
550 "123456789012345678901234567890123456789012345678901234567890" +
551 "123456789012345678901234567890123456789012345678901234567890" +
552 "123456789012345678901234567890123456789012345678901234567890" +
553 "123456789012345678901234567890123456789012345678901234567890" +
554 "123456789012345678901234567890123456789012345678901234567890" +
555 "123456789012345678901234567890123456789012345678901234567890" +
556 "123456789012345678901234567890123456789012345678901234567890" +
557 "123456789012345678901234567890123456789012345678901234567890" +
558 "123456789012345678901234567890123456789012345678901234567890" +
559 "123456789012345678901234567890123456789012345678901234567890" +
560 "123456789012345678901234567890123456789012345678901234567890" +
561 "123456789012345678901234567890123456789012345678901234567890" +
562 "123456789012345678901234567890123456789012345678901234567890" +
563 "123456789012345678901234567890123456789012345678901234567890" +
564 "123456789012345678901234567890123456789012345678901234567890" +
565 "123456789012345678901234567890123456789012345678901234567890";
566 TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
567 TextFormat.Merge("optional_string: \"" + longText + "\"", builder);
568 Assert.AreEqual(longText, builder.OptionalString);
569 }
570 }
571}